
    ﾋh+0                     \   U d dl Z d dlZd dlZd dlZd dlZd dlmZmZmZm	Z
 ddlmZ ddlmZmZ dedefd	Zdefd
ZdefdZ e       ZdZdZdZd e        ddZd,dededefdZ G d d      Zi Zeeef   ed<   dededee   defdZ  ejB                  d      d        Z" ejB                  d      d         Z# ejB                  d!      d"        Z$d#efd$Z% ejL                  d%      d&efd'       Z' ejB                  d(      d&efd)       Z( ejL                  d*      d&efd+       Z)y)-    N)requestjsonifyResponsecurrent_app   )bp_api   )okfailtextreturnc                 :    dj                  d | xs dD              S )N c              3   >   K   | ]  }t        |      d k  s|  yw)   N)ord).0cs     -/var/www/html/vivango/api/ia/app/routes/ai.py	<genexpr>z"_sanitize_ascii.<locals>.<genexpr>   s     ;c!fsl1;s   )join)r   s    r   _sanitize_asciir      s    77;tzr;;;    c                  ~    t        j                  dd      j                         } t        |       }|st	        d      |S )NAIML_API_KEYr   uE   AIML_API_KEY não encontrado ou contém apenas caracteres inválidos.)osgetenvstripr   RuntimeError)raw_key	clean_keys     r   _get_api_keyr"   	   s:    ii+113G(Ibccr   c                      d} t        j                  d|       j                         j                  d      }t	        |      }|st        d      |S )Nzhttps://api.aimlapi.com/v1AIML_BASE_URL/uF   AIML_BASE_URL não encontrado ou contém apenas caracteres inválidos.)r   r   r   rstripr   r   )defaultraw_url	clean_urls      r   _get_base_urlr*      sJ    *Gii1779@@EG(Icddr   z+meta-llama/Meta-Llama-3.1-8B-Instruct-Turbozgpt-4ozimagen-3.0-generate-002zBearer zapplication/json)AuthorizationzContent-Typepathpayloadtimeoutc                    t          |  }	 t        j                  |t        ||      }|j	                          |j                         S # t        j
                  $ rd}j                  dk(  rOd|j                  j                         v r3|j                  d      t        k7  rt        |d<   t        | ||      cY d }~S  d }~ww xY w)N)headersjsonr.   i  verificationmodel)	AIML_BASErequestspostHEADERSraise_for_status	HTTPErrorstatus_coder   lowergetFREE_FALLBACK
