
    i(                        U 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mZm	Z	m
Z
mZmZmZmZmZ d dlmZ d dlZd dlZd dlmZ d dlmZmZ d dlmZmZmZmZm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)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6 d d
l7m8Z8 d dl9m:Z:m;Z;m<Z<m=Z=m>Z> d dl?m@Z@mAZAmBZB er	d dlCmDZE eEZFneZF G d de      ZGe G d d             ZHdeIdeJfdZKd ZLdeJfdZMdeJfdZNdeJde6fdZOdZP G d de      ZQdd d!d"d#ZRe
eJe0f   eSd$<   d%eJd&eeJeTf   de/fd'ZUd%eJd(eTde/fd)ZVd%eJd*eJd&eJde/fd+ZWd,ee8   dee/   fd-ZXd.ee
   d/e6fd0ZYd.ee4   dee@   fd1ZZ G d2 d3eA      Z[y)4    N)	dataclass)	TYPE_CHECKINGAnyAsyncIteratorDictListOptionalProtocolTupleUnion)urlparse)track_llm_api_timing)
BaseConfigBaseLLMException)AsyncHTTPHandlerHTTPHandler_get_httpx_clientget_async_httpx_clientversionOCIError)CohereChatRequestCohereMessageCohereChatResultCohereParameterDefinitionCohereStreamChunk
CohereToolCohereToolCallOCIChatRequestPayloadOCICompletionPayloadOCICompletionResponseOCIContentPartUnionOCIImageContentPartOCIImageUrl
OCIMessageOCIRolesOCIServingModeOCIStreamChunkOCITextContentPartOCIToolCallOCIToolDefinition
OCIVendors)AllMessageValues)DeltaLlmProvidersModelResponseModelResponseStreamStreamingChoices)ChatCompletionMessageToolCallCustomStreamWrapperUsage)Loggingc                   *    e Zd ZdZdddededdfdZy)	OCISignerProtocola  
    Protocol for OCI request signers (e.g., oci.signer.Signer).

    This protocol defines the interface expected for OCI SDK signer objects.
    Compatible with the OCI Python SDK's Signer class.

    See: https://docs.oracle.com/en-us/iaas/tools/python/latest/api/signing.html
    Fenforce_content_headersrequestr:   returnNc                     y)a  
        Sign an HTTP request by adding authentication headers.

        Args:
            request: Request object with method, url, headers, body, and path_url attributes
            enforce_content_headers: Whether to enforce content-type and content-length headers
        N )selfr;   r:   s      u/Users/manta/Documents/Projects/TheRoad-I1/.venv/lib/python3.12/site-packages/litellm/llms/oci/chat/transformation.pydo_request_signz!OCISignerProtocol.do_request_signW   s     	    )__name__
__module____qualname____doc__r   boolrA   r>   rB   r@   r8   r8   M   s+     @E

8<
	
rB   r8   c                   P    e Zd ZU dZeed<   eed<   eed<   eed<   edefd       Z	y)	OCIRequestWrapperz
    Wrapper for HTTP requests compatible with OCI signer interface.

    This class wraps request data in a format compatible with OCI SDK signers,
    which expect objects with method, url, headers, body, and path_url attributes.
    methodurlheadersbodyr<   c                     t        | j                        }|j                  |j                  rd|j                  z   z   S dz   S )z0Returns the path + query string for OCI signing.? )r   rK   pathquery)r?   
parsed_urls     r@   path_urlzOCIRequestWrapper.path_urlr   s=     dhh'
J<L<L#
(8(8"8UURTUUrB   N)
rC   rD   rE   rF   str__annotations__dictbytespropertyrT   r>   rB   r@   rI   rI   d   s9     K	HM
KV# V VrB   rI   datar<   c                     t        j                  |       j                         }t        j                  |      j                         S N)hashlibsha256digestbase64	b64encodedecode)rZ   r_   s     r@   sha256_base64rc   y   s3    ^^D!((*FF#**,,rB   c                     g }|D ]8  }|dk(  r| j                          d| }n||   }|j                  | d|        : dj                  |      S )N(request-target) z: 
)lowerappendjoin)rJ   rQ   rL   signed_headerslinesheadervalues          r@   build_signature_stringro   ~   sb    E ''||~&av.EFOExr%)* ! 99UrB   key_strc                     	 ddl m} ddlm} |j                  | j                  d      d       }t        ||j                        st        d      |S # t        $ r}t	        d      |d }~ww xY w)Nr   )serialization)rsaicryptography package is required for OCI authentication. Please install it with: pip install cryptographyutf-8)passwordzNThe provided private key is not an RSA key, which is required for OCI signing.)
cryptography.hazmat.primitivesrr   )cryptography.hazmat.primitives.asymmetricrs   ImportErrorload_pem_private_keyencode
isinstanceRSAPrivateKey	TypeError)rp   rr   rs   ekeys        r@   load_private_key_from_strr      s    @A 
,
,w - C c3,,-\
 	
 J  ?
 	s   A 	A-A((A-	file_pathc                 .   	 t        | dd      5 }|j                         j                         }ddd       st        d|        t        |      S # 1 sw Y   $xY w# t        $ r t        d|        t        $ r}t	        d|  d|       |d}~ww xY w)	z$Loads a private key from a file pathrru   )encodingNzPrivate key file not found: z!Failed to read private key file 'z': zPrivate key file is empty: )openreadstripFileNotFoundErrorOSError
