
    i,                         d Z ddlmZ ddlmZmZmZmZmZm	Z	m
Z
mZ ddlZddlZddlmZ ddlmZ ddlmZmZ ddlmZ dd	lmZmZ d
dlmZ ddlmZ  G d dee      Z G d de      Z  G d de      Z!y)z
Support for OpenAI's `/v1/chat/completions` endpoint.

Calls done in OpenAI/openai.py as OpenRouter is openai-compatible.

Docs: https://openrouter.ai/docs/parameters
    )Enum)AnyAsyncIteratorIteratorListOptionalTupleUnioncastN)BaseModelResponseIterator)BaseLLMException)AllMessageValuesChatCompletionToolParam)OpenRouterErrorMessage)ModelResponseModelResponseStream   )OpenAIGPTConfig   OpenRouterExceptionc                   $    e Zd ZdZdZdZdZdZdZy)CacheControlSupportedModelsz4Models that support cache_control in content blocks.claudegeminiminimaxglmzz-aiN)	__name__
__module____qualname____doc__CLAUDEGEMINIMINIMAXGLMZAI     |/Users/manta/Documents/Projects/TheRoad-I1/.venv/lib/python3.12/site-packages/litellm/llms/openrouter/chat/transformation.pyr   r      s    >FFG
C
Cr(   r   c                       e Zd Zdedef fdZdededededef
 fdZdedefdZ		 dded	e
e   d
ee
d      dee
e   ee
d      f   f fdZd	e
e   de
e   fdZded	e
e   dedededef fdZ	 	 d dedej$                  dededed	e
e   dedededee   dee   def fdZdededeeej0                  f   defdZ	 d!deee   ee   ef   dedee   defdZ xZS )"OpenrouterConfigmodelreturnc                    t         |   |      }	 t        j                  |d      st        j                  |      r"|j	                  d       |j	                  d       t        t        j                  |            S # t
        $ r Y )w xY w)zU
        Allow reasoning parameters for models flagged as reasoning-capable.
        )r,   
openrouter)r,   custom_llm_providerreasoning_effortthinking)	superget_supported_openai_paramslitellmsupports_reasoningappend	Exceptionlistdictfromkeys)selfr,   supported_params	__class__s      r)   r4   z,OpenrouterConfig.get_supported_openai_params$   s     !7>U>K	))++%8 ''(:; ''
3 DMM"2344  		s   AB   	BBnon_default_paramsoptional_paramsdrop_paramsc                     t         
|   ||||      }i }|j                  dd       }|j                  dd       }|j                  dd       }	|||d<   |||d<   |	|	|d<   ||d<   |S )N
transformsmodelsroute
extra_body)r3   map_openai_paramspop)r<   r?   r@   r,   rA   mapped_openai_paramsrF   rC   rD   rE   r>   s             r)   rG   z"OpenrouterConfig.map_openai_params3   s      %w8 

 
'++L$?
#''$7"&&w5!'1J|$#)Jx "'Jw  		
 $#r(   c                 T    |j                         t        fdt        D              S )z
        Check if the model supports cache_control in content blocks.

        Returns:
            bool: True if model supports cache_control (Claude or Gemini models)
        c              3   :   K   | ]  }|j                   v   y wN)value).0supported_modelmodel_lowers     r)   	<genexpr>zFOpenrouterConfig._supports_cache_control_in_content.<locals>.<genexpr>V   s$      
#> !![0#>s   )loweranyr   )r<   r,   rP   s     @r)   "_supports_cache_control_in_contentz3OpenrouterConfig._supports_cache_control_in_contentN   s*     kkm 
#>
 
 	
r(   messagestoolsr   c                 P    | j                  |      r||fS t        | 	  |||      S rL   )rT   r3   1remove_cache_control_flag_from_messages_and_tools)r<   r,   rU   rV   r>   s       r)   rX   zBOpenrouterConfig.remove_cache_control_flag_from_messages_and_tools[   s6     2259U?"7Lx r(   c                    g }|D ]  }t        |      }|j                  dd      }||j                  d      }t        |t              r[t        |      dkD  rWg }t        |      D ]7  \  }}	t        |	      }
|t        |      dz
  k(  r||
d<   |j                  |
       9 ||d<   n
d||dg|d<   |j                  t        t        |              |S )a<  
        Move cache_control from message level to content blocks.
        OpenRouter requires cache_control to be inside content blocks, not at message level.

        To avoid exceeding Anthropic's limit of 4 cache breakpoints, cache_control is only
        added to the LAST content block in each message.
        cache_controlNcontentr      text)typer]   rZ   )
