o
    6i#                     @  s   d Z ddlmZ ddlZddlZddlZddlZddlmZm	Z	 ddl
Z
ddlmZmZmZmZmZ ddlmZmZ d	Zdd
lmZmZmZ eeZdZG dd deZdS )z
OpenRouter provider (SECONDARY): httpx async client, same interface as AI Studio,
cache verification via prompt_tokens_details.cached_tokens.
    )annotationsN)AnyOptional   )BaseProviderTranscriptionRequestTranscriptionResponse
TokenUsageRequestStatus   )TEMPERATUREMAX_RETRIES_429zgoogle/gemini-3-flash-preview)get_cacheable_system_promptbuild_user_promptget_json_schemaz-https://openrouter.ai/api/v1/chat/completionsc                   @  s^   e Zd Zd&d'ddZd(d	d
Zd)ddZd*ddZd+ddZd,ddZd-d!d"Z	d.d#d$Z
d%S )/OpenRouterProviderFapi_keystr	mock_modeboolc                 C  s   || _ || _t | _d S )N)r   r   r   _schema)selfr   r    r   4/home/ubuntu/transcripts/src/providers/openrouter.py__init__   s   zOpenRouterProvider.__init__returnc                 C  s   dS )N
openrouterr   r   r   r   r   get_provider_name$   s   z$OpenRouterProvider.get_provider_namerequestslist[TranscriptionRequest]list[TranscriptionResponse]c              	     s   j rfdd|D S tt|tjddddd}tjt|dd}tj||d	4 I d H   fd
d|D }tj| I d H W  d   I d H  S 1 I d H sUw   Y  d S )Nc                   s   g | ]}  |qS r   )_mock_response.0reqr   r   r   
<listcomp>)   s    z1OpenRouterProvider.send_batch.<locals>.<listcomp>g      $@g      4@g      >@)connectreadwritepoold   )max_connectionsmax_keepalive_connections)timeoutlimitsc                   s   g | ]	} | qS r   )_send_singler#   clientr   	semaphorer   r   r&   /   s    )	r   asyncio	SemaphorelenhttpxTimeoutLimitsAsyncClientgather)r   r   r.   r/   tasksr   r1   r   
send_batch'   s   0zOpenRouterProvider.send_batchr%   r   r2   httpx.AsyncClientr3   asyncio.Semaphorer   c                   s  |4 I d H k t td D ]X}zt }| ||I d H }t | d }|jdkri|tk rSdd|  }td|j d|d  d| d	 t	
|I d H  W qt|jtjd
dW   W  d   I d H  S |jdkr|jd d }	t|jtjd|j d|	 |dW   W  d   I d H  S | }
|
di gd di dd}z|rt|ni }W n tjy   d|i}Y nw | |
}t|jtj||||
dW   W  d   I d H  S  tjy3 } zF|dk rtd|j d|d   W Y d }~qtd|j d t|jtjd|d  d| dW  Y d }~  W  d   I d H  S d }~w tyh } z)td|j d|  t|jtjt|dW  Y d }~  W  d   I d H  S d }~ww W d   I d H  n1 I d H szw   Y  t|jtjddS )Nr   i  i  
   r   z429 on z, retry z in sz429 rate limited after retries)
segment_idstatuserror_message   i  zHTTP z: )rB   rC   rD   
latency_mschoicesr   messagecontent raw_text)rB   rC   transcription_datatoken_usagerF   raw_responsezTimeout on zDiscarding z+: timed out twice (bad sample / model hang)zDiscarded: timed out after z attempts: zOpenRouter error for zExhausted retries)ranger   time	monotonic	_call_apistatus_codeloggerwarningrB   r4   sleepr   r
   RATE_LIMITEDtextERRORjsongetloadsJSONDecodeErrorget_token_usageSUCCESSr7   TimeoutExceptionerrorTIMEOUT	Exceptionr   )r   r%   r2   r3   attemptstartresplatencywait
error_bodydatarI   parsedrM   er   r   r   r0   2   s   
$


"

.
99*AzOpenRouterProvider._send_singlehttpx.Responsec                   s   t  }t|j}tdd|ddidgddd|jd	d
dd|dgdgtddd| jddd}|jtd| j	 dd|dI d H S )NsystemrX   type	ephemeral)ro   rX   cache_control)rolerI   userinput_audioflac)rj   format)ro   rt   )ro   rX   json_schematranscription_outputT)namestrictschema)ro   rw   )modelmessagestemperatureresponse_formatzBearer zapplication/json)AuthorizationzContent-Type)headersrZ   )
r   r   language_codeOPENROUTER_MODELaudio_base64r   r   postOPENROUTER_API_URLr   )r   r%   r2   system_promptuser_promptpayloadr   r   r   rR   |   sH   
&
zOpenRouterProvider._call_apiresponser   c                 C  sD   z| di }| di }| dd}|dkW S  ty!   Y dS w )Nusageprompt_tokens_detailscached_tokensr   F)r[   rc   )r   r   r   detailscachedr   r   r   verify_cache_hit   s   
z#OpenRouterProvider.verify_cache_hitr	   c                 C  sr   z,| di }| dd}| dd}| di }| dd}t||||| |dkdW S  ty8   t  Y S w )Nr   prompt_tokensr   completion_tokensr   r   input_tokensoutput_tokensr   total_tokens	cache_hit)r[   r	   rc   )r   r   r   input_toutput_tr   r   r   r   r   r^      s    
z"OpenRouterProvider.get_token_usagec                 C  sN   d|j  d|j  ddddd|jd}t|jtj|td	d
ddddddS )Nz[MOCK-OR] Transcription for z$[MOCK-OR] [laugh] Transcription for happyconversationalnormalrJ   )emotionspeaking_stylepaceaccent)transcriptiontaggedspeakerdetected_languagei,        i  Tr   g     @P@)rB   rC   rL   rM   rF   )original_filer   r   rB   r
   r_   r	   )r   r%   	mock_datar   r   r   r"      s&   

z!OpenRouterProvider._mock_responseN)F)r   r   r   r   )r   r   )r   r    r   r!   )r%   r   r2   r>   r3   r?   r   r   )r%   r   r2   r>   r   rm   )r   r   r   r   )r   r   r   r	   )r%   r   r   r   )__name__
__module____qualname__r   r   r=   r0   rR   r   r^   r"   r   r   r   r   r      s    



J
9
	r   )__doc__
__future__r   r4   rZ   loggingrP   typingr   r   r7   baser   r   r   r	   r
   configr   r   r   prompt_builderr   r   r   	getLoggerr   rT   r   r   r   r   r   r   <module>   s    