ValueErrorr   )r   frp   r   s       r@   load_private_key_from_filer      s    T)S73qffhnn&G 4 6ykBCC$W-- 43 L">yk JKK T9)CsKLRSSTs-   A AA AA B=BBmodelc                     | j                  d      d   j                         }|dk(  rt        j                  S t        j                  S )z
    Extracts the vendor from the model name.
    Args:
        model (str): The model name.
    Returns:
        str: The vendor name.
    .r   cohere)splitrh   r,   COHEREGENERIC)r   vendors     r@   get_vendor_from_modelr      s@     [[a &&(F   !!!rB   i,  c                      e Zd ZdZ	 	 d4dZdedee   fdZdededed	e	def
d
Z
dededededeeef   f
dZdededededeedf   f
dZ	 	 	 	 d5dededededee   dee   dee	   dee	   deeee   f   fdZ	 	 d6dededee   dededee   dee   defdZ	 d7dee   dee   dedededee	   defdZdededefdZdee   dee   fdZdeeeef      dee   fdZdedefdZdedee   dedededefdZd eded!edefd"Zd#eded!ed$e jB                  def
d%Z"	 	 d6ded$e jB                  d!ed&e#dedee   deded'edee   d(ee	   defd)Z$ e%       	 	 	 d8ded*ed&e#deded+ede&d,ee'e(e)f      d(ee	   d-ee   dd.fd/       Z* e%       	 	 	 d8ded*ed&e#deded+ede&d,ee'e(e)f      d(ee	   d-ee   dd.fd0       Z+d1ed2e,de'ee jZ                  f   de.fd3Z/y)9OCIChatConfigz6
    Configuration class for OCI's API interface.
    r<   Nc                    t               j                         }|j                         D ]%  \  }}|dk7  s|t        | j                  ||       ' t        | j                  dd       i ddddddd	d	d
d
dddddddddddddddddddddddddddddddddd 	| _        | j
                  j                         | _        y )!Nr?   has_custom_stream_wrapperTstreamisStream
max_tokens	maxTokensmax_completion_tokenstemperaturetoolsfrequency_penaltyfrequencyPenaltylogprobslogProbs
logit_bias	logitBiasnnumGenerationspresence_penaltypresencePenaltyseedstoptool_choice
toolChoicetop_ptopPmax_retriesFtop_logprobs
modalitiesresponseFormat)	
predictionstream_optionsfunction_call	functionsextra_headersparallel_tool_callsaudioweb_search_optionsresponse_format)localscopyitemssetattr	__class__openai_to_oci_generic_param_mapopenai_to_oci_cohere_param_map)r?   locals_r   rn   s       r@   __init__zOCIChatConfig.__init__   sg    (--/!--/JCf}!2U3 * 	 ;TB0
j0
+0
 $[0
 =	0

 W0
  !30
 
0
 +0
 !0
  10
 F0
 F0
 <0
 V0
 50
  E!0
" %#0
$  #""#("'/50
,> 00557 	+rB   r   c                    g }t        |      }|t        j                  k(  r/| j                  }|j	                  d       |j	                  d       n| j
                  }|j                         D ]  \  }}|s	|j                  |        |S )Nr   r   )r   r,   r   r   popr   r   ri   )r?   r   supported_paramsr   open_ai_to_oci_param_mapr   rn   s          r@   get_supported_openai_paramsz)OCIChatConfig.get_supported_openai_params   s    &u-Z&&&'+'J'J$$((7$((7'+'K'K$288:JC '', ;  rB   non_default_paramsoptional_paramsdrop_paramsc                 R   i }t        |      }|t        j                  k(  r| j                  }n| j                  }i ||}|j                         D ]T  \  }	}
|j                  |	      }|du r"|st        j                  r.t        d|	 d      ||
||	<   E|
||<   |dk(  sP|
|d<   V |S )NFzparam `z` is not supported on OCIr   r   )
r   r,   r   r   r   r   getlitellmr   	Exception)r?   r   r   r   r   adapted_paramsr   r   
all_paramsr   rn   aliass               r@   map_openai_paramszOCIChatConfig.map_openai_params  s     &u-Z&&&'+'J'J$'+'K'K$>*>o>
$**,JC,005E~'"5"5'#.G HII}&+s#$)N5!((4901! -$ rB   rL   request_dataapi_basec                 d   |j                  d      }t        j                  |      j                  d      }t	        |j                  dd            j                         }|dvrt        d|       |j                         }|j                  dd       |j                  d	t	        t        |                   t        ||||
      }	|t        d      	 |j                  |	d       |j                  |	j                         ||fS # t        $ r }
t        ddt	        |
       d      |
d}
~
ww xY w)a  
        Sign request using OCI SDK Signer object.

        Args:
            headers: Request headers to be signed
            optional_params: Optional parameters including oci_signer
            request_data: The request body dict to be sent in HTTP request
            api_base: The complete URL for the HTTP request

        Returns:
            Tuple of (signed_headers, encoded_body)

        Raises:
            OCIError: If signing fails
            ValueError: If HTTP method is unsupported
        
