o
    iN                  
   @   sd   d dl Z d dlZd dlZdededededef
ddZd	d
 Zdd ZdedededefddZdS )    Nmodelprompt
file_bytesfilenamemimetypec                 C   s  zXt d}t|drt|j| ||||dW S dD ]}t||r2t||}t|| ||||  W S qt|drW| }dD ]}	t||	rVt||	}t|| ||||  W S q>W n, tya   Y n$ t	y }
 zzt
| |||W W  Y d}
~
S  t	y   |
w d}
~
ww t
| |||S )z
    Intenta usar el cliente compartido (shared.openai_manager) con distintas firmas.
    Si no encuentra una compatible, hace fallback a un llamado directo a OpenAI pidiendo JSON.
    Devuelve: dict (JSON)
    zshared.openai_managerrun_vision_jsonr   r   r   r   r   )vision_json
run_visioncall_vision_jsonrun_vision_bytesOpenAIManager)r   r	   r
   r   N)	importlibimport_modulehasattr_to_dictr   getattr_try_variantsr   ModuleNotFoundError	Exception_fallback_openai_call)r   r   r   r   r   mgrfnamefninstmethe r   B/var/www/html/flask_server/apps/wp_invoices/services/llm_client.pyr	      sD   


	




r	   c                 C   s   t | tr
t| S | S )N)
isinstancestrjsonloads)resultr   r   r   r   6   s   

r   c                 C   s   zt | |||||dW S  ty   Y nw zt | ||||dW S  ty*   Y nw z	t | |||W S  ty=   Y nw zt | ||W S  tyR   Y tdw )zP
    Intenta llamar a fn con distintas combinaciones de argumentos comunes.
    r   )r   r   r   r   u:   Ninguna firma conocida coincidió en shared.openai_manager)r   	TypeErrorRuntimeError)r   r   r   r   r   r   r   r   r   r   <   s*   r   c              
   C   sp  z
ddl m}m} W n ty } ztd|d}~ww ddl}ddl}| }	||d}
d| d|
 }d|d	d
d|idg}z%|	j	j
j| d|dgddid}|jd jj}t|trf||W S |W S  |yq   Y n	 tyy   Y nw dd| d	d
d|idg}|	j	j
j| d|dgd}|jd jj}zt|tr||W S |W S  ty   d|i Y S w )u   
    Fallback directo usando chat.completions:
    - Sin temperature
    - Primero intenta response_format={"type":"json_object"}
    - Si falla, reintenta sin response_format forzando JSON vía prompt
    r   )OpenAIBadRequestErrorun   openai SDK no disponible y no se encontró un manager compatible. Instala openai o implementa run_vision_json.Nzutf-8zdata:z;base64,text)typer(   	image_urlurl)r)   r*   user)rolecontentr)   json_object)r   messagesresponse_formatuF   Responde SOLO con un JSON válido. No agregues texto fuera del JSON.

)r   r0   _raw)openair&   r'   r   ImportErrorbase64r!   	b64encodedecodechatcompletionscreatechoicesmessager.   r   r    r"   )r   r   r   r   r&   r'   r   r5   r!   clientb64data_urlr.   respr(   
content_fbr   r   r   r   \   sV   

r   )	r5   r!   r   r    bytesr	   r   r   r   r   r   r   r   <module>   s   0 