
    fiL                     |    S SK r S SKrS SKrS SKrS SKJrJrJrJr  S SK	J
r
  S SKJrJrJrJrJrJr   " S S5      rg)    N)DictListAnyOptional)	AsyncGroq)SCENARIO_GENERATION_PROMPTCHARACTER_ROLEPLAY_PROMPTCHARACTER_CONCLUSION_PROMPT CHARACTER_GUIDED_ROLEPLAY_PROMPTSKILL_ANALYSIS_PROMPTget_skill_analysis_templatec                   v   \ rS rSrS rS\4S jrS\\\4   4S jr	S r
S\\\4   S\\\\4      4S	 jrS
\\\\4      S\\\\4      S\4S jrSS\\\4   S\\\\4      S\S\S
\\\\4      S\\   4S jjrSS\\\4   S\\\\4      S\S\\\\4      4S jjrS\S\\   4S jrS\S\\   4S jrSrg)GroqService   c                    SSK Jn  U" 5         [        R                  " S5      nU(       d0  [	        S5        [	        S5        [	        S5        S U l        SU l        O[        US9U l        S	U l        S
U l        SSSS.SSSS.SSSS.S.U l	        g )Nr   )load_dotenvGROQ_API_KEYu@   ⚠️  WARNING: GROQ_API_KEY not found in environment variablesuL       ℹ️  Groq service will not be available. System will use Ollama only.uJ       ℹ️  To use Groq, set GROQ_API_KEY in your .env file or environmentF)api_keyTzopenai/gpt-oss-20binputoutputtotal)previewconversation
assessment)
dotenvr   osgetenvprintclient	availabler   modeltoken_counts)selfr   r   s      G/var/www/eduai.edurigo.com/roleplay/production/services/groq_service.py__init__GroqService.__init__   s    &))N+TU`a^_DK"DN#G4DK!DN)
 "#a!<&'1qA$%Q?
    operation_typec           
      n   U(       a  [        US5      (       a  [        US5      (       a  UR                  nUR                  nUR                  nU R                  U   S==   U-  ss'   U R                  U   S==   U-  ss'   U R                  U   S==   U-  ss'   [        SU SU SU S	U 35        g
g
g
g
)z*Update token counts for specific operationprompt_tokenscompletion_tokensr   r   r   zGROQ Token count for z: Input=z	, Output=z, Total=N)hasattrr+   r,   total_tokensr#   r   )r$   r)   usage_statsinput_tokensoutput_tokensr.   s         r%   _update_token_countGroqService._update_token_count(   s    7;@@W[ZmEnEn&44L'99M&33Ln-g6,F6n-h7=H7n-g6,F6).)9,yYfXggop|o}~ Fo@;r(   returnc                 6    U R                   R                  5       $ )z+Get current token counts for all operations)r#   copy)r$   s    r%   get_token_countsGroqService.get_token_counts5   s      %%''r(   c                 P    U R                    H  nSSSS.U R                   U'   M     g)zReset all token countersr   r   N)r#   )r$   	operations     r%   reset_token_countsGroqService.reset_token_counts9   s)    **I56!a+PDi( +r(   admin_inputc           	        #     SnUS   R                  5        H  u  p4X# SU S3-  nM     SnUR                  S5      nU(       a1  Sn[        US5       H  u  pxXW SUR                  S	S5       S3-  nM!     [        R                  " US
   US   X%-   SR                  US   5      S9n	U R                  R                  R                  R                  SSS.SU	S./U R                  SSS9I Sh  vN n
U R                  SU
R                  5        U
R                  S   R                  R                  R!                  5       n UR#                  S5      (       a  USS nUR%                  S5      (       a  USS n[&        R(                  " U5      $  N! [&        R*                   a&  n[-        SU 35        [-        SU 35         SnAgSnAff = f! [.         a  n[-        SU 35         SnAgSnAff = f7f) z-Generate structured scenario from admin input details: 
roleplay_questionszO
GUIDED CONVERSATION QUESTIONS (The scenario should accommodate THESE topics):
   . questioncategory	objective, skills_to_assess)rG   rH   r@   skillssystemzHYou are a training scenario expert. Always respond with valid JSON only.rolecontentuserffffff?i   messagesr"   temperature
max_tokensNr   r   ```json   ```zJSON parsing error: Response text: zError generating scenario: )itemsget	enumerater   formatjoinr    chatcompletionscreater"   r2   usagechoicesmessagerO   strip
startswithendswithjsonloadsJSONDecodeErrorr   	Exception)r$   r=   details_textkeyvaluequestions_textrC   idxqpromptresponseresponse_textes                r%   generate_scenarioGroqService.generate_scenario>   s    :	L))4::<
%r% 33 =  N!,1E!F!!t'(:A>FC"Rj"0E/Fb&IIN ? 066$Z0%k2$5yy-?!@A	F "[[--99@@ !)#m
 !'#)	 jj A  H" $$Y?$,,Q/77??EEGM ++I66$1!"$5M ))%00$1#2$6Mzz-00;< '' ,QC0178
  	/s34	sm   G0C)G -F.AG  AF G0G G"G>G G0GG 
G-G(#G0(G--G0rC   conversation_historyc           
        ^ U(       d  gSR                  U Vs/ s H  o3R                  SS5      PM     sn5      R                  5       m/ n[        US5       H  u  pVUR                  SS5      R                  5       nUR	                  5       SS n[        U4S	 jU 5       5      n	U	(       a  S
OSn
UR                  SU SUR                  SS5       SU
 35        M     [        U5       H  u  pVUR                  SS5      R                  5       nUR	                  5       SS n[        U4S jU 5       5      n	U	(       a  MV  UR                  SUS-    SUR                  SS5       35          O   SR                  U5      $ s  snf )z
Analyze conversation history to determine which guided questions have been addressed.
Returns a formatted string explaining the progression status.
z&No guided questions for this roleplay. re   r?   rD   rF   N   c              3   P   >#    U  H  n[        U5      S :  d  M  UT;   v   M     g7fr|   Nlen.0keywordconversation_texts     r%   	<genexpr><GroqService._analyze_question_progression.<locals>.<genexpr>   )     eWTWX_T`cdTd8G'88   &&u   ✓ ADDRESSEDu   ⚠ NOT YET ADDRESSEDz	Question rA    - c              3   P   >#    U  H  n[        U5      S :  d  M  UT;   v   M     g7fr~   r   r   s     r%   r   r      r   r   z
**NEXT FOCUS**: Question rB   )r_   r\   lowerr]   splitanyappend)r$   rC   ry   turnprogression_linesrq   rr   question_textkeywords	addressedstatusr   s              @r%   _analyze_question_progression)GroqService._analyze_question_progression|   st   
 ";  HHJ^%_J^$hhy"&=J^%_`ffh 2A6FCEE*b1779M$**,Ra0HeeeI(1_7NF$$yRj"8M7NcRXQY%Z[ 7   23FCEE*b1779M$**,Ra0HeeeI9!((+FsQwisSTSXSXYcegShRi)jk 4 yy*+++ &`s   E=Nscenariouser_messageis_conclusionc                 (  #     SnU H#  nUS   S:X  a  SOUS   S   nXh SUS    S	3-  nM%     [        U V	s/ s H  oR                  S5      S:X  d  M  U	PM     sn	5      S
-   n
UR                  SS5      nUR                  SS5      nUR                  SS5      nUR                  SS5      nUR                  SS5      nU(       aR  [        nUS   S   US   S   US   S   US   S   US   R                  SS5      US   S   US   S   US   S   UUS.
nGOU(       a  [        nSn[	        US
5       H!  u  nnUU SUR                  SS5       S	3-  nM#     U R                  XR5      n0 S US   S   _SUS   S   _SUS   S   _SUS   S   _SUS   R                  SS5      _SUS   S   _SUS   S   _S!UR                  S!S5      _S"UR                  S#0 5      R                  SS5      _SUS   S   _S$U_S%U_S&U_S'U_SU_S(U_SU_UUU
S).EnO[        n0 S US   S   _SUS   S   _SUS   S   _SUS   S   _SUS   R                  SS5      _SUS   S   _SUS   S   _S!UR                  S!S5      _S"UR                  S#0 5      R                  SS5      _SUS   S   _S&U_S'U_SU_S(U_SU_SU_SU_S*U
0EnUR                  " S70 UD6nU R                  R                  R                  R                  S+S,S-.S.US-./U R                  S/S0S19I S2h  vN nU R                  S3UR                  5        UR                  S4   R                   R"                  R%                  5       $ s  sn	f  NV! [&         a  n[)        S5U 35         S2nAg6S2nAff = f7f)8z&AI character responses during roleplayr?   speakerlearnerLearnerai_characternamerA   re   rB   rD   roleplay_namezRoleplay Sessionai_role	Characterlearner_role
difficultymediumdurationi,  personalitygoals
backgroundemotional_stateneutralscenario_setupcontextenvironmentconstraints)
character_namer   r   r   r   r   r   r   ry   r   rE   rF   r   rH   additional_infor@   guided_questionsquestion_progress_analysisry   r   character_role)r   r   current_turnr   rL   a"  You are a world-class roleplay AI. You MUST stay strictly in character as a human-like counterpart (client, customer, etc.). You NEVER break character. You MUST follow the provided 'MANDATORY GUIDED QUESTIONS' if they exist. Respond professionally, naturally, and concisely (1-3 sentences).rM   rP   g?i   rR   Nr   r   zError in character roleplay: z:I'm having trouble responding right now. Please try again. )r   r\   r
   r   r]   r   r	   r^   r    r`   ra   rb   r"   r2   rc   rd   re   rO   rf   rl   r   )r$   r   ry   r   r   rC   history_textr   r   tr   r   r   r   r   r   prompt_templateprompt_kwargsrp   rq   rr   question_progressrs   rt   rv   s                            r%   play_characterGroqService.play_character   sc    o	PL,'+I)'C)R`IabhIi)2d9o->b AA -
 +?a+?a55CSW`C`+?abeffL %LL:LMM%\\)[AN#<<	BL!lH=J||J4H"=&.~&>v&F#+N#;M#J%n5g>"*>":<"H'/'?'C'CDUW`'a'(89)D#+,<#=m#L#+,<#=m#L,8$0! $"B!#'(:A>FC"Rj"0E/Fb&IIN ? %)$F$FGY$p!!$h~&>v&F!!8N#;M#J! Xn5g>! !(>":<"H	!
 &x'?'C'CDUW`'a! x(89)D! "8,<#=m#L!  k2!>! &x||Ir'B'F'F|UW'X! "8,<#=m#L! '! 12C! +L! #L! $]!  %n!!" #L#!$ #- ($0)!. #<!$h~&>v&F!!8N#;M#J! Xn5g>! !(>":<"H	!
 &x'?'C'CDUW`'a! x(89)D! "8,<#=m#L!  k2!>! &x||Ir'B'F'F|UW'X! "8,<#=m#L! +L! #L! $]! %n! #L!  !*!!" #!$ #L%!* %++<m<F![[--99@@ !) $H
 !'#)	 jj A  H" $$^X^^D##A&..66<<>>G  b`*  	P1!56O	PsS   N4M- M&M&J:M- M+AM- %N&M- -
N7N
N
NNconversation_turnsengagement_metadatac                 d  ^#     SnU H  nUS   S:X  a  SOSnXF SUS    S3-  nM     S	US
    SUS    SUS   S    SUS    SUS   S    SUS   S    S3nUS   n[        U5      n	[        R                  " SR                  U5      UUUU	S9n
U R                  R
                  R                  R                  SSS.SU
S./U R                  SSS 9I S!h  vN nU R                  S"UR                  5        UR                  S#   R                  R                  R                  5       n UR                  S$5      (       a  US%S! nOUR                  S&5      (       a  US'S! nUR!                  S&5      (       a  US!S( nUR                  5       n["        R$                  " U5      m['        U4S) jS* 5       5      (       d  [)        S+5        g!T$  N! ["        R*                   a  n[)        S,U 35        [)        S-U 35        S#S!KnUR/                  S.XR0                  5      nU(       a\   ["        R$                  " UR3                  5       5      m[)        S/5        Ts S!nA$ ! ["        R*                   a    [)        S05         Of = f S!nAg!S!nAff = f! [4         a  n[)        S1U 35         S!nAg!S!nAff = f7f)2z:Comprehensive skill analysis with engagement-aware scoringr?   r   r   r   zAI CharacterrA   re   rB   z
Category: rG   z
Objective: rH   z

Context: r   r   z
Success Criteria: success_criteriaz
AI Character: r   r   r   r   rJ   rI   )rK   scenario_contextr   r   skill_analysis_templaterL   zYou are an expert skill assessor. Provide STRICT, ACCURATE analysis in valid JSON format only. Do NOT inflate scores. Follow the engagement-based score ceilings exactly.rM   rP   g333333?i  rR   Nr   r   rV   rW   rX   r|   rY   c              3   ,   >#    U  H	  oT;   v   M     g 7f)Nr   )r   rn   analysiss     r%   r   -GroqService.analyze_skills.<locals>.<genexpr>O  s       M  7Ls(?  7Ls   )skill_analysisoverall_performanceconversation_analysisrecommendationszAnalysis missing required keysz JSON parsing error in analysis: rZ   z\{.*\}z0Successfully extracted JSON using regex fallbackzRegex fallback also failedzError analyzing skills: )r   r   r^   r_   r    r`   ra   rb   r"   r2   rc   rd   re   rO   rf   rg   rh   ri   rj   allr   rk   researchDOTALLgrouprl   )r$   r   r   r   r   r   r   r   rK   skill_templaters   rt   ru   rv   r   
json_matchr   s                   @r%   analyze_skillsGroqService.analyze_skills  s    W	 "*'+I)'C)!y4	?2C2%FF! +
$J
  ![!" #

#
$Y
/	0 1./0 1'/0H^4L\4Z3[ \  01F8@N*11yy(!1$7.(6F "[[--99@@ !) $O
 !'#)	 jj A  H" $$\8>>B$,,Q/77??EEGM" ++I66$1!"$5M"--e44$1!"$5M ))%00$1#2$6M - 3 3 5::m4   M  7L  M  M  M:;OR '' 8<=78 YYy-K
<#'::j.>.>.@#APQ'// <:;< "  	,QC01	s   J0CJ G	AJ )BG J0G J0	J JAJ#0IJJ J0I;8J:I;;J>J J0JJ 
J-J(#J0(J--J0rs   c                   #     U R                   R                  R                  R                  SSS.SUS./U R                  SSS9I Sh  vN nU R                  S	UR                  5        UR                  S
   R                  R                  R                  5       $  NQ! [         a  n[        SU 35         SnAgSnAff = f7f)z)Get a simple text completion from the LLMrL   z]You are a helpful assistant. Provide clear, natural responses without any formatting symbols.rM   rP   rQ   i  rR   Nr   r   zError getting completion: )r    r`   ra   rb   r"   r2   rc   rd   re   rO   rf   rl   r   )r$   rs   rt   rv   s       r%   get_completionGroqService.get_completionj  s     	![[--99@@ !) $C
 !'#)	 jj A  H" $$Y?##A&..66<<>>'*  	.qc23	sB   CAB 	B
AB CB 
B?'B:5C:B??Ctextc                 0  #    U R                   (       d  gU(       a  [        UR                  5       5      S:X  a  gUSS n [        R                  " S5      nSnSU 3SS.nS	S
USS.n[        SUSS  S35        [        R                  " SS9 ISh  vN nUR                  X4US9I Sh  vN nSSS5      ISh  vN   WR                  S:X  aT  UR                  nU(       a?  [        R                  " U5      R                  S5      n	[        S[        U	5       S35        U	$  g[        SUR                   SUR                   35        g N N N! , ISh  vN  (       d  f       N= f! [         a!  n
[        S[!        U
5       35         Sn
A
gSn
A
ff = f7f)z
Generate human-like voice using Groq's TTS model.
Uses direct HTTP request to avoid SDK version conflicts.
Returns base64 encoded audio string.
Nr   i  r   z+https://api.groq.com/openai/v1/audio/speechzBearer zapplication/json)AuthorizationzContent-Typezcanopylabs/orpheus-v1-englishtaramp3)r"   voicer   response_formatz*INFO: Requesting TTS from Groq for text: '   z...'g      >@)timeout)headersri      zutf-8z'SUCCESS: Generated TTS base64 (length: )zERROR: Groq TTS API returned rA   zEXCEPTION in generate_tts: )r!   r   rf   r   r   r   httpxAsyncClientpoststatus_coderO   base64	b64encodedecoder   rl   str)r$   r   r   urlr   payloadr    rt   
audio_data	b64_audiorv   s              r%   generate_ttsGroqService.generate_tts  s     ~~ s4::<(A- ET{"	ii/G?C $+7)!4 2G 9#(	G >tCRykNO((66&!'S!PP 76 ##s*%--
 & 0 0 < C CG LICC	NCSSTUV$$   5h6J6J5K2hmm_]^ 7P 7666  	/Ax89	s   =F AE( EE( E)E
*E.E( 9E:A%E( F E( !F"%E( FE( 
EE( E%EE%!E( (
F2F	FFF)r!   r    r"   r#   )FN)r?   )__name__
__module____qualname____firstlineno__r&   r   r2   r   r   r7   r;   r   rw   r   r   boolr   r   r   r   __static_attributes__r   r(   r%   r   r      s   
.@# @($sCx. (Q
<4S> <htTWY\T\~F^ <|,T#s(^@T ,lpquvy{~v~q  mA ,  FI ,@qPT#s(^ qPSWX\]`be]eXfSg qPwz qP  LP qP  nr  sw  x{  }@  x@  sA  nB qP  NV  WZ  N[ qPfYT#s(^ YQUVZ[^`c[cVdQe Y| Y  JR  SW  X[  ]`  X`  Sa  Jb Yv3 8C= 82s 2x} 2r(   r   )r   ri   r   r   typingr   r   r   r   groqr   config.promptsr   r	   r
   r   r   r   r   r   r(   r%   <module>r      s0    	    , ,  h hr(   