oci_signerru   rJ   POST)r   GETPUTDELETEPATCHzUnsupported HTTP method: content-typeapplication/jsoncontent-length)rJ   rK   rL   rM   Nz<oci_signer cannot be None when calling _sign_with_oci_signerTr9   i  z1Failed to sign request with provided oci_signer: z. The signer must implement the OCI SDK Signer interface with a do_request_sign(request, enforce_content_headers=True) method. See: https://docs.oracle.com/en-us/iaas/tools/python/latest/api/signing.htmlstatus_codemessage)r   jsondumpsr{   rU   upperr   r   
setdefaultlenrI   rA   r   r   updaterL   )r?   rL   r   r   r   r   rM   rJ   prepared_headersrequest_wrapperr   s              r@   _sign_with_oci_signerz#OCIChatConfig._sign_with_oci_signer%  sA   . %((6
zz,'..w7_((6:;AACBB8ABB"<<>##N4FG##$4c#d)nE+x1A
 N 	&&PT&U 	../}  		GAx Pc c 		s   D 	D/D**D/c           	         |j                  dd      }|xs t        j                  xs d| d}|j                  d      }|j                  d      }|j                  d      }|j                  d      }	|j                  d	      }
|r|r|r|	s|
st        d
      t	        |j                  dd            j                         }t        j                  |      j                  d      }t        |      }|j                  xs d}|j                  }t        j                  j                         j                  d      }|j                  dd      }t	        t        |            }t!        |      }|||||d}g d}t#        ||||      }	 ddlm} ddlm} d}|	r^t/        |	t              r+|	}|j1                  dd      }d|v r6|j1                  dd      }n#t3        ddt5        |	      j6                         |rt9        |      n|
rt;        |
      nd}|t3        dd      |j=                  |j                  d      |j?                         |jA                               }tC        jD                  |      jG                         }| d| d| }d | d!d"jI                  |       d#| d$}|jK                  ||||||d%       |dfS # t,        $ r}t-        d      |d}~ww xY w)&a  
        Sign request using manual OCI credentials.

        Args:
            headers: Request headers to be signed
            optional_params: Optional parameters including OCI credentials
            request_data: The request body dict to be sent in HTTP request
            api_base: The complete URL for the HTTP request

        Returns:
            Tuple of (signed_headers, None)

        Raises:
            Exception: If required credentials are missing
            ImportError: If cryptography package is not installed
        
oci_regionus-ashburn-1https://inference.generativeai..oci.oraclecloud.comoci_useroci_fingerprintoci_tenancyoci_keyoci_key_filezqMissing required parameters: oci_user, oci_fingerprint, oci_tenancy, and at least one of oci_key or oci_key_file.rJ   r   ru   /z%a, %d %b %Y %H:%M:%S GMTr   r   )datehostr   r   x-content-sha256)r   re   r   r   r   r   r   )hashes)paddingrt   Nz\nrg   z
i  zKoci_key must be a string containing the PEM private key content. Got type: r   z^Private key is required for OCI authentication. Please provide either oci_key or oci_key_file.zSignature version="1",keyId="z"",algorithm="rsa-sha256",headers="rf   z",signature="")authorizationr   r   r   r   r   )&r   r   r   r   rU   r   r   r   r{   r   rQ   netlocdatetimeutcnowstrftimer   rc   ro   rw   r   rx   r   ry   r|   replacer   typerC   r   r   signPKCS1v15SHA256r`   ra   rb   rj   r   ) r?   rL   r   r   r   r   r   r   r   r   r   rJ   rM   parsedrQ   r   r   content_typecontent_lengthx_content_sha256headers_to_signrk   signing_stringr   r   r   oci_key_contentprivate_key	signaturesignature_b64key_idr  s                                    r@   _sign_with_manual_credentialsz+OCIChatConfig._sign_with_manual_credentials`  sB   . %((~F
 RR0<PQ 	
 #&&z2)--.?@%))-8!%%i0&**>: "|? 
 _((6:;AACzz,'..w7(#{{!c}}  '')223NO{{>3EFSY(. (, 0

 0D/>
	=I '3'") #2"9"9%"F_,&5&=&=fd&KO #!!%g!7!7 8:   &o6  ,L9 	 x 
  $$!!'*MMO
	
 ((3::<=(1_,=>X 01 2'	+ 	 	!. ,"0$4		
 }E  	C 	s   K 	K
KKapi_keyr   fake_streamc	                 x    |j                  d      }	|	| j                  ||||      S | j                  ||||      S )an  
        Sign the OCI request by adding authentication headers.

        Supports two signing modes:
        1. OCI SDK Signer: Use an oci_signer object to sign the request
        2. Manual Signing: Use OCI credentials to manually sign the request

        Args:
            headers: Request headers to be signed
            optional_params: Optional parameters including auth credentials or oci_signer
            request_data: The request body dict to be sent in HTTP request
            api_base: The complete URL for the HTTP request
            api_key: Optional API key (not used for OCI)
            model: Optional model name
            stream: Optional streaming flag
            fake_stream: Optional fake streaming flag

        Returns:
            Tuple of (signed_headers, encoded_body):
            - If oci_signer is provided: Returns (headers, body) where body is the encoded JSON
            - If manual credentials are provided: Returns (headers, None) as body is not returned
              for the manual signing path

        Raises:
            OCIError: If signing fails with oci_signer
            Exception: If required credentials are missing
            ImportError: If cryptography package is not installed (manual signing only)

        Example:
            >>> from oci.signer import Signer
            >>> signer = Signer(
            ...     tenancy="ocid1.tenancy.oc1..",
            ...     user="ocid1.user.oc1..",
            ...     fingerprint="xx:xx:xx",
            ...     private_key_file_location="~/.oci/key.pem"
            ... )
            >>> headers, body = config.sign_request(
            ...     headers={},
            ...     optional_params={"oci_signer": signer},
            ...     request_data={"message": "Hello"},
            ...     api_base="https://inference.generativeai.us-ashburn-1.oci.oraclecloud.com/..."
            ... )
        r   )r   r   r  )
