o
    2h]                     @   sV  d dl mZmZ d dlmZ d dlmZmZ d dlm	Z	m
Z
mZmZ d dlmZ d dlZd dlZd dlmZ e  d dlmZ d d	lmZ d d
lmZ d dlmZ d dlmZ d dlmZ eddddZejedgddgdgd e Z e Z!ee e!Z"ee e!Z#ee e!Z$G dd deZ%G dd deZ&G dd deZ'G dd deZ(G dd deZ)G dd  d eZ*G d!d" d"eZ+G d#d$ d$eZ,G d%d& d&eZ-G d'd( d(eZ.G d)d* d*eZ/G d+d, d,eZ0G d-d. d.eZ1G d/d0 d0eZ2e3d1d2d3 Z4e3d4d5d6 Z5ej6d7e*d8d9e)fd:d;Z7d_d9e)d<e8d=ee fd>d?Z9d@e:dAe:d=e:fdBdCZ;dDe:dEe<d=ee fdFdGZ=dHed=e-fdIdJZ>dHed=e	e
e:e:f  fdKdLZ?d<e8d=e(fdMdNZ@ej6dOe.d8d9e0fdPdQZAej6dRe/d8d9e)fdSdTZBej6dUe2d8d9e1fdVdWZCe3dXd`dDe:dEe<fdYdZZDeEd[krd dlFZFeFjGed\d]d^ dS dS )a    )FastAPIHTTPException)CORSMiddleware)	BaseModelField)ListDictAnyOptional)datetimeN)load_dotenv)ScenarioGenerator)RoleplayEngine)GroqService)OllamaService)SkillAnalyzer)RoleplayScenarioAI Roleplay Servicez,Simple AI service for roleplay functionalityz1.0.0)titledescriptionversion*T)allow_originsallow_credentialsallow_methodsallow_headersc                   @   s   e Zd ZU eed< eed< dS )	SkillDataskill_id
skill_nameN__name__
__module____qualname__str__annotations__ r%   r%   U/var/www/eduai.edurigo.com/doc_train/edurigo_ai/roleplay/testing/roleplay_fast_api.pyr   .      
 r   c                   @   sv   e Zd ZU eed< eed< edddZeed< eed< edd	dZeed
< ee	 ed< dZ
eed< eed< eed< dS )RoleplayDatacategory	objective.zLearner role)aliaslearner_roleadditional_info Constraints/Policiescompany_policiesskills_for_roleplayEasydifficulty_levelisAdmingroqRoleplayN)r    r!   r"   r#   r$   r   r,   r0   r   r   r3   intr%   r%   r%   r&   r(   2   s   
 r(   c                   @   &   e Zd ZU eed< eed< eed< dS )
TokenCountinputoutputtotalN)r    r!   r"   r6   r$   r%   r%   r%   r&   r8   =      
 r8   c                   @   s.   e Zd ZU eed< eed< eed< eed< dS )TokenCountspreviewconversation
assessmentservice_usedN)r    r!   r"   r8   r$   r#   r%   r%   r%   r&   r=   B   
   
 r=   c                   @   s.   e Zd ZU eed< eed< eed< eed< dS )RoleplayRequest	client_id
session_idroleplay_dataqueryNr    r!   r"   r#   r$   r(   r%   r%   r%   r&   rC   H   rB   rC   c                   @   s&   e Zd ZU eed< eed< eed< dS )RoleplayResponserE   responsetoken_countsN)r    r!   r"   r#   r$   r=   r%   r%   r%   r&   rI   N   r<   rI   c                   @   s6   e Zd ZU eed< eed< eed< eed< eed< dS )CharacterDetailsnamepersonalitygoals
backgroundemotional_stateNr   r%   r%   r%   r&   rL   S   s   
 rL   c                   @   r7   )ScenarioSetupcontextenvironmentconstraintsNr   r%   r%   r%   r&   rR   Z   r<   rR   c                   @   s   e Zd ZU 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< eed	< eed
< eeef ed< eed< eed< dS )PreviewResponsescenario_idr)   r*   r,   ai_roleskills_to_assessscenario_setupcharacter_detailsscenario_introconversation_startersuccess_criteriar3   background_infoN)	r    r!   r"   r#   r$   r   rR   rL   r   r%   r%   r%   r&   rV   _   s   
 rV   c                   @   s*   e Zd ZU eeeef  ed< eed< dS )ScenarioPreviewResponseslidesrK   N)r    r!   r"   r   r   r#   r$   r=   r%   r%   r%   r&   r`   n   s   
 r`   c                   @   s>   e Zd ZU eed< eed< dZeeeef  ed< e	ed< dS )EndSessionResponsemessagerE   Nr@   rK   )
r    r!   r"   r#   r$   r@   r
   r   r	   r=   r%   r%   r%   r&   rb   r   s
   
 rb   c                   @      e Zd ZU eed< eed< dS )EndSessionRequestrE   rF   NrH   r%   r%   r%   r&   re   x   r'   re   c                   @   rd   )CleanupRequestrE   is_adminN)r    r!   r"   r#   r$   r6   r%   r%   r%   r&   rf   |   r'   rf   c                   @   s.   e Zd ZU eed< eed< eeef ed< dS )CleanupResponserc   rE   cleanup_statusN)r    r!   r"   r#   r$   r   boolr%   r%   r%   r&   rh      s   
 rh   /c                      s   dddS )zHealth check endpointr   running)rc   statusr%   r%   r%   r%   r&   root   s   
rn   z/healthc               
      s   z<dt   i} td}|sddd| d< nddi| d< t }d|r(dnd	i| d
< |dup2|}|r7dnd| d< | W S  tyT } ztddt	| dd}~ww )zHealth check	timestampGROQ_API_KEYerrorzGROQ_API_KEY not configured)rm   rc   groqrm   healthyunavailableollamaNoverall  zHealth check failed: status_codedetail)
r   now	isoformatosgetenvollama_servicehealth_check	Exceptionr   r#   )health_statusapi_keyollama_availableoverall_healthyer%   r%   r&   r      s    
r   z	/roleplay)response_modelrequestc           	   
      s  z| j }| jjdk}td| dt| d td| j d td| jj  td|r0d	nd
 d| jj d td|  t|| jj}td|du  |std t| |}|set	dddtd t
j|| jjdd t|}t||j|dW S td| j  t
|| jj}td|du  |du rtd t
j|| jjdd t|}t||j|dW S z*t
||| j| jj|}td|du  |st	dddt|}t|||dW W S  ty } z
tdt|   d}~ww  t	y     ty2 } z%tdt|  tdt|  ddl}|  t	dd t| dd}~w t	y:     tyQ } zt	dd!t| dd}~ww )"zBHandle roleplay request - both first time and ongoing conversation   z&DEBUG: Received session_id from PHP: 'z	' (type: )zDEBUG: Received client_id: ''z&DEBUG: request.roleplay_data.isAdmin: DEBUG: Using GroqOllamaz for AI service (groqRoleplay=z Processing request for session: zScenario found: NzCreating new scenario...rw   zFailed to create scenariorx   zStarting new session...T)force_restart)rE   rJ   rK   zAdding learner response: zConversation history exists: z.Starting conversation for existing scenario...zAI response generated: zFailed to generate AI responsezError in add_learner_response: zError in handle_roleplay: zError type: r   zInternal error: zError processing roleplay: )rE   rF   r5   printtyperD   r4   load_scenario_for_sessioncreate_scenario_from_requestr   roleplay_enginestart_sessionget_token_counts_responserI   r\   rG   get_conversation_historyadd_learner_responser   r#   	traceback	print_exc)	r   rE   use_groqscenariorK   conversation_historyai_responser   r   r%   r%   r&   handle_roleplay   s   "

r   r   returnc                 C   s   z;t d| j d | j}dd |jD }|j|jd|jd}t|j|j}t	j
| j|j|j|||j||j|d	}|W S  tyU } zt d|  W Y d	}~d	S d	}~ww )
z.Create scenario from the roleplay request dataz8DEBUG create_scenario_from_request: request.session_id='r   c                 S   s   g | ]}|j qS r%   )r   ).0skillr%   r%   r&   
<listcomp>  s    z0create_scenario_from_request.<locals>.<listcomp>zRoleplay conversation)rP   rU   rT   r3   )	rE   r)   r*   detailsrX   r,   rY   rg   r   zError creating scenario: N)r   rE   rF   r1   r-   r0   r3   generate_ai_roler)   scenario_generatorcreate_scenarior*   r,   r4   r   )r   r   rF   rY   r   rX   r   r   r%   r%   r&   r      s6   r   r)   r-   c                 C   s~   dddddd}| |  d}d| v rd	| S d
| v s'd| v r,d| S d| v s8d| v r=d| S |S )z:Generate appropriate AI role based on category and contextzPotential CustomerzCustomer with IssuezTeam MemberzNegotiation PartnerzUser with Technical Problem)saleszcustomer service
leadershipnegotiationztechnical supportzConversation Partner
enterprisezEnterprise budgetpricezBudget-Conscious 
frustrated	complaintzFrustrated )getlower)r)   r-   category_roles	base_roler%   r%   r&   r   $  s   


r   rE   rg   c              
   C   sJ   zt | |W S  ty$ } ztd|  d|  W Y d}~dS d}~ww )z"Load scenario for existing sessionz#Error loading scenario for session z: N)r   load_scenarior   r   )rE   rg   r   r%   r%   r&   r   :  s   r   r   c                 C   s  zot | jdd| jdd| jdd| jdd| jddd}t| jd	d| jd
d| jddd}i }t| jtrE| j}ndt| ji}t	| j
| j| j| j| j| j||| j| j|| jdd| jdddW S  ty } ztd|   d}~ww )z.Convert scenario to formatted preview responserM   zAI CharacterrN   zNot specifiedrO   rP   rQ   )rM   rN   rO   rP   rQ   rS   rT   rU   )rS   rT   rU   generalr3   Medium)rW   r)   r*   r,   rX   rY   rZ   r[   r\   r]   r^   r3   r_   z'Error formatting scenario for preview: N)rL   ai_characterr   rR   rZ   
isinstancer^   dictr#   rV   idr)   r*   r,   rX   rY   r\   r]   r   r   r   )r   r[   rZ   r^   r   r%   r%   r&   format_scenario_for_previewC  sJ   	r   c              
   C   s   z1g }| j dd }|r|d|d | j dd }|r/| dvr/|d|d |W S  tyU } ztd|  dd	| j d
dgW  Y d}~S d}~ww )z,Convert scenario to slide-based array formatrS   r.   Context)headingcontentrU   )r.   znot specifiednoner/   z%Error formatting scenario as slides: z
This is a z7 roleplay scenario where you will practice your skills.N)rZ   r   stripappendr   r   r   r)   )r   ra   rS   rU   r   r%   r%   r&   format_scenario_as_slidesr  s.   r   c                 C   s   | rt nt}| }tt|d d |d d |d d dt|d d |d d |d d dt|d d |d d |d d d| rGdd
S d	d
S )z0Get token counts from the appropriate AI servicer>   r9   r:   r;   )r9   r:   r;   r?   r@   rr   ru   )r>   r?   r@   rA   )groq_servicer   get_token_countsr=   r8   )r   
ai_service
token_datar%   r%   r&   r     s,   








r   z/roleplay_scenarioc              
      s  z[| j jdk}td| j  td|rdnd d t| j| j j}|r9td t|}t|}t||dW S td	 t	| |}|sJt
d
ddt|}t|}td t||dW S  t
yd     ty } ztdt|  ddl}|  t
d
dt| dd}~ww )z9Generate and return formatted preview data as slide arrayr   z(Processing preview request for session: r   r   r   z for preview generationz#Using existing scenario for preview)ra   rK   z!Creating new scenario for previewrw   z%Failed to create scenario for previewrx   z%Preview slides generated successfullyz(Error in get_roleplay_scenario_preview: r   NzError generating preview: )rF   r5   r   rE   r   r4   r   r   r`   r   r   r   r#   r   r   )r   r   existing_scenarioslides_responserK   r   r   r   r%   r%   r&   get_roleplay_scenario_preview  s8   
r   z/end_sessionc              
      s  z| j jdk}td| j d| j j  td|rdnd d t| j| j j}|s1tdd	d
