o
    .i                     @   s  d dl mZmZ d dl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mZ d dlZd dlZd dlZd dlZd dlmZ d d	lmZ d dlZd dlmZ d d
lmZmZmZ d dlZde de fddZ!de dee  de fdd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. d dl/m0Z0 eddddZ1e1j2edgddgdgd  e( Z3e* Z4e$e3e4Z5e&e3e4Z6e,e3e4Z7e. Z8G d!d" d"eZ9G 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>d-e;dee  fd.d/Z?G d0d1 d1eZ@G d2d3 d3eZAG d4d5 d5eZBG d6d7 d7eZCG d8d9 d9eZDG d:d; d;eZEG d<d= d=eZFG d>d? d?eZGG d@dA dAeZHG dBdC dCeZIG dDdE dEeZJG dFdG dGeZKG dHdI dIeZLe1MdJdKdL ZNe1MdMdNdO ZOe1jPdPe@dQdRe>fdSdTZQe1jPdUeEdQdRe>fdVdWZRe1jPdXeFdQdRe>fdYdZZSe1jPd[eIdQdReHfd\d]ZTe1jPd^eLdQdReKfd_d`ZUddRe>daeVdee0 fdbdcZWdde dee de fdfdgZXdhe dieYdee0 fdjdkZZdle0deee e f  fdmdnZ[daeVde=fdodpZ\dqe0de fdrdsZ]dte due dvee  dee  fdwdxZ^dde dte due dee dye de fdzd{Z_d|e dee  fd}d~Z`dejdejfddZadejdeYdeYdejfddZbd|e dee  fddZcdd|e de dee  fddZddS )    )FastAPIHTTPException)CORSMiddleware)JSONResponse)	BaseModelField)ListDictAnyOptional)datetime	timedeltaN)load_dotenv)Image)r   ImageEnhanceImageFiltertextreturnc                 C   s:   | s| S t dd| } t dd| }t dd|}| S )z
    Cleans response text by removing distracting symbols (like asterisks)
    while preserving professional data symbols ($ % / &) and standard punctuation.
    z[*_~`#] z.[^a-zA-Z0-9\s.,!?\'":;()\-\n$%/\&\+=@\[\]\{\}]z + )resubstrip)r   cleaned r   C/var/www/eduai.edurigo.com/roleplay/production/roleplay_fast_api.py
clean_text   s   r   starterdate_time_strc              
   C   s>  d}z"|r#|  }t|dkr#|d  d|d  }t|d}|j}W n ty@ } ztd| d|  W Y d}~nd}~ww |du rJt j}|d	k rQd
}n	|dk rXd}nd}td| d|  |  } ddl	}	 | }	|j
dd| |jd } | |	krnqm|j
dd| |jd}
|
r|
d  |
dd  }
| |
 S )z^Formats the conversation starter by stripping AI headers and prepending a time-based greeting.N   r   z%I:%M %pz!DEBUG: Failed to parse dateTime 'z':    zGood morning.    zGood afternoon. zGood evening. zDEBUG: Selected greeting 'z' based on hour r   Tz\^\s*\*?\*?(Roleplay Background|Character Introduction|AI Roleplay|Scenario|Context)[^\n]*\n+r   )flagszX^\s*(hi|hello|greetings|good morning|good afternoon|good evening|good day|hey)[,!\.]*\s*   )splitlenr   strptimehour	Exceptionprintnowr   r   r   
IGNORECASEupper)r   r   r)   partstime_strdtegreetingr   originalcleaned_starterr   r   r   format_conversation_starter*   sD   
r6   )ScenarioGenerator)RoleplayEngine)GroqService)OllamaService)SkillAnalyzer)
TTSService)RoleplayScenarioAI Roleplay Servicez:AI service for roleplay scenario preview and conversationsz2.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< eed< eed< eed< eed< eed< dZee ed	< eed
< dS )TextToSpeechDataidlanguagevoicenamestatus	file_nameroleplay_statusNgenderis_ai_voice)__name__
__module____qualname__str__annotations__rO   r   r   r   r   r   rG   ~   s   
 rG   c                   @   s   e Zd ZU eed< eed< dS )	SkillDataskill_id
skill_nameNrQ   rR   rS   rT   rU   r   r   r   r   rV         
 rV   c                   @   s  e Zd ZU dZeed< dZee ed< dZee	 ed< eed< e
dddZee ed	< dZee ed
< eed< e
dddZeed< dZee ed< e
dddZeeeeef   ed< dZeee  ed< dZeee  ed< dZeee  ed< dZeed< dZeed< dZe	ed< dZe	ed< dZee ed< dZee ed< dZee	 ed< dZeed< dZ e	ed < d!Z!e	ed"< dZ"ee ed#< G d$d% d%Z#dS )&RoleplayDatar   categoryNcategory_namecategory_id	objectiveLearner rolealiaslearner_roleroleadditional_infoConstraints/Policiescompany_policiesconstraintsroleplay_questionsskills_for_roleplayskill_names	skill_idsEasydifficulty_levelmedium
difficultyr   isAdminr%   groqRoleplayrJ   text_to_speech_datais_text_to_speechroleplay_namei,  durationd   max_attemptslms_roleplay_item_idc                   @      e Zd ZdZdS )zRoleplayData.ConfigTNrQ   rR   rS   populate_by_namer   r   r   r   Config       r}   )$rQ   rR   rS   r\   rT   rU   r]   r   r^   intr   rc   rd   rg   rh   ri   r   r	   r
   rj   rV   rk   rl   rn   rp   rq   rr   rJ   rs   rG   rt   ru   rv   rx   ry   r}   r   r   r   r   r[      s4   
 $r[   c                   @   &   e Zd ZU eed< eed< eed< dS )
TokenCountinputoutputtotalN)rQ   rR   rS   r   rU   r   r   r   r   r         
 r   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)rQ   rR   rS   r   rU   rT   r   r   r   r   r      s
   
 r   c                   @   sz   e Zd ZU dZee ed< dZee ed< eed< dZ	ee ed< g Z
eee  ed< dZee ed	< dZee ed
< dS )RoleplayRequestN	client_id
session_idroleplay_datar   queryprevious_roleplay_memoryr   
query_typedateTime)rQ   rR   rS   r   r   rT   rU   r   r[   r   r   r   r
   r   r   r   r   r   r   r      s   
 r   datac                 C   sB   d}| j r	| j }n| jr| jj r| jj }|r|S | jdkrdS dS )z
    Helper to extract Piper voice model name from either root or nested payload.
    Also respects the is_text_to_speech flag.
    Nr%   default)rJ   rs   rt   )r   rJ   r   r   r   extract_voice_model   s   
r   c                   @   s6   e Zd ZU eed< eed< eed< dZee ed< dS )RoleplayResponser   responsetoken_countsNvoice_base64)rQ   rR   rS   rT   rU   r   r   r   r   r   r   r   r      s
   
 r   c                   @   s6   e Zd ZU eed< eed< eed< eed< eed< dS )CharacterDetailsrK   personalitygoals
backgroundemotional_stateNrY   r   r   r   r   r      s   
 r   c                   @   r   )ScenarioSetupcontextenvironmentrh   NrY   r   r   r   r   r      r   r   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_   rc   ai_roleskills_to_assessscenario_setupcharacter_detailsscenario_introconversation_startersuccess_criteriarn   background_infoN)	rQ   rR   rS   rT   rU   r   r   r   r	   r   r   r   r   r      s   
 r   c                   @   s2   e Zd ZU eed< eed< dZeee  ed< dS )SlideheadingcontentNr   )rQ   rR   rS   rT   rU   r   r   r   r   r   r   r   r      s   
 r   c                   @   s:   e Zd ZU ee ed< eed< eed< dZe	e ed< dS )ScenarioPreviewResponseslidesscenarior   Nroleplay_image_base64)
rQ   rR   rS   r   r   rU   rT   r   r   r   r   r   r   r   r      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messager   Nr   r   )
rQ   rR   rS   rT   rU   r   r   r	   r
   r   r   r   r   r   r     s
   
 r   c                   @      e Zd ZU eed< eed< dS )EndSessionRequestr   r   N)rQ   rR   rS   rT   rU   r[   r   r   r   r   r   
  rZ   r   c                   @   r   )CleanupRequestr   is_adminN)rQ   rR   rS   rT   rU   r   r   r   r   r   r     rZ   r   c                   @   s.   e Zd ZU eed< eed< eeef ed< dS )CleanupResponser   r   cleanup_statusN)rQ   rR   rS   rT   rU   r	   boolr   r   r   r   r     s   
 r   c                   @   st   e Zd ZU dZeed< eed< edddZeed< dZeed	< dZ	eed
< dZ
eed< dZeed< G dd dZdS )RoleplayImageDataz=Simplified roleplay data model for image generation endpoint.r\   r_   .r`   ra   rc   r   ru   re   r   isGPUrq   c                   @   rz   )zRoleplayImageData.ConfigTNr{   r   r   r   r   r}   #  r~   r}   N)rQ   rR   rS   __doc__rT   rU   r   rc   ru   re   r   r   rq   r}   r   r   r   r   r     s   
 r   c                   @   s   e Zd ZU dZeed< dS )RoleplayImageRequestz+Request model for /roleplay_image endpoint.r   N)rQ   rR   rS   r   r   rU   r   r   r   r   r   '  s   
 r   c                   @   s2   e Zd ZU dZeed< dZeed< dZeed< dS )RoleplayImageResponsez,Response model for /roleplay_image endpoint.successr   r   r   N)	rQ   rR   rS   r   r   rU   r   rT   r   r   r   r   r   r   ,  s
   
 r   /c                      s   dddS )Nr>   running)r   rL   r   r   r   r   r   root4  s   