r:   rH   get
isinstancer9   len	enumerater7   r   r   )r<   rU   transformed_messagesmessagemessage_dictrZ   r[   content_copyiblock
block_dicts              r)   _move_cache_control_to_contentz/OpenrouterConfig._move_cache_control_to_contenth   s     8:G=L(,,_dCM(&**95gt,7|a'')(1'(:HAu)-eJ CL1$44>K
? ;(//
; ); 3?Y/
 %+$+-:/L+ !''-=|(LM;  > $#r(   litellm_paramsheadersc                     | j                  |      r| j                  |      }|j                  di       }t        |   |||||      }|j                  |       d|vrddi|d<   |S )z
        Transform the overall request to be sent to the API.

        Returns:
            dict: The transformed request. Sent as the body of the API call.
        rF   usageincludeT)rT   rj   rH   r3   transform_requestupdate)	r<   r,   rU   r@   rk   rl   rF   responser>   s	           r)   rp   z"OpenrouterConfig.transform_request   s{     2259::8DH$((r:
7,8_ng
 	
# ("!*D 1HWr(   raw_responsemodel_responselogging_objrequest_dataencodingapi_key	json_modec                 R   t         |   |||||||||	|
|      }	 |j                         }d|v rf|d   ra|d   j                  d      }|Kt	        |d      si |_        d|j
                  vri |j
                  d<   t        |      |j
                  d   d<   |S # t        $ r Y |S w xY w)z
        Transform the response from OpenRouter API.

        Extracts cost information from response headers if available.

        Returns:
            ModelResponse: The transformed response with cost information.
        )r,   rs   rt   ru   rv   rU   r@   rk   rw   rx   ry   rn   cost_hidden_paramsadditional_headersz$llm_provider-x-litellm-response-cost)r3   transform_responsejsonr_   hasattrr|   floatr8   )r<   r,   rs   rt   ru   rv   rU   r@   rk   rw   rx   ry   response_jsonresponse_costr>   s                 r)   r~   z#OpenrouterConfig.transform_response   s    . 3%)#%+) 4 
 	(--/M-'M',B -g 6 : :6 B ,">3CD8:5+>3P3PPNP556JK m, #112FG> 	  			s   A:B 	B&%B&error_messagestatus_codec                     t        |||      S )Nrd   r   rl   r   )r<   r   r   rl   s       r)   get_error_classz OpenrouterConfig.get_error_class   s     #!#
 	
r(   streaming_responsesync_streamc                     t        |||      S )N)r   r   ry   )(OpenRouterChatCompletionStreamingHandler)r<   r   r   ry   s       r)   get_model_response_iteratorz,OpenrouterConfig.get_model_response_iterator   s     81#
 	
r(   rL   )NN)F)r   r   r    strr9   r4   r:   boolrG   rT   r   r   r   r	   rX   rj   rp   httpxResponser   r   r~   intr
   Headersr   r   r   r   r   __classcell__)r>   s   @r)   r+   r+   #   s5   5 5 5$ $ $ 	$
 $ 
$6
 
 
" <@	 '( 678	
 
t$%x5N0O'PP	Q*$-.*$		*$X '( 	
   
R "&$(88 nn8 &	8
 8 8 '(8 8 8 8 #8 D>8 
8t
 
/2
=B4CV=W
	
 %*	

!(3-s1C]"RS

 

 D>	


 


r(   r+   c                       e Zd ZdedefdZy)r   chunkr-   c           
      8   	 d|v r|d   }t        dj                  |d   |j                  di       |j                  dd            |d   |j                  di             }t        |d   |d   |d   j                  d	i       
      g }|d   D ]-  }|d   j                  d      |d   d<   |j	                  |       / t        |d   d|d   |j                  d      |d   |      S # t        $ r}t        d| d| dddi
      d }~wt        $ r}|d }~ww xY w)Nerrorz&Message: {}, Metadata: {}, User ID: {}rd   metadatauser_id code)rd   r   r   rl   r   choicesdelta	reasoningreasoning_contentidzchat.completion.chunkcreatedrn   r,   )r   objectr   rn   r,   r   z
KeyError: z+, Got unexpected response from OpenRouter: i  zContent-Typezapplication/json)r   formatr_   r   r7   r   KeyErrorr8   )r<   r   error_chunkr   new_choiceschoicees          r)   chunk_parserz5OpenRouterChatCompletionStreamingHandler.chunk_parser  sg   &	%#Gn 6DKK#I.#
B7#	26
 %V,(__Z<! *))4 -f 5)*599)RH  K	*7=g7J7J;7Ww 34""6* + ';.i(ii(Gn#   	%$QC'RSXRYZ');< 
  	G	s$   C$C' '	D0DDDDN)r   r   r    r:   r   r   r'   r(   r)   r   r     s    '$ '+> 'r(   r   )"r!   enumr   typingr   r   r   r   r   r	   r
   r   r   r5   )litellm.llms.base_llm.base_model_iteratorr   )litellm.llms.base_llm.chat.transformationr   litellm.types.llms.openair   r   litellm.types.llms.openrouterr   litellm.types.utilsr   r   openai.chat.gpt_transformationr   common_utilsr   r   r   r+   r   r'   r(   r)   <module>r      s]     S S S   O F O @ B = .#t \
 \
~(/H (r(   