r?   rL   r   r   r   r  r   r   r  r   s
             r@   sign_requestzOCIChatConfig.sign_request  sW    l %((6
 !--, 
 11_lH
 	
rB   messageslitellm_paramsc                    |j                  d      }|j                  dd      }	|xs t        j                  xs d|	 d}|st        d      |}|j                  d      }
|j                  d      }|j                  d	      }|j                  d
      }|j                  d      }|j                  d      }|
r
|r|r|s|r|st        d      |j	                  ddt
         d       |st        d      |S )a  
        Validate the OCI environment and credentials.

        Supports two authentication modes:
        1. OCI SDK Signer: Pass an oci_signer object (e.g., oci.signer.Signer)
        2. Manual Credentials: Pass oci_user, oci_fingerprint, oci_tenancy, and oci_key/oci_key_file

        Args:
            headers: Request headers to populate
            model: Model name
            messages: List of chat messages
            optional_params: Optional parameters including authentication credentials
            litellm_params: LiteLLM parameters
            api_key: Optional API key (not used for OCI)
            api_base: Optional API base URL

        Returns:
            Updated headers dict

        Raises:
            Exception: If required parameters are missing or invalid
        r   r   r   r   r   zEither `api_base` must be provided or `litellm.api_base` must be set. Alternatively, you can set the `oci_region` optional parameter to use the default OCI region.r   r   r   r   r   oci_compartment_idzMissing required parameters: oci_user, oci_fingerprint, oci_tenancy, oci_compartment_id and at least one of oci_key or oci_key_file. Alternatively, provide an oci_signer object from the OCI SDK.r   zlitellm/)r   z
user-agentzRkwarg `messages` must be an array of messages that follow the openai chat standard)r   r   r   r   r   r   )r?   rL   r   r  r   r  r  r   r   r   r   r   r   r   r   r  s                   r@   validate_environmentz"OCIChatConfig.validate_environment7  s8   @ %((6
$((~F
  RR0<PQ 	 p  &**:6H-112CDO)--m<K%)))4G*..~>L!0!4!45I!J &"<)T  	 2 (	2	
 d  rB   c                 2    |j                  dd      }d| dS )Nr   r   r   z*.oci.oraclecloud.com/20231130/actions/chat)r   )r?   r   r  r   r   r  r   r   s           r@   get_complete_urlzOCIChatConfig.get_complete_url  s&     %((~F
0<fggrB   r   c                    i }|t         j                  k(  r&| j                  }|j                  d       dddddd}n| j                  }|j                         D ]  \  }}|s	||v s||   ||<    |j                         D ]  }|s||v s||vs||   ||<    d|v r=|t         j                  k(  r| j                  |d         |d<   nt        |d   |      |d<   d|v r|d   }t        |t              rd	|v rt        |      }	|	|d<   |	d	   }
d }d
|	v r/|	j                  d
      }t        |t              rt        |      }n|}|||	d<   |t         j                  k(  r|
|	d	<   |S |
j                         }|dk(  rd}||	d	<   |S )Nr   iX     r   g      ?)r   r   topKr   r   r   r   r  json_schema
jsonSchemaJSONJSON_OBJECT)r,   r   r   r   r   r   values)adapt_tool_definitions_to_cohere_standard%adapt_tool_definition_to_oci_standardr|   rW   r   )r?   r   r   selected_paramsr   
openai_keyr   	oci_valuerf
rf_payloadresponse_typeschema_payloadraw_schema_payloadformat_types                 r@   _get_optional_paramsz"OCIChatConfig._get_optional_params  s   Z&&&'+'J'J$$((7 ! $%O (,'K'K$ $<#A#A#CJ:8+::+F( $D
 288:I0_4-<Y-G	* ; o%***+/+Y+Y#G,,( ,Q#G,f,(
 . !12B"d#"!"X