r   z/healthc               
      s   z8dt   i} td}|rddinddd| d< t I d H }d|r(dnd	i| d
< |s1|r3dnd| d< | W S  tyP } ztddt	| dd }~ww )N	timestampGROQ_API_KEYrL   healthyerrorzGROQ_API_KEY not configured)rL   r   groqunavailableollamaoverall  zHealth check failed: status_codedetail)
r   r,   	isoformatosgetenvollama_servicehealth_checkr*   r   rT   )health_statusapi_keyollama_availabler2   r   r   r   r   8  s   
r   z	/roleplay)response_modelrequestc              
      s^  zt d| j  t d| jjdd  | jptt }t| j}| jjdk}t	|| jj
}|rV|j  | jj  krVt d| d tj|| jj
 d }|st| |I d H }|shtdd	d
t|j| j|_tj|| jj
dd t|}t|j}d }|rtj||d}t||||dW S t|| jj
}|d u rt|j| j|_tj|| jj
dd t|}t|j}d }|rtj||d}t||||dW S t||| jpd| jj
|I d H }	|	stddd
t|}t|	}
d }|rtj|
|d}t||
||dW S  ty     ty. } zdd l }|!  tddt| d
d }~ww )Nz.DEBUG: Received roleplay request for session: zDEBUG: Roleplay Data: T)by_aliasr%   z%DEBUG: Objective changed for session . Regenerating scenario.r   zFailed to create scenarior   )force_restartrJ   )r   r   r   r   r   zFailed to generate AI responser   zInternal error: )"r+   r   r   dictrT   uuiduuid4r   rr   load_scenario_for_sessionrq   r_   r   lowerroleplay_enginejson_handlerdelete_conversationcreate_scenario_from_requestr   r6   r   r   start_sessionget_token_counts_responser   tts_servicegenerate_voice_base64r   get_conversation_historyadd_learner_responser   r*   	traceback	print_exc)r   r   voice_modeluse_groqr   r   r5   r   conversation_historyai_responsecleaned_responser2   r   r   r   r   handle_roleplayG  s   
"