_call_aimlr1   )r,   r-   r.   urlres         r   r>   r>   "   s    Kv
CMM#wWgN	 668O  ==CNafflln$D{{7#}4#0 !$99s$   -A	 	C AB;4C :B;;C c                   6    e Zd ZdZdededee   fdZdefdZy)	_Session)promptr3   eventslast_urlfieldsrD   r3   rG   c                 n    || _         || _        t        j                         | _        d | _        || _        y N)rD   r3   queueQueuerE   rF   rG   )selfrD   r3   rG   s       r   __init__z_Session.__init__1   s+    
kkmr   evtc                 :    | j                   j                  |       y rI   )rE   put)rL   rN   s     r   
push_eventz_Session.push_event7   s    r   N)	__name__
__module____qualname__	__slots__strlistrM   dictrQ    r   r   rC   rC   /   s1    CIs 3 S	 d r   rC   	_sessionsrD   r3   rG   c                 j    t        j                         j                  }t        | ||      t        |<   |S rI   )uuiduuid4hexrC   rZ   )rD   r3   rG   sids       r   _new_sessionr`   <   s*    
**,

CfeV4IcNJr   z/service/descriptionc                  0   t        j                  d      xs i } | j                  d      xs dj                         | j                  d      xs dj                         | j                  d      xs dj                         dj	                         D cg c]
  \  }}|r	| }}}|rt        dd	d
|i      S | j                  d      xs dj                         }| j                  d      xs dj                         }| j                  d      }t        |t              r,dj                  |D cg c]  }|st        |       c}      }n|xs dj                         }g }|r|j                  d| d       |r|j                  d| d       |r|j                  d|        dj                  |      }d d d d d d| dj                         }	t        dddd|	dgdt        | j                  dd             t        | j                  d!d"            t        | j                  d#d$            t        | j                  d%d$            d&d'}
fd(}d)t        fd*}d+t        fd,}	 t        d-|
      }|d.   d/   d0   d)   j                         }	  ||      }t        |t              re ||j                  d1d            } ||j                  d2d            } ||j                  d3d            }t        |||g      rt!        |||d4      S t!         |             S c c}}w c c}w # t"        j$                  t&        t(        f$ r t!         |             cY S w xY w# t*        j,                  $ r t!         |             cY S w xY w)5NTsilentnomer   localtipo)rd   re   rf   u;   parâmetros obrigatórios ausentes no corpo da requisiçãoi  missing_fields)statusdetailstompublicokeywords, zTom desejado: ""u   Público-alvo: "zPalavras-chave: 
u  
Você é um redator turístico sênior.
Crie DESCRIÇÕES CURTAS e CRIATIVAS para o serviço abaixo, em três idiomas.

FORMATO DE SAÍDA (obrigatório):
Retorne APENAS um JSON plano, em UMA LINHA, com as chaves "pt", "en" e "es".
Cada valor DEVE ser UMA ÚNICA STRING (sem objetos, sem arrays, sem quebras de linha, sem chaves "{}").
Exemplo:
{"pt":"Frase completa PT.","en":"Full sentence EN.","es":"Frase completa ES."}

CONTEÚDO:
- Máx. 500 caracteres por idioma.
- Combine: 1) gancho sensorial curto; 2) diferencial específico do  em u}   ; 3) chamada para ação direta.
- Verbo ativo, substantivos concretos. Evite clichês.
- Sem emojis/hashtags.

DADOS:
Nome: z
Local: z
Tipo: systemu   Você é um redator turístico sênior. Sempre retorne JSON válido, plano, em uma linha, com valores de string. Nunca retorne objetos/arrays por idioma.rolecontentuseri  temperaturegffffff?top_pg?presence_penaltyg?frequency_penaltyF)r3   messages
max_tokensrv   rw   rx   ry   streamc                  ~     d  dj                          d d  d d d  dj                          dd	S )
Nrp   . u8    com proposta única no destino. Garanta sua vaga agora.z in z. A z# with a clear local edge. Book now.z en z' con un diferencial local. Reserva hoy.ptenes)
capitalize)local_rd   rf   s   r   _defaultz%service_description.<locals>._default   sb    F$vhb):(;;stF$vhd4&0STF$vhb):(;;bc
 	
r   rt   c                     | xs dj                         }|j                  d      rB|j                  d      r|dd  }n|dd  }|j                  d      r|d d }|j                         }t        j                  |      S )Nr   z```z```json      )r   
startswithendswithr1   loads)rt   txts     r   _parse_json_textz-service_description.<locals>._parse_json_text   sr    }"##%>>% ~~i(!"g!"g||E"#2h))+Czz#r   r   c                    t        | t              red}|D cg c]  }|| v s| |   st        | |          }}|s)| j                         D cg c]  }|st        |       }}dj	                  |      }n8t        | t
              rdj	                  d | D              }nt        | xs d      }|j                  dd      j                  dd      }dj	                  |j                               d d }|S c c}w c c}w )	N)ganchohookdiferencialuniquectachamadacall_to_actionr~   c              3   8   K   | ]  }|st        |        y wrI   )rV   )r   xs     r   r   z>service_description.<locals>._flatten_value.<locals>.<genexpr>   s     1Qq#a&1s   r   {} i  )
isinstancerX   rV   valuesr   rW   replacesplit)v	keys_prefkpartsr   ss         r   _flatten_valuez+service_description.<locals>._flatten_value   s    aaI(1E1Q!V!S1YEEE)*9AqQ99		% A4 		1!11AAGAIIc2&&sB/HHQWWY% F9s   	C4C4C4C9C9/chat/completionschoicesr   messager   r   r   r   )r   get_jsonr<   r   itemsr   r   rW   r   rV   appendDEFAULT_MODELfloatr>   rX   anyr
   r1   JSONDecodeError	TypeError
ValueErrorr5   RequestException)bodyr   r   missingrj   rk   rl   extras
extras_txtrD   r-   r   r   r   datart   parsedr   r   r   r   rd   rf   s                       @@@r   service_descriptionr   A   s   4(.BDHHV"))+Dhhw%2,,.FHHV"))+D&*VTJPPR\TQZ[q\G\QZ]hx  {B  hC  D  	D88E? b
'
'
)Cxx	"(b//1Gxx
#H(D!99h<!c!f<=N))+F
FMMOC523 0	;<!1(<=6"JE FJF$vh W
 f x f  )* 
EG+ 0  ! w /
 TXXmT:;txx-.!$((+=s"CD"488,?#EFG"

# 
S -w7y/!$Y/	:@@B
	"%g.F&$'#FJJtR$89#FJJtR$89#FJJtR$89B|$Rr<==hj>!O ] =@ $$i< 	"hj>!	"$$ (*~sO   
L0)L08L6 L6:(M/ #A<L;  L; ;.M,)M/ +M,,M/ /#NNz/chatc                     t        j                  d      xs i } | j                  d      }|sddidfS | j                  dt              d|d	g| j                  d
d      dd}	 t	        t        d|            S # t        j                  $ r9}d|j                  j                  d|j                  j                  fcY d }~S d }~wt        j                  $ r}dt        |      ddfcY d }~S d }~ww xY w)NTrb   rD   error   campo 'prompt' é obrigatório  r3   ru   rr   r{   i   F)r3   rz   r{   r|   r   z falha ao contatar modelo de chatr   detailfalha de rede  )r   r   r<   r   r   r>   r5   r9   responser   r:   r   rV   )r   rD   r-   errs       r   chat_completionr      s    4(.BDXXhF9:C??'=1$89hh|S1	GCz"5w?@@ t;s||GXGXY[^[g[g[s[sss$$ C(CH=sBBCs0   $A9 9C0.C :C0 C0C+%C0+C0z/imagec                     t        j                  d      xs i } | j                  d      }|sddidfS | j                  dg       }t        |t              sddidfS d	j                  |      }|r| d
| n|}| j                  dt              }||dd}	 t        d|d      }|d   d   d   }t        |||      }	t        |	   }
||
_
        |
j                  d|d       d}|	|| d|	 d| d|	 d| d|	 ddS # t        j                  $ r9}d|j                  j                  d|j                  j                   fcY d }~S d }~wt        j"                  $ r}dt%        |      ddfcY d }~S d }~ww xY w)NTrb   rD   r   r   r   rG   zcampo 'fields' deve ser listarm   u   . Campos do formulário: r3   r3   rD   convert_base64_to_url/images/generationsx   r.   r   r   r?   imagetyper   z/api/sessionsr%   z/eventsz/commandz/html)
session_idinitial_image
events_urlcommand_urlhtml_urlfalha ao gerar imagemr   r   r   )r   r   r<   r   rW   r   IMAGE_MODELr>   r`   rZ   rF   rQ   r5   r9   r   r   r:   r   rV   )r   rD   rG   
fields_strfull_promptr3   r-   r   	first_urlr_   sess	base_pathr   s                r   image_generationr      s   4(.BDXXhF9:C??XXh#Ffd#893>>6"JFLVH5j\BRXKHHWk*EtTGC/#FLOE*	;v6~!$78#	!&KqW5'[#h7$+Qse51
 	
  i0CLL<M<MNPSP\P\PhPhhh$$ C(CH=sBBCs1   A%C; ;E2.E<E2E2E-'E2-E2r   c              #   x   K   	 dt        j                  | j                  j                               z   dz    6w)Nzdata: z

)r1   dumpsrE   r<   )r   s    r   _event_streamr      s2     
DKKOO$566?? s   8:z/sessions/<sid>/eventsr_   c                 h    t         j                  |       }|sddidfS t        t        |      d      S )Nr      sessão não encontrada  ztext/event-streammimetype)rZ   r<   r   r   )r_   r   s     r   listen_eventsr      s7    ==D23S88M$'2EFFr   z/sessions/<sid>/commandc                 r   t         j                  |       }|sddidfS t        j                  d      xs i }|j                  d      }|sddidfS 	 |d	k(  rb|j                  |j                  d
|j
                        dd}t        d|d      }|d   d   d   |_        |j                  d|d       ddidfS ddidfS # t        j                  $ r9}d|j                  j                  d|j                  j                  fcY d }~S d }~wt        j                  $ r}dt        |      ddfcY d }~S d }~ww xY w)Nr   r   r   Trb   commandu   campo 'command' é obrigatórior   