t| j| j j}|sBtddd
t	| j| j j}|sStddd
td| j  t
| j||| j j|}td|du  t|}td|  |rtnt}|  td |rtd tj| j| j j}td|  d| j|d}	|r| |	d< tdi |	W S  ty     ty }
 ztddt|
 d
d}
~
ww )zBEnd a roleplay session and automatically generate skill assessmentr   zDEBUG end_session: session_id='z', roleplay_data.isAdmin=r   r   r   z for assessment generation  zSession/Scenario not foundrx   zNo conversation history foundrw   zFailed to end sessionz0DEBUG: About to generate assessment for session zDEBUG: Assessment generated: Nz(DEBUG: Final token counts before reset: z3DEBUG: Token counts reset to zero after end_sessionz8DEBUG: Deleting conversation after successful assessmentzDEBUG: Conversation deleted: zSession ended successfully)rc   rE   rK   r@   zError ending session: r%   )rF   r5   r   rE   r4   r   r   r   %get_conversation_turns_for_assessmentend_sessionskill_analyzeranalyze_sessionr   r   r   reset_token_countsjson_handlerdelete_conversationto_dictrb   r   r#   )r   r   r   conversation_turnssuccessr@   final_token_countsr   conversation_deletedresponse_datar   r%   r%   r&   r     sN   r   z/cleanupc              
      s  zt d| j  dddd}ztj| j| j}||d< t d|  W n ty? } zt d|  W Y d}~nd}~ww ztj| j| j}||d< t d	|  W n tyo } zt d
