Ë
    uPêjÉ`  ã                   óÆ  — U d Z ddlZddlmZmZ ddlmZmZmZm	Z	m
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mZmZmZ dd	lmZ dd
lmZ ddlmZ er	ddl m!Z" e"Z#neZ#dZ$ee%d<   dZ&ee%d<    G d„ de
d¬«      Z' G d„ de
d¬«      Z( G d„ de
d¬«      Z) G d„ de	«      Z* G d„ de	«      Z+de*dee,e-f   fd „Z.de+de)fd!„Z/d"e,de0fd#„Z1 G d$„ d%ee«      Z2 G d&„ d'e«      Z3y)(uY  
Snowflake Cortex REST API â€” Chat Transformation

Routes to native Cortex REST API endpoints based on model:
  - Claude models â†’ POST /api/v2/cortex/v1/messages (Anthropic format)
  - All other models â†’ POST /api/v2/cortex/v1/chat/completions (OpenAI format)

Ref: https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-rest-api
é    N)ÚMappingÚSequence)ÚTYPE_CHECKINGÚAnyÚFinalÚProtocolÚ	TypedDict)ÚReadOnly)ÚAllMessageValuesÚChatCompletionToolCallChunk)ÚChatCompletionMessageToolCallÚChatCompletionUsageBlockÚChoicesÚFunctionÚGenericStreamingChunkÚMessageÚModelResponseÚUsageé   )ÚBaseModelResponseIterator)ÚOpenAIGPTConfigé   )ÚSnowflakeBaseConfig)ÚLoggingz
2023-06-01ÚANTHROPIC_VERSION)zclaude-Úclaude_Ú_CLAUDE_MODEL_PREFIXESc                   óh   — e Zd ZU ee   ed<   ee   ed<   ee   ed<   ee   ed<   eeeef      ed<   y)Ú_AnthropicContentBlockÚtypeÚtextÚidÚnameÚinputN)Ú__name__Ú
__module__Ú__qualname__r
   ÚstrÚ__annotations__r   Úobject© ó    úo/home/oem/CyberBrain26-unified/.venv/lib/python3.12/site-packages/litellm/llms/snowflake/chat/transformation.pyr   r   1   s>   … Ø
�3‰-ÓØ
�3‰-ÓØ�‰ÓØ
�3‰-ÓØ�G˜C ˜KÑ(Ñ)Ô)r,   r   F)Útotalc                   ó.   — e Zd ZU ee   ed<   ee   ed<   y)Ú_AnthropicUsageBlockÚinput_tokensÚoutput_tokensN)r%   r&   r'   r
   Úintr)   r+   r,   r-   r0   r0   9   s   … Ø˜3‘-ÓØ˜C‘=Ô r,   r0   c                   ód   — e Zd ZU ee   ed<   ee   ed<   ee   ed<   eee      ed<   ee   ed<   y)Ú_AnthropicMessagesResponser"   ÚmodelÚstop_reasonÚcontentÚusageN)	r%   r&   r'   r
   r(   r)   r   r   r0   r+   r,   r-   r5   r5   >   s=   … Ø�‰ÓØ�C‰=ÓØ˜#‘ÓØ�hÐ5Ñ6Ñ7Ó7ØÐ(Ñ)Ô)r,   r5   c                   ó&   — e Zd ZdZdeeef   fd„Zy)Ú_ChatCompletionsResponsezOResponse view that decodes the Cortex chat-completions body as a field mapping.Úreturnc                  ó   — y ©Nr+   ©Úselfs    r-   Újsonz_ChatCompletionsResponse.jsonI   ó   � r,   N)r%   r&   r'   Ú__doc__r   r(   r*   rA   r+   r,   r-   r;   r;   F   s   „ ÙYà/�g˜c 6˜kÑ*Ô/r,   r;   c                   ó   — e Zd ZdZdefd„Zy)Ú_MessagesResponsezGResponse view that decodes the Cortex messages body in Anthropic shape.r<   c                  ó   — y r>   r+   r?   s    r-   rA   z_MessagesResponse.jsonO   rB   r,   N)r%   r&   r'   rC   r5   rA   r+   r,   r-   rE   rE   L   s   „ ÙQà5Ð0Ô5r,   rE   Úresponser<   c                 ó"   — | j                  «       S r>   ©rA   ©rG   s    r-   Ú_decoded_chat_completionsrK   R   ó   € Ø�=‰=‹?Ðr,   c                 ó"   — | j                  «       S r>   rI   rJ   s    r-   Ú_decoded_messagesrN   V   rL   r,   r6   c                 ór   ‡— | j                  «       j                  d«      Št        ˆfd„t        D «       «      S )zPReturn True if model name (after stripping snowflake/ prefix) is a Claude model.ú
snowflake/c              3   ó@   •K  — | ]  }‰j                  |«      –— Œ y ­wr>   )Ú
startswith)Ú.0Úpr#   s     €r-   ú	<genexpr>z#_is_claude_model.<locals>.<genexpr>]   s   øè ø€ ÒB aˆt�‰˜q×!ÑBùs   ƒ)ÚlowerÚremoveprefixÚanyr   )r6   r#   s    @r-   Ú_is_claude_modelrY   Z   s+   ø€ à—+‘+“-×,Ñ,¨\Ó:€DÜÓBÔ+AÔBÓBÐBr,   c                   ó–  ‡ — e Zd ZdZeˆ fd„«       Zdedee   fd„Z	 d&dedz  dedz  ded	e	d
e	de
dz  defd„Z	 	 d'de	dedee   d	e	d
e	dedz  dedz  de	fˆ fd„Zdee	   dee	   fd„Zdee   deedz  ee	   f   fd„Zdedee   d	e	d
e	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	eef   fd„Zdedee   d	e	de
de	de	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dz  de
dz  defd„Zdedej.                  dedede	dee   defd „Zdedej.                  dedede	dee   defd!„Z	 d(d"ed#e
de
dz  dd$fd%„Zˆ xZS ))ÚSnowflakeConfiguÍ  
    Snowflake Cortex REST API â€” unified provider.

    Auto-routes based on model name:
      - Claude models â†’ /api/v2/cortex/v1/messages (Anthropic Messages format)
      - All others   â†’ /api/v2/cortex/v1/chat/completions (OpenAI format)

    Auth:
        PAT:  api_key="pat/<token>"  â†’  X-Snowflake-Authorization-Token-Type: PROGRAMMATIC_ACCESS_TOKEN
        JWT:  api_key="<jwt>"        â†’  X-Snowflake-Authorization-Token-Type: KEYPAIR_JWT
    c                 ó    •— t         ‰| �  «       S r>   )ÚsuperÚ
get_config)ÚclsÚ	__class__s    €r-   r^   zSnowflakeConfig.get_configm   s   ø€ ä‰wÑ!Ó#Ð#r,   r6   r<   c                 óF   — g d¢}t        |«      r|j                  d«       |S )N)ÚtemperatureÚ
max_tokensÚmax_completion_tokensÚtop_pÚstreamÚtoolsÚtool_choiceÚthinking)rY   Úappend)r@   r6   Úparamss      r-   Úget_supported_openai_paramsz+SnowflakeConfig.get_supported_openai_paramsq   s$   € ò
ˆô ˜EÔ"Ø�M‰M˜*Ô%Øˆr,   NÚapi_baseÚapi_keyÚoptional_paramsÚlitellm_paramsrf   c                 óP   — | j                  ||«      }t        |«      r|› d�S |› d�S )Nz/cortex/v1/messagesz/cortex/v1/chat/completions)Ú_get_api_baserY   )r@   rm   rn   r6   ro   rp   rf   s          r-   Úget_complete_urlz SnowflakeConfig.get_complete_url   s:   € ð ×%Ñ% h°Ó@ˆÜ˜EÔ"Ø�ZÐ2Ð3Ð3Ø�Ð6Ð7Ð7r,   ÚheadersÚmessagesc           	      ó\   •— t         ‰| �  |||||||¬«      }t        |«      r	t        |d<   |S )N)rt   r6   ru   ro   rp   rn   rm   zanthropic-version)r]   Úvalidate_environmentrY   r   )	r@   rt   r6   ru   ro   rp   rn   rm   r`   s	           €r-   rw   z$SnowflakeConfig.validate_environment�   sH   ø€ ô ‘'Ñ.ØØØØ+Ø)ØØð /ó 
ˆô ˜EÔ"Ü+<ˆGÐ'Ñ(Øˆr,   rg   c                 ó  — g }|D ]w  }|j                  d«      dk(  rPd|v rL|d   }d|j                  dd«      i}d|v r|d   |d<   d|v r	|d   |d<   ndi d	œ|d<   |j                  |«       Œg|j                  |«       Œy |S )
zé
        Convert tools from OpenAI format to Anthropic format.

        OpenAI: {"type": "function", "function": {"name": ..., "parameters": {...}}}
        Anthropic: {"name": ..., "description": ..., "input_schema": {...}}
        r    Úfunctionr#   Ú ÚdescriptionÚ