4> 01 *6 204 J.)3)F&!"4d;)-.@)A);!-/=J|,Z...)6Jv&  #0"5"5"7K"f,&3)4Jv&rB   c                    g }|dd D ]  }|j                  d      }|j                  d      }t        |t              rFd}|D ]=  }t        |t              s|j                  d      dk(  s)||j                  dd      z  }? |}t        |t              s|t	        |      nd}d}|dk(  rd	|v r|j                  d	      rg }|d	   D ]  }	|	j                  d
i       j                  di       }
t        |
t              r	 t        j                  |
      }n|
}|j                  t        t	        |	j                  d
i       j                  dd            |              |dk(  r|j                  t        d|             v|dk(  r|j                  t        d||             |dk(  s|j                  t        d|d              |S # t
        j                  $ r i }Y w xY w)z%Build chat history for Cohere models.NrolecontentrP   r  text	assistant
tool_callsfunction	argumentsname)r?  
parametersuserUSER)r8  r   CHATBOT)r8  r   	toolCallstoolTOOL)r   r|   listrW   rU   r   loadsJSONDecodeErrorri   r   r   )r?   r  chat_historymsgr8  r9  text_contentcontent_itemr<  	tool_callraw_argumentsr>  s               r@   !adapt_messages_to_cohere_standardz/OCIChatConfig.adapt_messages_to_cohere_standard  s    CR=C776?Dggi(G'4(!$+L"<6(,,V4>$(8(8(DD %, ' gs+*1*=#g,2 :>J{"|s':sww|?T
!$\!2I)2z2)F)J)J#R*M "-5+8<

=8QI %2	%%&!$Y]]:r%B%F%Fvr%R!S'0 "3( v~##Mvw$OP$##!y'ZX ##!# '"&g !v 9  $33 +(*I+s   <GG#"G#r   c           
         g }|D ]  }|j                  di       }|j                  di       j                  di       }|j                  di       j                  dg       }i }|j                         D ]8  \  }}	t        |	j                  dd      |	j                  dd      ||v 	      ||<   : |j                  t	        |j                  d
d      |j                  dd      |              |S )z(Adapt tool definitions to Cohere format.r=  r@  
propertiesrequireddescriptionrP   r  string)rT  r  
isRequiredr?  )r?  rT  parameterDefinitions)r   r   r   ri   r   )
r?   r   cohere_toolsrE  function_defr@  rS  parameter_definitions
param_nameparam_schemas
             r@   r*  z7OCIChatConfig.adapt_tool_definitions_to_cohere_standard"  s     D88J3L%)),;??bQJ#''b9==j"MH$&!,6,<,<,>(
L4M , 0 0 C%))&(;)X55%j1 -? %))&"5 , 0 0 C)> * rB   r9  c                     t        |t              r|S t        |t              rFd}|D ]=  }t        |t              s|j	                  d      dk(  s)||j	                  dd      z  }? |S t        |      S )z*Extract text content from message content.rP   r  r:  )r|   rU   rG  rW   r   )r?   r9  rL  rM  s       r@   _extract_text_contentz#OCIChatConfig._extract_text_content>  sp    gs#N&L '|T2$((0F: L$4$4VR$@@L !(  7|rB   c                     |j                  dd       }|st        d      t        |      }|j                  dd      }|dvrt        d      |dk(  r |j                  d|      }	t        d|		      }
nt        d|
      }
|t        j
                  k(  r|D cg c]  }|j                  d      dk(  s| }}|st        d      |D cg c]  }|j                  d      dk(  s| }}d }|rdj                   fd|D              }|r|} j                  t        j
                  |      }t        dd j                  |d   d          j                  |      |d|}t        ||
|      }n=t        ||
t        d|j                  t        |      d j                  ||            }|j                  d      S c c}w c c}w )Nr  z7kwarg `oci_compartment_id` is required for OCI requestsoci_serving_mode	ON_DEMAND)ra  	DEDICATEDzBkwarg `oci_serving_mode` must be either 'ON_DEMAND' or 'DEDICATED'rb  oci_endpoint_id)servingType
endpointId)rd  modelIdr8  rA  z&No user message found for Cohere modelsystemrg   c              3   F   K   | ]  }j                  |d            yw)r9  N)r^  ).0rK  r?   s     r@   	<genexpr>z2OCIChatConfig.transform_request.<locals>.<genexpr>y  s(      %. ..s9~>.s   !r   r7  r9  )	apiFormatr   chatHistorypreambleOverride)compartmentIdservingModechatRequest)rk  r  T)exclude_noner>   )r   r   r   r'   r,   r   rj   r5  r   r^  rP  r    r   rn   &adapt_messages_to_generic_oci_standard
model_dump)r?   r   r  r   r  rL   r  r   r`  rc  ro  rK  user_messagessystem_messagespreamble_overridepreambleoptional_cohere_paramschat_requestrZ   s   `                  r@   transform_requestzOCIChatConfig.transform_requestM  s    -001EtL!UVV&u-*../A;O#==T  {*-112CUKO('*K
 )'K Z&&& -5RHS68QSHMR  HII /7Vhs#''&/X:UshOV $99 %.%  (0% &*%>%>!!?&" - "22=3DY3OP BB8L!2	
 )L (0'(D (0'1 $llCHM //HD D11Y S
 Ws   F;0F;G !G json_responsemodel_responsec           	         t        di |}|}||_        t        t        j                  j	                         j                               |_        |j                  j                  }|j                  j                  }|dk(  rd}n