r   z/roleplay_scenarioc              
      s
  zt d| j  | jptt }t| j}| jjdk}t|| jj	}|r@|j
  | jj
  kr@t d| d d }|pIt| |I d H }|sRtdddt|}t|j|j
|jp_g d}t|}d	d
 |D }	|	tdd|d t|}
d }z/| jjp| jjpd}| jjp| jjpd}| jjp| jj}t||| jj
| jj|d}t|}W n ty } zd }t d|  W Y d }~nd }~ww d }|rt j!|j"|d}t#|	||
||dW S  ty     ty } zdd l$}|%  tddt| dd }~ww )Nz6DEBUG: Received scenario preview request for session: r%   z0DEBUG: Objective changed for preview in session r   r   z%Failed to create scenario for previewr   )rc   r_   skillsc                 S   s    g | ]}t |d  |d dqS )r   r   r   r   )r   .0sr   r   r   
<listcomp>  s     z1get_roleplay_scenario_preview.<locals>.<listcomp>Goalsz,Focus on these outcomes during the roleplay.)r   r   r   GeneralParticipant)r\   rc   r_   re   rg   z8WARNING: Pollinations ultra HD image generation failed: r   )r   r   r   r   r   r   zError generating preview: )&r+   r   rT   r   r   r   r   rr   r   rq   r_   r   r   r   r    build_professional_scenario_textbuild_short_goalsrc   r   format_scenario_as_slidesappendr   r   r]   r\   rd   rh   rg   "build_pollinations_ultra_hd_promptre   %pollinations_generate_ultra_hd_base64r*   r   r   r   r   r   r   )r   r   r   r   existing_scenarior   scenario_text
goals_listbase_slidesslides_as_modelsr   roleplay_image_b64cat	role_nameconstraints_textpoll_promptr2   r   r   r   r   r   get_roleplay_scenario_preview  sx   
"r  z/end_sessionc                    s  z| j jdk}t| j| j j}|stdddt| j| j j}|s)tdddt| j| j jI d H }|s=tdddt	
| j||| j j|I d H }t|}|rTtnt}|  |rmtj| j| j j}td|  d	| j|d
}	|r| }
d|
v r|
d D ]>}d|v r|d rztt|d }|tddd }|d|d< W q ty } ztd|  W Y d }~qd }~ww q|
|	d< tdi |	W S  ty     ty } ztddt| dd }~ww )Nr%   i  zSession/Scenario not foundr   zNo conversation history foundr   zFailed to end sessionz"DEBUG: Session cleanup performed: zSession ended successfully)r   r   r   conversation_turnsr         )hoursminutesz%d/%m/%y %I:%M %pzError formatting timestamp: r   zError ending session: r   )r   rr   r   r   rq   r   r   %get_conversation_turns_for_assessmentend_sessionskill_analyzeranalyze_sessionr   groq_servicer   reset_token_countsr   cleanup_sessionr+   to_dictr   fromisoformatrT   r   strftimer*   r   )r   r   r   r  r   r   final_token_counts
ai_servicecleanup_resultsresponse_dataassessment_dictturndt_objdt_istr2   r   r   r   r    sf   