|  W Y d}~nd}~ww zt	j
| j| j}||d< t d|  W n ty } zt d|  W Y d}~nd}~ww t d| j  td| j|dW S  ty } zt dt|  tddt| dd}~ww )zKDelete all session-related data after assessment has been saved to databasez,DEBUG: Cleaning up session data for session F)scenario_deletedassessment_deletedr   r   z!DEBUG: Scenario deletion result: zError deleting scenario: Nr   z#DEBUG: Assessment deletion result: zError deleting assessment: r   z%DEBUG: Conversation deletion result: zError deleting conversation: zCLEANUP COMPLETED - Session: z$Session data cleaned up successfully)rc   rE   ri   zError in cleanup_session_data: rw   z Error cleaning up session data: rx   )r   rE   r   r   delete_scenariorg   r   r   delete_assessmentr   r   rh   r#   r   )r   ri   r   r   r   r   r%   r%   r&   cleanup_session_data  sT   r   z/session/{session_id}/historyc              
      s^   zt | |}|du rtddd| |dW S  ty. } ztddt| dd}~ww )z&Get conversation history for a sessionNr   zSession not foundrx   )rE   r   rw   zError retrieving history: )r   r   r   r   r#   )rE   rg   historyr   r%   r%   r&   get_session_history@  s   r   __main__z0.0.0.0i@  )hostport)T)r   )Hfastapir   r   fastapi.middleware.corsr   pydanticr   r   typingr   r   r	   r
   r   uuidr}   dotenvr   services.scenario_generatorr   services.roleplay_enginer   services.groq_servicer   services.ollama_servicer   services.skill_analyzerr   models.scenarior   appadd_middlewarer   r   r   r   r   r   r(   r8   r=   rC   rI   rL   rR   rV   r`   rb   re   rf   rh   r   rn   r   postr   rj   r   r#   r   r6   r   r   r   r   r   r   r   r   r    uvicornrunr%   r%   r%   r&   <module>   s    	




X'	/!%;0