|dk(  rd}nd}d}	|j                  j                  rhg }	|j                  j                  D ]M  }
|	j                  dt        |	       d|
j                  t        j                  |
j                         dd	       O d
dlm}  |d
d||	d|      }|g|_        |j                  j(                  }d
dlm}  ||j,                  |j.                  |j0                        |_        |S )z'Handle Cohere-specific response format.COMPLETEr   
MAX_TOKENSlengthNcall_r=  r?  r>  idr  r=  r   )Choicesr;  )r8  r9  r<  )indexr   finish_reason)r5   prompt_tokenscompletion_tokenstotal_tokensr>   )r   r   intr  now	timestampcreatedchatResponser:  finishReasonrD  ri   r   r?  r   r   r@  litellm.types.utilsr  choicesusager5   promptTokenscompletionTokenstotalTokens)r?   r{  r   r|  cohere_responsemodel_idresponse_textoci_finish_reasonr  r<  rN  r  choice
usage_infor5   s                  r@   _handle_cohere_responsez%OCIChatConfig._handle_cohere_response  sw    +;];  (!$X%6%6%:%:%<%F%F%H!I (4499+88EE 
*"M,.$M"M 6:
''11J,99CC	!! %c*o%67 *$-NN)-I4H4H)I%	 D 	0#((
 (
 #) %1177
-$$11(99#// 
 rB   r   raw_responsec                    	 t        d	i |}|j
                  j                  }t        j                  j                  |j                  dd            }t        |j                               |_        |j                  |_        |j                  d   j                   }	|j
                  j                  d   j                   }
|
j"                  r:|
j"                  d   j$                  dk(  r|
j"                  d   j&                  |	_        |
j(                  rt+        |
j(                        |	_        t/        |j
                  j0                  j2                  |j
                  j0                  j4                  |j
                  j0                  j6                        }||_        |S # t        $ r(}t        dt        |       |j                        d}~ww xY w)
z#Handle generic OCI response format.z4Response cannot be casted to OCICompletionResponse: r   r   NZz+00:00r   TEXTr  r>   )r!   r~   r   rU   r   r  timeCreatedr  fromisoformatr  r  r  r  rf  r   r  r   r9  r  r:  rD  adapt_tools_to_openai_standardr<  r5   r  r  r  r  )r?   r   r   r|  r  completion_responser   iso_strdtr   response_messager  s               r@   _handle_generic_responsez&OCIChatConfig._handle_generic_response  s   	"7"?$"? &22>>,,W__S(-KL!$R\\^!42:: ((+33.;;CCAFNN##(8(@(@(C(H(HF(R.66q9>>GO%%!? **"G -::@@MM1>>DDUU,99??KK

  %9  	NsSTvhW(44 	s   F 	G##GGlogging_objr   	json_modec                    |j                         } |j                  d      }|#t        t        |d         |j                        t        |t              st        d|j                        t        |      }|t        j                  k(  r| j                  |||      }n| j                  ||||      }|j                  |j                  d<   |S )Nerrorr  z Invalid response format from OCIadditional_headers)r   r   r   rU   r   r|   rW   r   r,   r   r  r  rL   _hidden_params)r?   r   r  r|  r  r   r  r   r  r   r  r  r   r  r   s                  r@   transform_responsez OCIChatConfig.transform_response	  s       "!DM*(44 
 $%:(44 
 'u- Z&&&!99$~VN!::e^\N ?K>R>R%%&:;rB   custom_llm_providerrZ   clientsigned_json_bodyOCIStreamWrapperc                    d|v r|d= |t        |t              rt        i       }	 |j                  ||t	        j
                  |      d|t              }|j                  dk7  r!t        |j                  |j                        |j                         }t        ||||      }|S # t        j                  $ r:}t        |j                  j                  |j                  j                        d }~ww xY w)Nr   )paramsTrL   rZ   r   r  timeoutr      completion_streamr   r  r  )r|   r   r   postr   r   STREAMING_TIMEOUThttpxHTTPStatusErrorr   responser   r:  	iter_textr  )r?   r   r  r  r   rL   rZ   r  r  r  r  r  r   r  streaming_responses                  r@   get_sync_custom_stream_wrapperz,OCIChatConfig.get_sync_custom_stream_wrapper5  s     tX>Z0@A&b1F
	X{{ZZ%') # H 3&x';';X]]SS$..0-/ 3#	
 "! $$ 	Xqzz'='=qzzWW	Xs   .B& &C395C..C3c                 T  K   d|v r|d= |t        |t              rt        t        j                  i       }	 |j                  ||t        j                  |      d|t               d {   }|j                  dk7  r!t        |j                  |j                        |j                         }dt         t"           fd}t%         ||      |||	      }|S 7 l# t        j                  $ r:}t        |j                  j                  |j                  j                        d }~ww xY ww)
Nr   )llm_providerr  Tr  r   r  r  c                   K   | 2 3 d {   }|j                  d      D ]  }|s|j                           67 16 y w)Nz

)r   r   )r  itemchunks      r@   split_chunkszCOCIChatConfig.get_async_custom_stream_wrapper.<locals>.split_chunks  s>     / (d!ZZ/E  ++-' 0(/s   ?=;=.?=?r  )r|   r   r   r/   BYTEZr  r   r   r  r  r  r   r  r   r:  
aiter_textr   rU   r  )r?   r   r  r  r   rL   rZ   r  r  r  r  r  r   r  r  r  s                   r@   get_async_custom_stream_wrapperz-OCIChatConfig.get_async_custom_stream_wrappera  s     tX>Z<+9K9KTVWF
	X#[[ZZ%') )  H 3&x';';X]]SS$//1	(-2D 	( .*+<= 3#	
 "!; $$ 	Xqzz'='=qzzWW	Xs;   5D(1C )C*C .A(D(C D%+5D  D%%D(error_messager   c                     t        ||      S )Nr   r   )r?   r  r   rL   s       r@   get_error_classzOCIChatConfig.get_error_class  s     KGGrB   )r<   N)NNNN)NNr\   )NNN)0rC   rD   rE   rF   r   rU   r   r   rW   rG   r   r   rX   r   r  r	   r  r-   r  r!  r,   r   r5  r   rP  r   r   r*  r^  rz  r0   r  r  Responser  LiteLLMLoggingObjr  r   rG  r   r   r   r  r  r  Headersr   r  r>   rB   r@   r   r      s   *
	*