parametersÚinput_schemar*   )r    Ú
properties)Úgetrj   )r@   rg   Úanthropic_toolsÚtoolÚfuncÚanthropic_tools         r-   Ú_transform_tools_to_anthropicz-SnowflakeConfig._transform_tools_to_anthropic¤   s»   € ð "$ˆØò 	-ˆDØ�x‰x˜Ó :Ò-°*ÀÑ2DØ˜JÑ'�à˜DŸH™H V¨RÓ0ð5�ð ! DÑ(Ø48¸Ñ4G�N =Ñ1Ø 4Ñ'Ø59¸,Ñ5G�N >Ò2ð !)Ø&(ñ6�N >Ñ2ð  ×&Ñ& ~Õ6à×&Ñ& tÕ,ð#	-ð$ Ðr,   c           	      óÆ  — g }g }|D �]  }t        |t        «      r%|j                  dd«      }|j                  dd«      }nt        |dd«      }t        |dd«      }|dk(  r]t        |t        «      r|r|j                  |«       Œ|t        |t        «      sŒ�|j                  dj                  d„ |D «       «      «       Œµ|dk(  �rvt        |t        «      r|j                  d«      nt        |dd	«      }|�r/g }|r|j                  d
|dœ«       |D ]ü  }	t        |	t        «      r|	j                  di «      nt        |	di «      }
t        |	t        «      r|	j                  dd«      nt        |	dd«      }t        |
t        «      r|
j                  dd«      nt        |
dd«      }t        |
t        «      r|
j                  dd«      nt        |
dd«      }	 t        |t        «      rt        j                  |«      n|}|j                  d|||dœ«       Œþ |j                  d|dœ«       �Œ|j                  d|dœ«       �Œ1|dk(  rÔt        |t        «      r|j                  dd«      nt        |dd«      }t        |t        «      r|nt        j                  |«      }d||dœ}|r_|d   d   dk(  rTt        |d   d   t        «      r>|d   d   r6|d   d   d   j                  d«      dk(  r|d   d   j                  |«       �Œó|j                  d|gdœ«       �Œ
|j                  ||dœ«       �Œ  |rdj                  |«      nd	}||fS # t        j                  t        f$ r i }Y �Œkw xY w)uF  
        Split messages into system prompt and conversation turns for Anthropic format.

        - system messages â†’ collected and joined (preserves guardrail prompts)
        - assistant messages with tool_calls â†’ tool_use content blocks
        - tool role messages â†’ user role with tool_result content blocks
        Úrolerz   r8   Úsystemú
c              3   ój   K  — | ]+  }|j                  d «      dk(  sŒ|j                  dd«      –— Œ- y­w)r    r!   rz   N)r   )rS   Úbs     r-   rU   z?SnowflakeConfig._extract_system_and_messages.<locals>.<genexpr>×   s0   è ø€ Ò1pÈÐXY×X]ÑX]Ð^dÓXeÐioÓXo°!·%±%¸À×2CÑ1pùs   ‚3œ3Ú	assistantÚ
tool_callsNr!   )r    r!   ry   r"   r#   Ú	argumentsz{}Útool_use)r    r"   r#   r$   )r†   r8   r�   Útool_call_idÚtool_result)r    Útool_use_idr8   éÿÿÿÿÚuserr   r    z

)Ú
isinstanceÚdictr   Úgetattrr(   rj   ÚlistÚjoinrA   ÚloadsÚJSONDecodeErrorÚ	TypeErrorÚdumps)r@   ru   Úsystem_partsÚconversationÚmsgr†   r8   rŒ   Úcontent_blocksÚtcr‚   Útc_idÚ	func_nameÚ	func_argsÚ
input_datar�   Útool_contentÚtool_result_blockr‡   s                      r-   Ú_extract_system_and_messagesz,SnowflakeConfig._extract_system_and_messagesÀ   sU  € ð *,ˆØ*,ˆàó >	HˆCÜ˜#œtÔ$Ø—w‘w˜v rÓ*�Ø"Ÿw™w y°"Ó5‘ä˜s F¨BÓ/�Ü! # y°"Ó5�à�xÒÜ˜g¤sÔ+±Ø ×'Ñ'¨Õ0Ü ¬Õ.Ø ×'Ñ'¨¯	©	Ñ1pÈWÔ1pÓ(pÕqØ˜Ó$Ü6@ÀÄdÔ6K˜SŸW™W \Ô2ÔQXÐY\Ð^jÐlpÓQq�
ÚØ>@�NÙØ&×-Ñ-°vÀwÑ.OÔPØ(ò ˜Ü9CÀBÌÔ9M˜rŸv™v j°"Ô5ÔSZÐ[]Ð_iÐkmÓSn˜Ü4>¸rÄ4Ô4H §¡ t¨RÔ 0ÌgÐVXÐZ^Ð`bÓNc˜Ü<FÀtÌTÔ<R D§H¡H¨V°RÔ$8ÔX_Ð`dÐflÐnpÓXq˜	ä;EÀdÌDÔ;Q˜DŸH™H [°$Ô7ÔW^Ð_cÐepÐrvÓWwð "ð,ÜBLÈYÔX[ÔB\¬¯©°IÔ)>Ðbk˜Jð '×-Ñ-à(2Ø&+Ø(1Ø)3ñ	õðð& !×'Ñ'°ÈÑ(XÖYà ×'Ñ'°ÈÑ(QÖRØ˜’ä3=¸cÄ4Ô3H�C—G‘G˜N¨BÔ/ÌgÐVYÐ[iÐkmÓNnð ô +5°W¼cÔ*B™wÌÏ
É
ÐSZÓH[�à)Ø#/Ø+ñ%Ð!ñ !Ø$ RÑ(¨Ñ0°FÒ:Ü" <°Ñ#3°IÑ#>ÄÔEØ$ RÑ(¨Ò3Ø$ RÑ(¨Ñ3°AÑ6×:Ñ:¸6ÓBÀmÒSà  Ñ$ YÑ/×6Ñ6Ð7HÖIà ×'Ñ'°ÐEVÐDWÑ(XÖYà×#Ñ#¨T¸gÑ$FÖGð}>	Hñ@ BN F§K¡K°Ô$=ÐSWˆØ�|Ð#Ð#øôK !%× 4Ñ 4´iÐ@ò ,Ø)+›Jð,ús   Ç'MÍM ÍM c                 ó¼   — |j                  dd«      xs d}|j                  di «      }t        |«      r| j                  |||||«      S | j                  |||||«      S )Nrf   FÚ
extra_body)ÚpoprY   Ú_transform_request_anthropicÚ_transform_request_openai)r@   r6   ru   ro   rp   rt   rf   rª   s           r-   Útransform_requestz!SnowflakeConfig.transform_request  sk   € ð .×1Ñ1°(¸EÓBÒKÀeˆØ+×/Ñ/°¸bÓAˆ
ä˜EÔ"Ø×4Ñ4°U¸HÀoÐW]Ð_iÓjÐjØ×-Ñ-¨e°X¸ÐPVÐXbÓcÐcr,   rª   c                 óš   — |j                  dd«      }|j                  dd«      }|xs |}|j                  d«      ||dœ|¥|¥}	|�||	d<   |	S )z-OpenAI format for /chat/completions endpoint.rc   Nrd   rP   ©r6   ru   rf   )r«   rW   )
r@   r6   ru   ro   rf   rª   rc   rd   Úresolved_maxÚbodys
             r-   r­   z)SnowflakeConfig._transform_request_openai  s~   € ð ,×/Ñ/°¸dÓCˆ