regeneraterD   r   r   r   r   r   r   r?   r   r   rh   	generated   u   comando inválidor   r   r   r   )rZ   r<   r   r   r3   rD   r>   rF   rQ   r5   r9   r   r   r:   r   rV   )r_   r   r   cmdr-   r   r   s          r   handle_commandr      sF   ==D23S884(.BD
((9
C:;S@@C,((8T[[9)-G
 3WcJD LOE2DMOOWd;<k*C//,-s22 i0CLL<M<MNPSP\P\PhPhhh$$ C(CH=sBBCs7   A&B? 9B? ?D6.D D6D6D1+D61D6z/sessions/<sid>/htmlc                     t         j                  |       }|sddidfS t        |j                        }dj	                  d |j                  D              }d| d| d}t        |d	
      S )Nr   r   r   r   c              3   @   K   | ]  }d | d| d| d| d| d  yw)z<div class="field"><label for="z">z</label><input id="z" name="z" placeholder="z"></div>NrY   )r   fs     r   r   zhtml_snippet.<locals>.<genexpr>  sA        *!Bqc 2S?1#X	?s   uY   <!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="utf-8">
<title>Formulário – af   campos</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;600&display=swap" rel="stylesheet">
<style>
:root{--primary:#20b2ff;--primary-light:#eaf7ff;--bg:#f5f9ff;--text:#1f2937}
*{box-sizing:border-box;margin:0;padding:0;font-family:'Poppins',sans-serif}
body{background:var(--bg);display:flex;justify-content:center;align-items:flex-start;padding:2rem}
.card{background:#fff;width:100%;max-width:600px;border-radius:16px;box-shadow:0 6px 24px rgba(0,0,0,.08);padding:2rem}
h1{color:var(--text);font-size:1.5rem;font-weight:600;margin-bottom:1.5rem;text-align:center}
form{display:grid;gap:1rem}
.field{display:flex;flex-direction:column}
label{margin-bottom:.25rem;color:var(--text);font-size:.9rem;font-weight:600}
input{padding:.75rem 1rem;border:2px solid var(--primary-light);border-radius:8px;font-size:1rem}
input:focus{outline:none;border-color:var(--primary)}
button{margin-top:1.25rem;padding:.9rem 1rem;background:var(--primary);color:#fff;font-size:1rem;border:none;border-radius:8px;cursor:pointer;transition:background .2s}
button:hover{background:#1198e6}
</style>
</head>
<body>
<div class="card">
<h1>Reserve sua viagem perfeita</h1>
<form>zC<button type="submit">Enviar</button></form>
</div>
</body>
</html>z	text/htmlr   )rZ   r<   lenrG   r   r   )r_   r   countinputs_htmlhtmls        r   html_snippetr     s    ==D23S88E''   K
 w , m 5D< D;//r   )<   )*r   rJ   r\   r1   r5   flaskr   r   r   r   appr   r   utils.responser
   r   rV   r   r"   r*   r4   r   r=   r   r7   rX   intr>   rC   rZ   __annotations__rW   r`   r6   r   r   r   r   r<   r   r   r   rY   r   r   <module>r      s   & & & @ @  %<# <# <c s  O	=' |~./&
S 4 # 	 	 "$	4X # S $s)  
 #$q %qf WC C$ XC C@@ @ $%Gs G &G &'C C (C2 "#(0c (0 $(0r   