X   c  " " " 	"
 " 
"H99 9 	9
 9 
tU{	9vRR R 	R
 R 
tTz	Rt "&#!%&*A
A
 A
 	A

 A
 #A
 }A
 A
 d^A
 
tXe_$	%A
T "&"&SS S '(	S
 S S #S 3-S 
Sx "&
h3-
h #
h 	
h
 
h 
h 
h 

hF: F FQU FP@-.@	m	@D$sCx.)	j	8S S P2P2 '(P2 	P2
 P2 P2 
P2d@!@*-@?L@	@D&& & &	&
 nn& 
&f "&$(** nn* &	*
 '* * '(* * * * #* D>* 
*X  BF$(,0)")" !)" '	)"
 )" )" )" )" {,<<=>)" D>)" #5/)" 
)" )"V  BF$(,01"1" !1" '	1"
 1" 1" 1" 1" {,<<=>1" D>1" #5/1" 
1" 1"fH H/2H=B4CV=WH	HrB   r   SYSTEMrB  	ASSISTANTrF  )rg  rA  r;  rE  open_ai_to_generic_oci_role_mapr8  r9  c                    g }t        |t              r!t        t        |    t	        |      gd d       S |D ]"  }t        |t
              st        d      |j                  d      }t        |t              st        d      |dvrt        d| d      |d	k(  rH|j                  d	      }t        |t              st        d
      |j                  t	        |             |dk(  s|j                  d      }t        |t
              r|j                  d      }t        |t              st        d      |j                  t        t        |                   % t        t        |    |d d       S )Nr:  r8  r9  rD  
toolCallIdz&Each content item must be a dictionaryr  zProp `type` is not a string)r:  	image_urlzProp `z` is not supportedr:  zProp `text` is not a stringr  rK   zDProp `image_url` must be a string or an object with a `url` property)rK   )imageUrl)r|   rU   r%   r  r)   rW   r   r   ri   r#   r$   )r8  r9  new_contentrM  r  r:  r  s          r@   6adapt_messages_to_generic_oci_standard_content_messager    se    .0K'306'W56	
 	
  ,-DEE'$$9::,,fTF*<=>>6>##F+DdC( =>>1t<=[ $((5I)T*%MM%0	i-Z  2KI<VWX5  8 ,T2	 rB   r<  c           	      \   g }|D ]  }t        |t              st        d      |j                  d      dk7  rt        d      |j                  d      }t        |t              st        d      |j                  d      }t        |t              st        d      |j                  d      }t        |t              st        d	      |d   j                  d
d      }t        |t              st        d      |j                  t        |d||              t        t        |    d |d       S )Nz#Each tool call must be a dictionaryr  r=   OCI only supports function toolsr  zProp `id` is not a string#Prop `function` is not a dictionaryr?  zProp `name` is not a stringr>  z{}z Prop `arguments` is not a stringFUNCTION)r  r  r?  r>  r  )	r|   rW   r   r   rU   ri   r*   r%   r  )r8  r<  tool_calls_formatedrN  tool_call_idtool_functionfunction_namer>  s           r@   0adapt_messages_to_generic_oci_standard_tool_callr    s(    	)T*ABB== J.>?? }}T*,,788!j1-.ABB%))&1--9::j)--k4@	)S)>?? 	"""#		
A  R ,T2%	 rB   r  c                 D    t        t        |    t        |      gd |      S )Nr  r  )r%   r  r)   )r8  r  r9  s      r@   4adapt_messages_to_generic_oci_standard_tool_responser    s*     ,T2#12	 rB   r  c                 >   g }| D ]  }|d   }|j                  d      }|j                  d      }|j                  d      }|dk(  r9|7t        |t              st        d      |j	                  t        ||             z|dv r?|=t        |t        t        f      st        d      |j	                  t        ||             |d	k(  st        |t              st        d
      t        |t              st        d      |j	                  t        |||              |S )Nr8  r9  r<  r  r;  z.Prop `tool_calls` must be a list of tool calls)rg  rA  r;  z:Prop `content` must be a string or a list of content itemsrE  z4Prop `tool_call_id` is required and must be a stringzProp `content` is not a string)	r   r|   rG  r   ri   r  rU   r  r  )r  new_messagesr   r8  r9  r<  r  s          r@   rr  rr    s$    Lv++i([[.
{{>2;:#9j$/ PQQ@zR 449LgT{3P  FtWU V^lC0 VWWgs+ @AAD,7 B rB   r   r   c           
      4   g }| D ]  }|d   dk7  rt        d      |j                  d      }t        |t              st        d      t	        d|j                  d      |j                  dd      |j                  d	i       
      }|j                  |        |S )Nr  r=  r  r  r  r?  rT  rP   r@  )r  r?  rT  r@  )r   r   r|   rW   r+   ri   )r   r   	new_toolsrE  r  new_tools         r@   r+  r+  @  s    I<:%>??,-.ABB$""6*%))-<$((r:	
 	"   rB   c                     g }| D ]B  }t        |j                  d|j                  |j                  d      }|j	                  |       D |S )Nr=  r  r  )r3   r  r?  r>  ri   )r   r  rE  r  s       r@   r  r  U  sR     I0ww		!^^
 	"  rB   c                   L     e Zd ZdZdef fdZdefdZdefdZdefdZ	 xZ
S )	r  zw
    Custom stream wrapper for OCI responses.
    This class is used to handle streaming responses from OCI's API.
    kwargsc                 $    t        |   di | y )Nr>   )superr   )r?   r  r   s     r@   r   zOCIStreamWrapper.__init__l  s     	"6"rB   r  c                     t        |t              st        d|       |j                  d      st        d|       t	        j
                  |dd        }d|v r%|j                  d      dk(  r| j                  |      S | j                  |      S )NzChunk is not a string: zdata:z#Chunk does not start with 'data:':    rk  r   )	r|   rU   r   