Ø'6×':Ñ':Ð;RÐTXÓ'YÐØ3ÒA°zˆð ×'Ñ'¨Ó5Ø Øñ
ð ð	
ð
 ð
ˆð Ð#Ø,8ˆDÐ(Ñ)àˆr,   rh   c                 ó  — t        |t        «      r ddiddiddidœ}|j                  |ddi«      S t        |t        «      r=|j                  d«      dk(  r'|j                  di «      }d|j                  dd	«      d
œS |S ddiS )a$  
        Convert tool_choice from OpenAI format to Anthropic format.

        OpenAI string values: "auto", "required", "none"
        OpenAI dict: {"type": "function", "function": {"name": "..."}}
        Anthropic: {"type": "auto"}, {"type": "any"}, {"type": "tool", "name": "..."}
        r    ÚautorX   Únone)r´   Úrequiredrµ   ry   r�   r#   rz   )r    r#   )r”   r(   r   r•   )r@   rh   Úmappingr‚   s       r-   Ú#_transform_tool_choice_to_anthropicz3SnowflakeConfig._transform_tool_choice_to_anthropic7  s–   € ô �k¤3Ô'à Ð(Ø# U˜OØ Ð(ñˆGð
 —;‘;˜{¨V°VÐ,<Ó=Ð=Ü˜¤TÔ*Ø�‰˜vÓ&¨*Ò4Ø)Ÿo™o¨j¸"Ó=�Ø &°·±¸ÀÓ0DÑEÐEØÐØ˜ÐÐr,   c                 ó*  — | j                  |«      \  }}d|v r| j                  |d   «      |d<   d|v r| j                  |d   «      |d<   |j                  dd«      }|r	d|vr||d<   |j	                  d«      }	|	||dœ|¥|¥}