r  z/cleanupc              
      sV   zt j| j| j}td| j|dW S  ty* } ztddt| dd }~ww )Nz$Session data cleaned up successfully)r   r   r   r   z Error cleaning up session data: r   )	r   r   r  r   r   r   r*   r   rT   )r   r   r2   r   r   r   cleanup_session_data+  s   r'  z/roleplay_imagec              
      s   z2| j j| j j| j j| j j| j jd}td| j j  t|}|r,t	d|ddW S t	ddddW S  t
yY } zd	d
l}|  t	dddt| dW  Y d
}~S d
}~ww )a  
    Fetch a copyright-free, relevant image for roleplay based on provided context.

    Uses Pixabay API to find professional images matching the roleplay scenario.
    Returns the image as a base64-encoded JPEG string.

    Args:
        request: RoleplayImageRequest containing roleplay_data with:
            - category: Type of roleplay (sales, customer service, etc.)
            - objective: Learning objective
            - Learner role: Role the learner plays
            - roleplay_name: Name of the scenario
            - additional_info: Extra context

    Returns:
        RoleplayImageResponse with success status and base64 image
    )r\   r_   r`   ru   re   z6INFO: Processing roleplay_image request for category: Tz'Image fetched successfully from Pixabay)r   r   r   Fr   zMCould not fetch a relevant image. Please check Pixabay API key configuration.r   NzError generating image: )r   r\   r_   rc   ru   re   r+   image_scraper_serviceget_roleplay_imager   r*   r   r   rT   )r   roleplay_data_dictimage_base64r2   r   r   r   r   r)  5  s>   
r)  r   c                    sF  z| j }|jp|jpd}|j}|jp|jpd}g }|jr!|j}n|jr,dd |jD }|j|j	p3|j
d|jp9|j| jd}t||j}td|d d  d	 td
|  td|j  tj| jpitt |||||||j||j|j||jp||j|j|jdI d H }	|	W S  ty }
 ztd|
  W Y d }
~
d S d }
~
ww )Nr   r   c                 S   s   g | ]}|j qS r   )rX   r   r   r   r   r     s    z0create_scenario_from_request.<locals>.<listcomp>zRoleplay conversation)r   rh   r   rn   r   z)DEBUG: Creating scenario with objective: 2   ...zDEBUG: Skills: zDEBUG: Roleplay Questions: )r   r\   r_   detailsr   rc   r   r   r   ri   ru   rd   rp   rv   rx   zError creating scenario: )r   r]   r\   r_   rd   rc   rk   rj   re   rh   rg   rp   rn   r   generate_ai_roler+   ri   scenario_generatorcreate_scenarior   rT   r   r   rq   ru   rv   rx   r*   )r   r   r   r  objr  r   r.  r   r   r2   r   r   r   r   r  sX   


r   r\   re   c                 C   sr   dddddd}| |  d}| }d|v rd	| S d
|v s%d|v r*d| S d|v s2d|v r7d| S |S )Nz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 )getr   )r\   re   category_roles	base_rolelowr   r   r   r/    s   


r/  r   r   c              
   C   sJ   zt | |W S  ty$ } ztd|  d|  W Y d }~d S d }~ww )Nz#Error loading scenario for session z: )r0  load_scenarior*   r+   )r   r   r2   r   r   r   r     s   r   r   c              
   C   s   z3g }| j dp
d }|r|d|d | j dpd }|r1| dvr1|d|d |W S  tyW } ztd|  dd	| j d
dgW  Y d }~S d }~ww )Nr   r   Contextr   rh   )r   znot specifiednonerf   z%Error formatting scenario as slides: z
This is a z7 roleplay scenario where you will practice your skills.)r   r;  r   r  r   r*   r+   r\   )r   r   r   rh   r2   r   r   r   r    s   "r  c                 C   sZ   | rt nt}| }ttdi |d tdi |d tdi |d | r)ddS ddS )Nr   r   r   r   r   )r   r   r   r   r   )r  r   get_token_countsr   r   )r   r   tdr   r   r   r     s   r   scnc              	   C   s   | j }| j}| j}| j}| jdpd}d|  d| d|  d|  d	g}|rTd|v r;| dd d nt	|d	krK| d d	 d
 n| }|
| d|S )Nr   r   zIn this z roleplay, you act as a z collaborating with an z to achieve the objective: .r   rw   r-  r   )r\   rc   r   r_   r   r;  r   r   r&   r'   r  join)rD  r\   learnerr   r_   r   r/   short_contextr   r   r   r     s   (F

r   rc   r_   r   c                 C   s   g d}| d | d d |  }g }d|v r|d d|v s&d|v r+|d d|v s3d	|v r8|d
 d|v s@d|v rE|d |d d D ]}t|dk rX|| qK|d d S )N)z-Clarify the user's intent and missing detailsz@Structure effective prompts with clear instructions and examplesz4Validate responses for accuracy, tone, and relevancez4Iterate based on feedback to improve the next outputr   promptz8Apply prompt patterns (role, task, context, constraints)customersupportz.Use empathetic, concise language for end users	technicalengineeringz,Ground outputs in accurate, testable detailsr3  r5  z)Surface value, objections, and next stepsr      )rF  r   r  r'   )rc   r_   r   baser   customcr   r   r   r     s    




r   rg   c                 C   s^   d|  d| ddddddd	g}|r&t | d
kr&|| dd  d|dd S )z
    Build a concise, focused ultra HD prompt for Pollinations.
    Shorter, more focused prompts often yield better results.
    zprofessional z scenez in modern office environmentphotorealisticz8K ultra HDzsharp focuszprofessional lightingzcinematic compositionzhigh detail
   Nrw   z, r"   )r'   r   r  rF  )r\   rc   r_   re   rg   scene_partsr   r   r   r    s   
r  rI  c              
   C   s  d}d}d}d}t j| dd}d| d| d	| d
tt| d  }ddddd}ztd| d| d tj||ddd}|jdkrOtd|j  W dS |j}	|	rZt	|	dk ratd W dS t
t|	}
|
d}
|
j\}}td| d| dt	|	 d t|
}
t|
||}|tjd dd!d"}t }|j|d#d$ddd%d& t| d'}t	| }td(| d| d)| d |W S  tjy   td* Y dS  ty } ztd+t|  d%dl}|  W Y d}~dS d}~ww ),z
    Enhanced version with multiple strategies for HD image generation.
    Uses higher base resolution and better upscaling techniques.
      8  i 
  i  r   safe%https://image.pollinations.ai/prompt/z?width=z&height=z7&nologo=true&private=true&enhance=true&model=flux&seed=i@B z7image/jpeg,image/png,image/webp,image/*;q=0.9,*/*;q=0.8z<Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36zgzip, deflate, brzno-cache)Acceptz
User-AgentzAccept-EncodingzCache-Controlz-INFO: Requesting HD image from Pollinations (xz)...x   T)headerstimeoutstream   z$ERROR: Pollinations returned status N  z(ERROR: Received invalid/empty image dataRGBzINFO: Received image: z (z bytes)r%      )radiuspercent	thresholdJPEGb   r   )formatqualityoptimizeprogressivesubsamplingutf-8zSUCCESS: Generated z HD image (z#ERROR: Timeout while fetching imagez ERROR: Image generation failed: )upquoteabshashr+   requestsr;  r   r   r'   r   openioBytesIOconvertsizeenhance_image_qualityresize_and_crop_hqfilterr   UnsharpMasksavebase64	b64encodegetvaluedecodeTimeoutr*   rT   r   r   )rI  TARGET_WIDTHTARGET_HEIGHTREQUEST_WIDTHREQUEST_HEIGHTencoded_prompturlr]  respr   imgorig_worig_h	img_finaloutput_bytes
b64_result
final_sizer2   r   r   r   r   r    st   


 	r  r  c                 C   s@   t | }|d} t | }|d} t | }|d} | S )z2
    Apply quality enhancements to the image.
    g?gffffff?g?)r   Contrastenhance	SharpnessColor)r  enhancerr   r   r   ry  w  s   





ry  target_wtarget_hc                 C   s   | j \}}|| }|| }||kr|}t|||  }n
|}t|||  }| j||ftjd}	|| d }
|| d }|
| }|| }|	|
|||f}|S )zi
    High-quality resize and crop to exact dimensions.
    Uses Lanczos resampling for best quality.
    )resampler   )rx  r   resizer   LANCZOScrop)r  r  r  r  r  target_ratio
orig_rationew_hnew_wimg_resizedlefttoprightbottomimg_croppedr   r   r   rz    s   
rz  c                 C   s0   t | }|r|S td t| dd}|r|S dS )zC
    Try multiple strategies/services for HD image generation.
    z9INFO: Pollinations failed, trying alternative approach...turbo)modelN)r  r+   try_alternative_pollinations)rI  resultr   r   r   generate_hd_image_with_fallback  s   r  r  r  c           	   
   C   s   ddl m} |j| dd}d| d| d}zItj|dd	}|jd
krZt|jdkr]t	t
|j}|d}t|}t|dd}t
 }|j|dddd t| dW S W dS W dS  tyy } ztd|  W Y d}~dS d}~ww )z;
    Try Pollinations with alternative model settings.
    r   Nr   rW  rY  z?width=1920&height=1080&model=z&enhance=true&nologo=truer\  )r^  r`  ra  rb  rU  rV  rg  rh  T)ri  rj  rk  rn  zAlternative strategy failed: )urllib.parseparserp  rs  r;  r   r'   r   r   rt  ru  rv  rw  ry  rz  r}  r~  r  r  r  r*   r+   )	rI  r  ro  r  r  r  r  r   r2   r   r   r   r    s2   	
r  )T)r  )efastapir   r   fastapi.middleware.corsr   fastapi.responsesr   pydanticr   r   typingr   r	   r
   r   r   r   r   r~  rs  r   dotenvr   PILr   ru  r  r  ro  r   r   r   rT   r   r6   services.scenario_generatorr7   services.roleplay_enginer8   services.groq_servicer9   services.ollama_servicer:   services.skill_analyzerr;   services.tts_servicer<   models.scenarior=   appadd_middlewarer  r   r0  r   r  r   rG   rV   r[   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r;  r   r   postr   r  r  r'  r)  r   r   r/  r   r   r  r   r   r   r  r  ry  rz  r  r  r   r   r   r   <module>   s   1	


!	

ZG@	<5
"
Z" 