startswithr   rH  r   _handle_cohere_stream_chunk_handle_generic_stream_chunk)r?   r  
dict_chunks      r@   chunk_creatorzOCIStreamWrapper.chunk_creatorr  s    %%6ug>??(B5'JKKZZab	*
 *$)D)P33J??44Z@@rB   r  c                 x   	 t        di |}|j                  d|_        |j
                  xs d}|j                  }|dk(  rd}n|dk(  rd}n|d}nd}d}t        t        |j                  r|j                  ndt        ||ddd	      |
      g      S # t        $ r}t        dt        |             d}~ww xY w)z(Handle Cohere-specific streaming chunks.z-Chunk cannot be casted to CohereStreamChunk: Nr   rP   r~  r   r  r  r9  r<  provider_specific_fieldsthinking_blocksreasoning_contentr  deltar  r  r>   )
r   r~   r   rU   r  r:  r  r1   r2   r.   )r?   r  typed_chunkr   r:  r  r<  s          r@   r  z,OCIStreamWrapper._handle_cohere_stream_chunk  s    	W+9j9K $ !K %2 $00J&"Ml*$M" M"M 
" /:/@/@+++a $#-15(,*. #0

 	
/  	WLSQRVHUVV	Ws   B 	B9B44B9c                    |j                  d      r=|d   j                  d      r)|d   d   D ]  }d|vrd|d<   d|vrd|d<   d|vsd|d<     	 t        di |}|j
                  d	|_        d}|j                  r|j                  j                  rm|j                  j                  D ]T  }t        |t              r||j                  z  }#t        |t              rt        d
      t        d|j                          d}|j                  r5|j                  j                  rt        |j                  j                        }t        t!        |j
                  r|j
                  nd	t#        ||r|D cg c]  }|j%                          c}ndddd      |j&                        g      S # t        $ r}t        dt	        |             d}~ww xY wc c}w )z$Handle generic OCI streaming chunks.r   rD  r>  rP   r  r?  z*Chunk cannot be casted to OCIStreamChunk: Nr   z9OCI does not support image content in streaming responsesz*Unsupported content type in OCI response: r  r  r  r>   )r   r(   r~   r   rU   r  r   r9  r|   r)   r:  r#   r  rD  r  r1   r2   r.   rs  r  )	r?   r  rN  r  r   r:  r  r<  rE  s	            r@   r  z-OCIStreamWrapper._handle_generic_stream_chunk  s    >>)$I)>)B)B;)O'	2;?	i/-/Ik*y(&(IdO*(*If% @	T(6:6K $ !K;#6#6#>#>#++33d$67DII%D&9:$S  %DTYYKP  4 
;#6#6#@#@78K8K8U8UVJ" /:/@/@+++a $  * <FF:4T__.:F!%15(,*.
 #.":":
 	
1  	TI#a&RSS	T> Gs   F+ 1G+	G4GG)rC   rD   rE   rF   r   r   r  rW   r  r  __classcell__)r   s   @r@   r  r  f  s<    
##A3 A)
d )
V9
t 9
rB   r  )\r`   r  r]   r   dataclassesr   typingr   r   r   r   r   r	   r
   r   r   urllib.parser   r  r   (litellm.litellm_core_utils.logging_utilsr   )litellm.llms.base_llm.chat.transformationr   r   &litellm.llms.custom_httpx.http_handlerr   r   r   r   r   litellm.llms.oci.common_utilsr   litellm.types.llms.ocir   r   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   r&   r'   r(   r)   r*   r+   r,   litellm.types.llms.openair-   r  r.   r/   r0   r1   r2   litellm.utilsr3   r4   r5   *litellm.litellm_core_utils.litellm_loggingr6   _LiteLLMLoggingObjr  r8   rI   rX   rU   rc   ro   r   r   r   r  r   r  rV   rG  r  r  r  rr  r+  r  r  r>   rB   r@   <module>r     s	       !
 
 
 "   I R  3     . 7   X* . V V V(- -# -
s *.# . " " "   WHJ WHv 	8 c8m!4 2
2c4i(22j2
222j
 +.%#$%	*%Pd Z *	
'("}
* }
rB   