|�||
d<   d|
vrd	|
d<   |
S )
z1Anthropic Messages format for /messages endpoint.rg   rh   rd   Nrc   rP   r°   r‡   i   )r¨   r„   r¸   r«   rW   )r@   r6   ru   ro   rf   rª   r‡   rž   rd   Ú
model_namer²   s              r-   r¬   z,SnowflakeConfig._transform_request_anthropicM  sç   € ð  $×@Ñ@ÀÓJÑˆ�à�oÑ%Ø'+×'IÑ'IÈ/ÐZaÑJbÓ'cˆO˜GÑ$à˜OÑ+Ø-1×-UÑ-UÐVeÐfsÑVtÓ-uˆO˜MÑ*à'6×':Ñ':Ð;RÐTXÓ'YÐÙ  \¸Ñ%HØ,AˆO˜LÑ)à!×.Ñ.¨|Ó<ˆ
ð  Ø$Øñ*
ð ð	*
ð
 ð*
ˆð ÐØ#ˆD�‰Nà˜tÑ#Ø!%ˆD�Ñàˆr,   Úraw_responseÚmodel_responseÚlogging_objÚrequest_dataÚencodingÚ	json_modec                 óp   — t        |«      r| j                  ||||||«      S | j                  ||||||«      S r>   )rY   Ú_transform_response_anthropicÚ_transform_response_openai)r@   r6   r»   r¼   r½   r¾   ru   ro   rp   r¿   rn   rÀ   s               r-   Útransform_responsez"SnowflakeConfig.transform_responset  sM   € ô ˜EÔ"Ø×5Ñ5Ø�| ^°[À,ÐPXóð ð ×.Ñ.¨u°lÀNÐT_ÐamÐowÓxÐxr,   c                 ó²   — t        |«      }|j                  |d|d|i¬«       t        di |¤Ž}d|j                  xs dz   |_        |�||j                  d<   |S )z0Parse standard OpenAI chat completions response.rz   Úcomplete_input_dict©r$   rn   Úoriginal_responseÚadditional_argsrP   r6   r+   )rK   Ú	post_callr   r6   Ú_hidden_params)	r@   r6   r»   r¼   r½   r¾   ru   Úresponse_jsonÚreturned_responses	            r-   rÃ   z*SnowflakeConfig._transform_response_openaiˆ  sy   € ô  9¸ÓFˆà×ÑØØØ+Ø2°LÐAð	 	ô 	
ô $1Ñ#A°=Ñ#AÐØ".Ð2C×2IÑ2IÒ2OÈRÑ"PÐÔàÐØ8=Ð×,Ñ,¨WÑ5à Ð r,   c                 óÞ  — t        |«      }|j                  |d|d|i¬«       d}g }	|j                  dg «      D ]¬  }
|
j                  d«      dk(  r||
j                  dd«      z  }Œ-|
j                  d«      dk(  sŒB|	j                  t	        |
j                  dd«      d	t        |
j                  d
d«      t        j                  |
j                  di «      «      ¬«      ¬«      «       Œ® dddddœ}|j                  |j                  dd«      d«      }t        |xs dd¬«      }|	r|	|_	        t        |d|¬«      }|j                  di «      }t        |j                  dd«      |j                  dd«      |j                  dd«      |j                  dd«      z   ¬«      }|g|_        ||_        d|j                  d|«      z   |_        |j                  dd«      |_        |�||j                   d<   |S )z5Parse Anthropic Messages response into OpenAI format.rz   rÆ   rÇ   r8   r    r!   rŽ   r"   ry   r#   r$   ©r#   r�   )r"   r    ry   ÚstopÚlengthrŒ   ©Úend_turnrc   rŽ   Ústop_sequencer7   rÓ   Nr‹   )r8   r†   r   )Úfinish_reasonÚindexÚmessager9   r1   r2   ©Úprompt_tokensÚcompletion_tokensÚtotal_tokensrP   r6   )rN   rÊ   r   rj   r   r   rA   rœ   r   rŒ   r   r   Úchoicesr9   r6   r"   rË   )r@   r6   r»   r¼   r½   r¾   ru   rÌ   Útext_contentrŒ   ÚblockÚ_stop_reason_maprÕ   r×   ÚchoiceÚ
usage_datar9   s                    r-   rÂ   z-SnowflakeConfig._transform_response_anthropic£  s  € ô  1°Ó>ˆà×ÑØØØ+Ø2°LÐAð	 	ô 	
ð ˆØˆ
à"×&Ñ& y°"Ó5ò 	ˆEØ�y‰y˜Ó  FÒ*Ø §	¡	¨&°"Ó 5Ñ5‘Ø—‘˜6Ó" jÓ0Ø×!Ñ!Ü1Ø Ÿ9™9 T¨2Ó.Ø'Ü!)Ø!&§¡¨6°2Ó!6Ü&*§j¡j°·±¸7ÀBÓ1GÓ&Hô"ôõ	ð		ð  Ø"Ø$Ø#ñ	#
Ðð  0×3Ñ3°M×4EÑ4EÀmÐU_Ó4`ÐbhÓiˆä ¨Ò)=¸ÀKÔPˆÙØ!+ˆGÔäØ'ØØô
ˆð *×-Ñ-¨g°rÓ:ˆ
ÜØ$Ÿ.™.¨¸Ó;Ø(Ÿn™n¨_¸aÓ@Ø#Ÿ™¨¸Ó:¸Z¿^¹^ÈOÐ]^Ó=_Ñ_ô
ˆð #) ˆÔØ$ˆÔØ+¨m×.?Ñ.?ÀÈÓ.OÑOˆÔØ)×-Ñ-¨d°BÓ7ˆÔàÐØ5:ˆN×)Ñ)¨'Ñ2àÐr,   Ústreaming_responseÚsync_streamÚSnowflakeStreamingHandlerc                 ó   — t        |||¬«      S )N)râ   rã   rÀ   )rä   )r@   râ   rã   rÀ   s       r-   Úget_model_response_iteratorz+SnowflakeConfig.get_model_response_iteratorë  s   € ô )Ø1Ø#Øô
ð 	
r,   r>   )NN©F) r%   r&   r'   rC   Úclassmethodr^   r(   r—   rl   r•   Úboolrs   r   rw   r„   Útupler¨   r®   r­   r   r¸   r¬   ÚhttpxÚResponser   ÚLiteLLMLoggingObjr*   rÄ   rÃ   rÂ   ræ   Ú__classcell__©r`   s   @r-   r[   r[   `   s¿  ø„ ñ
ð ó$ó ð$ð°ð ¸¸c¹ó ð* #ñ8à˜‘*ð8ð �t‘ð8ð ð	8ð
 ð8ð ð8ð �t‘ð8ð 
ó8ð* #Ø#ñàðð ðð Ð'Ñ(ð	ð
 ðð ðð �t‘ðð ˜‘*ðð 
õð.°4¸±:ð À$ÀtÁ*ó ð8L$°TÐ:JÑ5Kð L$ÐPUÐVYÐ\`ÑV`ÐbfÐgkÑblÐVlÑPmó L$ð\dàðdð Ð'Ñ(ðdð ð	dð
 ðdð ðdð 
ódðàðð Ð'Ñ(ðð ð	ð
 ðð ðð 
óð4 ¸sð  ÀtÈCÐQTÈHÁ~ó  ð,%àð%ð Ð'Ñ(ð%ð ð	%ð
 ð%ð ð%ð 
ó%ðd #Ø!%ñyàðyð —n‘nðyð &ð	yð
 'ðyð ðyð Ð'Ñ(ðyð ðyð ðyð ðyð �t‘ðyð ˜$‘;ðyð 
óyð(!àð!ð —n‘nð!ð &ð	!ð
 'ð!ð ð!ð Ð'Ñ(ð!ð 
ó!ð6FàðFð —n‘nðFð &ð	Fð
 'ðFð ðFð Ð'Ñ(ðFð 
óFðX "'ñ	

à"ð

ð ð

ð ˜$‘;ð	

ð
 
%÷

r,   r[   c                   ój   ‡ — e Zd ZdZ	 ddedededz  fˆ fd„Zdedefd	„Z	dedefd
„Z
dedefd„Zˆ xZS )rä   zÏ
    Parse streaming events from both Snowflake endpoints.

    - /chat/completions: OpenAI SSE format (has "choices" key)
    - /messages: Anthropic SSE format (has "type" key like content_block_delta)
    râ   rã   rÀ   Nc                 ó`   •— t         ‰| �  ||¬«       d| _        d| _        d| _        d| _        y )N)râ   rã   r   rz   )r]   Ú__init__Ú_tool_indexÚ_tool_idÚ
_tool_nameÚ_input_tokens)r@   râ   rã   rÀ   r`   s       €r-   rò   z"SnowflakeStreamingHandler.__init__   s6   ø€ ô 	‰ÑÐ,>ÈKÐÔXØˆÔØˆŒØˆŒØˆÕr,   Úchunkr<   c                 óN   — d|v r| j                  |«      S | j                  |«      S )NrÜ   )Ú_parse_openai_chunkÚ_parse_anthropic_chunk)r@   r÷   s     r-   Úchunk_parserz&SnowflakeStreamingHandler.chunk_parser  s,   € Ø˜ÑØ×+Ñ+¨EÓ2Ð2Ø×*Ñ*¨5Ó1Ð1r,   c           
      ó  — |j                  dg «      }|st        dddd dd ¬«      S |d   }|j                  di «      }|j                  d«      xs d}|j                  d«      xs d}d }|j                  d	«      }|ri|d   }	|	j                  d
i «      }
t        |	j                  dd«      d
|
j                  dd«      |
j                  dd«      dœ|	j                  dd«      ¬«      }t        ||dk7  |d |j                  dd«      |¬«      S )NrÜ   rz   Fr   ©r!   Úis_finishedrÕ   r9   rÖ   rŽ   ÚdeltarÕ   r8   rŒ   ry   r"   r#   r�   rÏ   rÖ   ©r"   r    ry   rÖ   )r   r   r   )r@   r÷   rÜ   rà   rÿ   rÕ   r!   rŽ   rŒ   r¡   r‚   s              r-   rù   z-SnowflakeStreamingHandler._parse_openai_chunk  s!  € ØŸ™ 9¨bÓ1ˆÙÜ(ØØ!Ø ØØØôð ð   ™
ˆØ—z‘z '¨2Ó.ˆØ%Ÿz™z¨/Ó:Ò@¸bˆØ—i‘i 	Ó*Ò0¨bˆàˆØ!ŸI™I lÓ3ˆ
ÙØ" 1™ˆBØŸ&™& ¨RÓ0ˆDÜ2Ø—6‘6˜$ Ó#Øà ŸH™H V¨RÓ0Ø!%§¡¨+°rÓ!:ñð —f‘f˜W aÓ(ôˆHô %ØØ%¨Ñ+Ø'ØØ—*‘*˜W aÓ(Øô
ð 	
r,   c                 óŠ  — |j                  dd«      }|dk(  rL|j                  di «      }|j                  di «      }|j                  dd«      | _        t        dddd dd ¬	«      S |d
k(  r¿|j                  di «      }|j                  dd«      }|dk(  r1t        |j                  dd«      ddd |j                  dd«      d ¬	«      S |dk(  �rët        dddd |j                  dd«      t        | j                  d| j
                  |j                  dd«      dœ| j                  ¬«      ¬	«      S |dk(  r»|j                  di «      }|j                  d«      dk(  �r`|j                  dd«      | _        |j                  dd«      | _        |j                  dd«      | _        t        dddd |j                  dd«      t        | j                  d| j
                  ddœ| j                  ¬«      ¬	«      S |dk(  r±|j                  di «      }|j                  dd«      }|j                  di «      }dddddœ}	d }
|s| j                  rC|j                  dd«      }| j                  xs |j                  dd«      }t        ||||z   ¬ «      }
t        dd!|	j                  |d«      |
dd ¬	«      S |d"k(  rt        dd!dd dd ¬	«      S t        dddd dd ¬	«      S )#Nr    rz   Úmessage_startr×   r9   r1   r   Frý   Úcontent_block_deltarÿ   Ú
text_deltar!   rÖ   Úinput_json_deltary   Úpartial_jsonrÏ   r   Úcontent_block_startÚcontent_blockrŽ   r"   r#   Úmessage_deltar7   rÐ   rÑ   rŒ   rÒ   r2   rØ   TÚmessage_stop)r   rö   r   r   rô   rõ   ró   r   )r@   r÷   Ú
event_typer×   rá   rÿ   Ú
delta_typer  r7   Ú	_stop_mapr9   Úoutput_tÚinput_ts                r-   rú   z0SnowflakeStreamingHandler._parse_anthropic_chunk:  s  € Ø!ŸI™I f¨bÓ1ˆ
à˜Ò(Ø"ŸY™Y y°"Ó5ˆGØ Ÿ™ W¨bÓ1ˆJØ!+§¡°ÀÓ!BˆDÔÜ(ØØ!Ø ØØØôð ð Ð0Ò0Ø—I‘I˜g rÓ*ˆEØ %§	¡	¨&°"Ó 5ˆJà˜\Ò)Ü,ØŸ™ 6¨2Ó.Ø %Ø"$ØØŸ)™) G¨QÓ/Ø!ôð ð Ð1Ó1Ü,ØØ %Ø"$ØØŸ)™) G¨QÓ/Ü8ØŸ=™=Ø'à$(§O¡OØ).¯©°>À2Ó)Fñ"ð #×.Ñ.ôôð ð" Ð0Ò0Ø#(§9¡9¨_¸bÓ#AˆMØ× Ñ  Ó(¨JÓ6Ø -× 1Ñ 1°$¸Ó ;�”Ø"/×"3Ñ"3°F¸BÓ"?�”Ø#(§9¡9¨W°aÓ#8�Ô Ü,ØØ %Ø"$ØØŸ)™) G¨QÓ/Ü8ØŸ=™=Ø'Ø*.¯/©/ÈÑ!KØ"×.Ñ.ô	ôð ð ˜?Ò*Ø—I‘I˜g rÓ*ˆEØ!&§¡¨=¸"Ó!=ˆKØŸ™ 7¨BÓ/ˆJà"Ø&Ø(Ø!'ñ	 ˆIð ˆEÙ˜T×/Ò/Ø",§.¡.°À!Ó"D�Ø!%×!3Ñ!3Ò!X°z·~±~ÀnÐVWÓ7X�Ü0Ø")Ø&.Ø!(¨8Ñ!3ô�ô
 )ØØ Ø'Ÿm™m¨K¸Ó@ØØØôð ð ˜>Ò)Ü(ØØ Ø$ØØØôð ô %ØØØØØØô
ð 	
r,   rç   )r%   r&   r'   rC   r*   ré   rò   r•   r   rû   rù   rú   rî   rï   s   @r-   rä   rä   ø  sr   ø„ ñð "'ñ	
à"ð
ð ð
ð ˜$‘;õ	
ð2 $ð 2Ð+@ó 2ð
'
¨ð '
Ð2Gó '
ðRp
¨Dð p
Ð5J÷ p
r,   rä   )4rC   rA   Úcollections.abcr   r   Útypingr   r   r   r   r	   rë   Útyping_extensionsr
   Úlitellm.types.llms.openair   r   Úlitellm.types.utilsr   r   r   r   r   r   r   r   Úbase_llm.base_model_iteratorr   Úopenai_like.chat.transformationr   Úutilsr   Ú*litellm.litellm_core_utils.litellm_loggingr   Ú_LiteLLMLoggingObjrí   r   r)   r   r   r0   r5   r;   rE   r(   r*   rK   rN   ré   rY   r[   rä   r+   r,   r-   ú<module>r     s  ðòó ß -ß AÕ Aã Ý &ç S÷	÷ 	ó 	õ FÝ >Ý 'áÝXà*ÑàÐà'Ð �5Ó 'ð!Ð ˜ó ô*˜Y¨eõ *ô!˜9¨Eõ !ô
* °%õ *ô0˜xô 0ô6˜ô 6ðÐ(@ð ÀWÈSÐRXÈ[ÑEYó ðÐ 1ð Ð6Pó ðC˜Cð C Dó CôU
Ð)¨?ô U
ôpr
Ð 9õ r
r,   