Ë
    uPêjrÜ  ã                   óœ  — U d Z ddlZddlmZmZ ddlmZ ddlmZ ddl	m
Z
mZmZmZ ddlm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mZmZmZmZm Z m!Z! ddl"m#Z# ddl$m%Z%m&Z& ddl'm(Z(m)Z)m*Z*m+Z+ ddl,m-Z-m.Z.m/Z/m0Z0 e
rddl1m2Z2m3Z3 ddl4m5Z6 ddl7m8Z8 ddl9m:Z:  edd¬«       G d„ d«      «       Z; edd¬«       G d„ d«      «       Z< edd¬«       G d„ d«      «       Z= edd¬«       G d„ d«      «       Z>e;e<z  e=z  e>z  Z? edd¬«       G d„ d «      «       Z@ edd¬«       G d!„ d"«      «       ZA eAd#d#¬$«      ZBeeCd%<    G d&„ d'e«      ZDy)(aÛ  
Anthropic Message Handler for Unified Guardrails

This module provides a class-based handler for Anthropic-format messages.
The class methods can be overridden for custom behavior.

Pattern Overview:
-----------------
1. Extract text content from messages/responses (both string and list formats)
2. Create async tasks to apply guardrails to each text segment
3. Track mappings to know where each response belongs
4. Apply guardrail responses back to the original structure
é    N)ÚMappingÚSequence)Údeepcopy)Ú	dataclass)ÚTYPE_CHECKINGÚAnyÚFinalÚcast)Úassert_never)Úverbose_proxy_logger)ÚAnthropicConfig)ÚLiteLLMAnthropicMessagesAdapterÚis_provider_native_tool_dict)ÚBaseTranslation)Úanthropic_tool_nameÚanthropic_tool_namesÚ.effective_scan_only_tool_results_for_guardrailÚ+effective_skip_system_message_for_guardrailÚ)effective_skip_tool_message_for_guardrailÚ!merge_guardrailed_scoped_messagesÚ'merge_returned_tools_into_request_toolsÚ!scoped_structured_message_indices)Ú"AnthropicPassthroughLoggingHandler)ÚAllAnthropicToolsValuesÚAnthropicMessagesRequest)ÚAllMessageValuesÚChatCompletionRequestÚChatCompletionToolCallChunkÚChatCompletionToolParam)ÚChatCompletionMessageToolCallÚChoicesÚGenericGuardrailAPIInputsÚModelResponse)ÚCustomGuardrailÚModifyResponseException)ÚLogging)ÚUserAPIKeyAuth©ÚAnthropicMessagesResponseT)ÚfrozenÚslotsc                   ó   — e Zd ZU eed<   y)ÚMessageContentTargetÚmsg_idxN©Ú__name__Ú
__module__Ú__qualname__ÚintÚ__annotations__© ó    ú~/home/oem/CyberBrain26-unified/.venv/lib/python3.12/site-packages/litellm/llms/anthropic/chat/guardrail_translation/handler.pyr-   r-   H   s   … à„Lr6   r-   c                   ó"   — e Zd ZU eed<   eed<   y)ÚContentBlockTextTargetr.   Úcontent_idxNr/   r5   r6   r7   r9   r9   M   ó   … àƒLØÔr6   r9   c                   ó"   — e Zd ZU eed<   eed<   y)ÚToolResultStringTargetr.   r:   Nr/   r5   r6   r7   r=   r=   S   r;   r6   r=   c                   ó,   — e Zd ZU eed<   eed<   eed<   y)ÚToolResultBlockTextTargetr.   r:   Ú	block_idxNr/   r5   r6   r7   r?   r?   Y   s   … àƒLØÓØ„Nr6   r?   c                   ó"   — e Zd ZU eed<   eed<   y)ÚScannedTextÚtextÚtargetN)r0   r1   r2   Ústrr4   ÚInputWriteBackTargetr5   r6   r7   rB   rB   e   s   … à
ƒIØ Ô r6   rB   c                   ó6   — e Zd ZU eedf   ed<   eedf   ed<   y)ÚExtractedInput.ÚscannedÚimagesN)r0   r1   r2   ÚtuplerB   r4   rE   r5   r6   r7   rH   rH   k   s    … à�; Ð#Ñ$Ó$Ø�#�s�(‰OÔr6   rH   r5   ©rI   rJ   ÚEMPTY_EXTRACTED_INPUTc                   ó®  ‡ — e Zd ZdZˆ fd„Zedee   dedz  de	dz  fd„«       Z
	 	 dRdd	d
edee   dz  dee   fd„Zdd	dee   fd„Zdd	dee   dee   fd„Zedee   deedz  edz  f   fd„«       Zededeeeef      fd„«       Zdedefd„Zdedee   dz  fd„Z	 dSdedddddefd„Zdededz  fd„Zedeeef   deeef   dz  fd„«       Zedeeef   dee   deddfd„«       Zedededefd „«       Zededefd!„«       Z ed"edefd#„«       Z!e	 	 dTded"eded$eddf
d%„«       Z"ede#eef   d&ede$fd'„«       Z%dedee   fd(„Z&e'	 	 	 dUde#eef   d&ed)ed*ed+ede$fd,„«       Z(e'	 dVd-e#eef   d&ed.ed*ed+ede$fd/„«       Z)e'd-e#eef   d&ed.ede$fd0„«       Z*ed1e#eef   deed2f   fd3„«       Z+d4eeeef      d5ee   d6ee,d2f   ddfd7„Z-	 	 	 dWd8d9ddddd:d;dedz  dd9fd<„Z.	 	 	 dWdee   ddddd:d;dedz  dee   fd=„Z/dedz  d8ed:d;d>edef
d?„Z0ed8edee   fd@„«       Z1dAee   dBee   dCee   dDeeeedz  f      dEedF   ddfdG„Z2edBee   dCee   dEedF   d8eddHf
dI„«       Z3dee   defdJ„Z4dKedefdL„Z5dee   defdM„Z6d8d9defdN„Z7	 dSdOeeef   d.edBee   dCee   dDeeeedz  f      dEee8   dz  ddfdP„Z9d8d9d5ee   dDeeeedz  f      ddfdQ„Z:ˆ xZ;S )XÚAnthropicMessagesHandlerzàProcess Anthropic messages with guardrails.

    In-sequence system entries are untrusted client input. This handler scans and preserves
    them through guardrail rewrites; downstream provider handling is out of scope.
    c                 ó@   •— t         ‰| �  «        t        «       | _        y ©N)ÚsuperÚ__init__r   Úadapter)ÚselfÚ	__class__s    €r7   rS   z!AnthropicMessagesHandler.__init__{   s   ø€ Ü‰ÑÔÜ6Ó8ˆ�r6   Úresponses_so_farÚrequest_dataNÚreturnc                 óÐ   — t        d„ | D «       «      }|sy 	 t        j                  |t        |xs i j	                  d«      xs d«      ¬«      S # t
        t        t        f$ r Y y w xY w)Nc              3   óN   K  — | ]  }t        |t        t        f«      sŒ|–— Œ y ­wrQ   )Ú
isinstancerE   Úbytes)Ú.0Úresponses     r7   ú	<genexpr>zKAnthropicMessagesHandler._build_streaming_usage_response.<locals>.<genexpr>„   s!   è ø€ Òn¨8Ì:ÐV^ÔadÔfkÐ`lÕKmœhÑnùs   ‚%ž%ÚmodelÚ )Ú
all_chunksra   )rK   r   Ú&_build_usage_only_response_from_chunksrE   ÚgetÚAttributeErrorÚ	TypeErrorÚ
ValueError)rW   rX   Úchunkss      r7   Ú_build_streaming_usage_responsez8AnthropicMessagesHandler._build_streaming_usage_response   sn   € ô
 ÑnÐ7GÔnÓnˆÙØð	Ü5×\Ñ\Ø!Ü˜<Ò-¨2×2Ñ2°7Ó;ÒA¸rÓBôð øô ¤	¬:Ð6ò 	Ùð	ús   —6A ÁA%Á$A%Úexcr%   Ústream_startedc                 óT   — |r| j                  ||xs g «      S | j                  |«      S )aK  
        Build an Anthropic SSE sequence delivering the guardrail block message
        and terminating the stream cleanly.

        - ``stream_started`` False (buffered / pre-stream): nothing has been
          sent, so emit a complete standalone message (message_start ->
          content_block_* -> message_delta -> message_stop) via
          FakeAnthropicMessagesStreamIterator, the same converter the
          /v1/messages pre-stream block handler uses.
        - ``stream_started`` True (sampling / detect-only end-of-stream): real
          chunks were already sent, so *continue* the in-progress message --
          close the open content block, append the block message as a new text
          block, then end the message. Emitting a second ``message_start`` here
          would make Anthropic clients reject the stream.
        )Ú_block_continuation_chunksÚ_standalone_block_chunks)rU   rk   rl   rW   s       r7   Úbuild_block_sse_chunksz/AnthropicMessagesHandler.build_block_sse_chunks�   s1   € ñ* Ø×2Ñ2°3Ð8HÒ8NÈBÓOÐOØ×,Ñ,¨SÓ1Ð1r6   c                 óä   — dd l }ddlm} ddlm} ddlm}  |d|j                  «       › �ddd|j                  d	œg|j                  d
 |t        |dd «      «      ¬«      }t         ||¬«      «      S )Nr   )Ú#FakeAnthropicMessagesStreamIterator©Úblocked_response_usager(   Úmsg_ÚmessageÚ	assistantrC   ©ÚtyperC   Úend_turnÚoriginal_response)Úidry   ÚroleÚcontentra   Ústop_reasonÚusage©r_   )ÚuuidÚNlitellm.llms.anthropic.experimental_pass_through.messages.fake_stream_iteratorrr   Ú1litellm.llms.base_llm.guardrail_translation.utilsrt   Úlitellm.types.utilsr)   Úuuid4rv   ra   ÚgetattrÚlist)rU   rk   r‚   rr   rt   r)   Úblock_responses          r7   ro   z1AnthropicMessagesHandler._standalone_block_chunks¨   ss   € Ûõ	
õ	
õ 	Bá 9Ø�d—j‘j“l�^Ð$ØØØ$¨c¯k©kÑ:Ð;Ø—)‘)Ø"Ù(¬°Ð6IÈ4Ó)PÓQô!
ˆô Ñ7ÀÔPÓQÐQr6   c                 óˆ  — ddl m} dt        dt        dt        fd„} |t        |dd«      «      d	   }| j                  |«      \  }}|�|d
z   nd}g }	|�|	j                   |dd|dœ«      «       |	 |dd|dddœdœ«       |dd|d|j                  dœdœ«       |dd|dœ«       |dddddœd	|idœ«       |dddi«      gz  }	|	S )z¸Continue an already-started message: close the open content block,
        append the block message as a new text block, then end the message --
        without a second message_start.r   rs   Ú
event_typeÚpayloadrY   c                 óV   — d| › dt        j                  |«      › d�j                  «       S )Nzevent: z
data: ú

)ÚjsonÚdumpsÚencode)r‹   rŒ   s     r7   Ú_ssezAAnthropicMessagesHandler._block_continuation_chunks.<locals>._sseÇ   s*   € Ø˜Z˜L¨´·±¸GÓ1DÐ0EÀTÐJ×QÑQÓSÐSr6   r{   NÚoutput_tokensé   Úcontent_block_stop)ry   ÚindexÚcontent_block_startrC   rb   rx   )ry   r–   Úcontent_blockÚcontent_block_deltaÚ
text_delta)ry   r–   ÚdeltaÚmessage_deltarz   )r   Ústop_sequence)ry   r›   r€   Úmessage_stopry   )	r„   rt   rE   Údictr]   r‡   Ú_content_block_stateÚappendrv   )
rU   rk   rW   rt   r’   r“   Ú
open_indexÚ	max_indexÚ	new_indexri   s
             r7   rn   z3AnthropicMessagesHandler._block_continuation_chunks¾   s-  € õ
	
ð	TœSð 	T¬4ð 	T´Eó 	Tñ  6´g¸cÐCVÐX\Ó6]Ó^Ð_nÑoˆØ $× 9Ñ 9Ð:JÓ KÑˆ
�IØ.7Ð.C˜I¨šMÈˆ	Ø ˆØÐ!Ø�M‰M™$Ð3Ð>RÐ]gÑ5hÓiÔjØÙØ%à1Ø&Ø.4¸bÑ%Añóñ Ø%à1Ø&Ø&2¸C¿K¹KÑHñóñ Ð%Ð0DÈyÑ'YÓZÙØà+Ø-7È$ÑOØ-¨}Ð=ñóñ � &¨.Ð!9Ó:ð5
ñ 	
ˆð8 ˆr6   c                 ód  — t        «       }d}| D ]�  }t        j                  |«      D ]s  }|j                  d«      }|j                  d«      }t	        |t
        «      sŒ6|dk(  r"|j                  |«       |€|nt        ||«      }Œ]|dk(  sŒc|j                  |«       Œu Œ� |rt        |«      nd}||fS )a‰  From the SSE chunks already sent to the client, return (open
        content-block index or None, highest content-block index seen or None).

        A single streamed item may bundle multiple SSE events (raw bytes) or be
        an already-parsed event dict, so every event across every item is
        considered -- matching how ``get_streaming_string_so_far`` reads the
        same stream.Nry   r–   r—   r•   )	ÚsetrO   Ú_iter_sse_eventsre   r\   r3   ÚaddÚmaxÚdiscard)rW   Úopen_indicesr£   ÚitemÚdatar‹   r–   r¢   s           r7   r    z-AnthropicMessagesHandler._content_block_stateî   s¾   € ô ),«ˆØ $ˆ	Ø$ò 
	0ˆDÜ0×AÑAÀ$ÓGò 	0�Ø!ŸX™X fÓ-�
ØŸ™ Ó)�Ü! %¬Ô-ØØÐ!6Ò6Ø ×$Ñ$ UÔ+Ø)2Ð):¡ÄÀIÈuÓ@U‘IØÐ#7Ó7Ø ×(Ñ(¨Õ/ñ	0ð
	0ñ 2>œC Ô-À4ˆ
Ø˜9Ð$Ð$r6   r¬   c                 óô  — t        | t        «      r| gS t        | t        t        f«      sg S g }| j	                  dd¬«      j                  d«      D ]Œ  }|j                  d«      D ]v  }|j                  «       }|j                  d«      sŒ%	 t        j                  |t        d«      d j                  «       «      }t        |t        «      sŒf|j                  |«       Œx ŒŽ |S # t        j                  $ r Y Œ’w xY w)a  Yield the event-data dicts in one stream chunk.

        Handles both formats this stream can carry (see
        ``get_streaming_string_so_far``): raw SSE ``bytes`` -- which may bundle
        several events separated by a blank line -- and an already-parsed event
        ``dict``.úutf-8Úreplace)ÚerrorsrŽ   ú
údata:N)r\   rŸ   r]   Ú	bytearrayÚdecodeÚsplitÚstripÚ
startswithr�   ÚloadsÚlenÚJSONDecodeErrorr¡   )r¬   ÚeventsÚblockÚlineÚparseds        r7   r§   z)AnthropicMessagesHandler._iter_sse_events	  sí   € ô �dœDÔ!Ø�6ˆMÜ˜$¤¬	Ð 2Ô3ØˆIØ13ˆØ—[‘[ °�[Ó;×AÑAÀ&ÓIò 	*ˆEØŸ™ DÓ)ò *�Ø—z‘z“|�Ø—‘ wÔ/ØðÜhl×hrÑhrØœS ›\˜^Ð,×2Ñ2Ó4ói�Fô
 ˜f¤dÕ+Ø—M‘M &Õ)ñ*ð	*ð ˆøô	 ×+Ñ+ò Ùðús   Â
/C!Ã!C7Ã6C7r­   c                 óx   — t        «       j                  t        t        |j	                  «       «      ¬«      \  }}|S )z=Translate Anthropic request to OpenAI chat completion format.)Úanthropic_message_request)r   Útranslate_anthropic_to_openair
   r   Úcopy)rU   r­   Ú"chat_completion_compatible_requestÚ_tool_name_mappings       r7   Ú_translate_to_openaiz-AnthropicMessagesHandler._translate_to_openai%  s?   € ô
 ,Ó-×KÑKÜ&*Ô+CÀTÇYÁYÃ[Ó&Qð Ló 
ñ	
Ø.Øð 2Ð1r6   c                 ó¦   — |j                  d«      }|€y| j                  |«      }t        t        t           |j                  dg «      «      }|r|S dS )z¨
        Convert Anthropic messages request data to OpenAI-spec structured messages.

        Uses the Anthropic-to-OpenAI adapter to translate message format.
        ÚmessagesN)re   rÆ   r
   rˆ   r   )rU   r­   rÈ   rÄ   Úresults        r7   Úget_structured_messagesz0AnthropicMessagesHandler.get_structured_messages/  s^   € ð Ÿ(™( :Ó.ˆØÐØØ48×4MÑ4MÈdÓ4SÐ*ÜÜÔ!Ñ"Ø.×2Ñ2°:¸rÓBó
ˆñ  ˆvÐ) TÐ)r6   Úguardrail_to_applyr$   Úlitellm_logging_objzLiteLLMLoggingObj | Nonec              ƒ   óp  ‡ ‡#‡$‡%K  — |j                  d«      }|€|S t        |«      Š$t        |«      Š%t        |«      Š#|j	                  «       D ��ci c]  \  }}|dk7  sŒ||“Œ }}}‰ j                  |«      }t        t        t           |j                  dg «      «      }	t        d„ |	D «       «      }
‰$rdn‰ j                  |«      }|�|	j                  d|«       t        |	‰#d‰%¬«      }|D �cg c]  }|	|   ‘Œ	 }}‰#rg n*|j                  dg «      D �cg c]  }t        |«      s|‘Œ c}}t        ˆ#ˆ ˆ$ˆ%fd	„t        |«      D «       «      }t        d
„ |D «       «      }|D �cg c]  }|j                   ‘Œ }}|D ��cg c]  }|j"                  D ]  }|‘Œ Œ }}}|�ret%        |¬«      }|r||d<   |r||d<   |}|r||d<   |j                  d«      }|r||d<   |j'                  ||d|¬«      ƒ d{  –—† }|j                  dg «      }|j                  d«      }|��t)        «       }g }|D ]*  }|j+                  |«      \  } }!| €Œ|j-                  | «       Œ, ‰#r!t/        |j                  d«      |t0        ¬«      ng d„ |j                  d«      xs g D «       ¢|¢|d<   |j                  d«      }"|"�8|"|ur4‰ j3                  ||j5                  «       r|"nt7        |	||"¬«      ||
¬«       n‰ j9                  |||¬«      ƒ d{  –—†  t;        j<                  d|«       |S c c}}w c c}w c c}w c c}w c c}}w 7 �ŒE7 Œ:­w)zP
        Process input messages by applying guardrails to text content.
        rÈ   NÚsystemc              3   óz   K  — | ]3  }t        |j                  d «      xs d«      j                  «       dk(  –— Œ5 y­w)r}   rb   rÎ   N)rE   re   Úlower©r^   rv   s     r7   r`   zBAnthropicMessagesHandler.process_input_messages.<locals>.<genexpr>\  s6   è ø€ ò 0
ØCJŒC�—‘˜FÓ#Ò) rÓ*×0Ñ0Ó2°hÕ>ñ0
ùs   ‚9;r   F)Úscan_only_tool_resultsÚskip_systemÚ	skip_toolÚtoolsc              3   óP   •K  — | ]  \  }}‰j                  ||‰‰‰¬ «      –— Œ y­w))rv   r.   Úskip_system_messageÚskip_tool_messagerÒ   N)Ú_extract_input_text_and_images)r^   r.   rv   rÒ   rU   rÓ   rÔ   s      €€€€r7   r`   zBAnthropicMessagesHandler.process_input_messages.<locals>.<genexpr>w  s>   øè ø€ ò 	!
ñ !�˜ð ×/Ñ/ØØØ$/Ø"+Ø'=ð 0÷ ñ	!
ùs   ƒ#&c              3   óB   K  — | ]  }|j                   D ]  }|–— Œ Œ y ­wrQ   ©rI   )r^   Úone_messager¬   s      r7   r`   zBAnthropicMessagesHandler.process_input_messages.<locals>.<genexpr>�  s"   è ø€ Òa¨È[×M`ÑM`ÒaÀTœtÐa˜tÑaùó   ‚©ÚtextsrJ   Ústructured_messagesra   Úrequest©ÚinputsrX   Ú
input_typeÚlogging_objrß   )Úrequest_toolsÚreturned_toolsÚ	tool_namec              3   ó8   K  — | ]  }t        |«      sŒ|–— Œ y ­wrQ   )r   )r^   Útools     r7   r`   zBAnthropicMessagesHandler.process_input_messages.<locals>.<genexpr>¯  s   è ø€ Òi 4ÔFbÐcgÕFhœ$Ñiùs   ‚“)Úfull_messagesÚscoped_indicesÚguardrailed_scoped)Úhoisted_system_messageÚpreserve_system_messages)rÈ   Ú	responsesrI   z0Anthropic Messages: Processed input messages: %s)re   r   r   r   ÚitemsrÆ   r
   rˆ   r   ÚanyÚ!_hoisted_top_level_system_messageÚinsertr   r   rK   Ú	enumeraterC   rJ   r"   Úapply_guardrailr   Ú_map_tool_helperr¡   r   r   Ú_write_back_structured_messagesÚ&structured_messages_cover_full_requestr   Ú#_apply_guardrail_responses_to_inputr   Údebug)&rU   r­   rË   rÌ   rÈ   ÚkeyÚvalueÚtranslation_sourcerÄ   Úfull_structured_messagesÚhas_midturn_system_messagerî   Úscoped_message_indicesr–   rà   rê   Útools_to_checkÚ	extractedrI   r¬   Útexts_to_checkrÜ   ÚimageÚimages_to_checkrã   Úoriginal_structured_messagesra   Úguardrailed_inputsÚguardrailed_textsÚguardrailed_toolsÚanthropic_configÚanthropic_toolsÚconverted_toolÚ
mcp_serverÚguardrailed_structured_messagesrÒ   rÓ   rÔ   s&   `                                  @@@r7   Úprocess_input_messagesz/AnthropicMessagesHandler.process_input_messages?  sö  ûè ø€ ð Ÿ(™( :Ó.ˆØÐØˆKäHÐI[Ó\ˆÜDÐEWÓXˆ	Ü(VÐWiÓ(jÐð *.¯©«÷%
Ù%˜3 ¸À»ˆC�‰Jð%
Ðñ %
ð 59×4MÑ4MÐN`Ó4aÐ*ä*.ÜÔ!Ñ"Ø.×2Ñ2°:¸rÓBó+
Ð ô -0ñ 0
ØNfô0
ó -
Ð"ñ 1<©À×AgÑAgÐhlÓAmÐØ!Ð-Ø$×+Ñ+¨AÐ/EÔFô )JØ$Ø#9ØØô	)
Ðð TjÖ%jÈ%Ð&>¸uÓ&EÐ%jÐÐ%jñ &ñ ð ?×BÑBÀ7ÈBÓOöàÜ3°DÔ9ò òð 	ô !ö 	!
ô %.¨hÓ$7ô	!
ó 	
ˆ	ô Ña°yÔaÓaˆØ7>Ö ?¨t §£Ð ?ˆÐ ?à%.÷"
Ø!¸K×<NÑ<Nò"
Ø38ŠEð"
Øð"
ˆñ "
ò
 Ü5¸NÔKˆFÙØ#2��xÑ ÙØ"0��w‘Ø2EÐ(Ù"Ø0C�Ð,Ñ-àŸ8™8 GÓ,ˆEÙØ"'��w‘Ø.@×.PÑ.PØØ!Ø$Ø/ð	 /Qó /÷ )Ðð (:×'=Ñ'=¸gÀrÓ'JÐØ'9×'=Ñ'=¸gÓ'FÐØ Ð,ä*9Ó*;Ð ØHJ�Ø-ò ?�DØ1A×1RÑ1RÐSWÓ1XÑ.�N JØ%Ñ1Ø'×.Ñ.¨~Õ>ð?ñ .ô <Ø&*§h¡h¨wÓ&7Ø'6Ü"5õðÙi¨4¯8©8°GÓ+<Ò+BÀÔiðà(ðð �W‘ð 6H×5KÑ5KÐLaÓ5bÐ+à/Ð;Ø3Ð;WÑWà×4Ñ4Øà)×PÑPÔRñ 4ä:Ø&>Ø'=Ø+Jôð
 ,BØ-Gð 5õ ð ×>Ñ>Ø%Ø/Ø#ð ?ó ÷ ð ô 	×"Ñ"Ð#UÐW_Ô`àˆùóy%
ùò. &kùò
ùò& !@ùó"
ð$)ùðdúsp   †A
L6ÁLÁLÁ#B	L6Ã,LÃ8L6ÄL!Ä&9L6ÅL&Å2L6Å9L+ÆAL6Ç,L1Ç-AL6È>B;L6Ë9L4Ë:8L6Ì4L6c                 ó¶   — |j                  d«      }|sy| j                  |j                  d«      xs dg |dœ«      }|j                  d«      xs g }|r|d   S dS )zGReturn the system message produced by translating the top-level prompt.rÎ   Nra   rb   )ra   rÈ   rÎ   rÈ   r   )re   rÆ   )rU   r­   rÎ   ÚprobeÚhoisteds        r7   ró   z:AnthropicMessagesHandler._hoisted_top_level_system_messageÑ  sj   € ð Ÿ™ Ó*ˆÙØØ×0Ñ0àŸ™ 'Ó*Ò0¨bØØ ñó
ˆð Ÿ™ :Ó.Ò4°"ˆÙ$ˆw�q‰zÐ.¨$Ð.r6   rv   c                 óœ  — | j                  d«      }t        |t        «      r	|rd|dœS dS t        |t        «      syg }|D ]‚  }t        |t        «      r|j                  d«      dk7  rŒ(|j                  d«      }t        |t        «      r|sŒLd|dœ}|j                  d«      }|rt        |«      |d<   |j                  |«       Œ„ |rd|dœS dS )	zHConvert an OpenAI system message to the client's Anthropic-shaped entry.r~   rÎ   )r}   r~   Nry   rC   rx   Úcache_control)re   r\   rE   rˆ   rŸ   r   r¡   )rv   r~   Úblocksr½   rC   Úanthropic_blockr  s          r7   Ú#_openai_system_message_to_anthropicz<AnthropicMessagesHandler._openai_system_message_to_anthropicâ  sä   € ð
 !Ÿ™ YÓ/ˆÜ�gœsÔ#á:A˜¨gÑ6ðØGKðô ˜'¤4Ô(ØØ13ˆØò 	+ˆEÜ˜e¤TÔ*¨e¯i©i¸Ó.?À6Ò.IØØ—9‘9˜VÓ$ˆDÜ˜d¤CÔ(±ØàØñ2ˆOð "ŸI™I oÓ6ˆMÙÜ3;¸MÓ3J� Ñ0Ø�M‰M˜/Õ*ð	+ñ 6<�X¨&Ñ1ð	
ØAEð	
r6   Úleading_systemsÚinclude_existing_systemc           	      óv  — |r| j                  d«      nd}t        |t        «      r|rd|dœgnt        |t        «      rt        |«      ng }t	        d„ |D «       «      }||D ��cg c],  }|�(t        |d   t        «      r	d|d   dœgn|d   D ]  }|‘Œ Œ. c}}z   }|r|| d<   y| j                  dd«       yc c}}w )zgDeliver leading system rows through Anthropic's top-level system param, which rejects them in messages.rÎ   NrC   rx   c              3   óf   K  — | ])  }t        |t        «      rt        j                  |«      –— Œ+ y ­wrQ   )r\   rŸ   rO   r  rÑ   s     r7   r`   zPAnthropicMessagesHandler._fold_leading_systems_into_top_level.<locals>.<genexpr>  s-   è ø€ ò &
àÜ˜'¤4Ô(ô %×HÑHÈ×Qñ&
ùs   ‚/1r~   )re   r\   rE   rˆ   rK   Úpop)	r­   r  r  ÚexistingÚexisting_blocksÚconverted_rowsÚrowr½   Úfoldeds	            r7   Ú$_fold_leading_systems_into_top_levelz=AnthropicMessagesHandler._fold_leading_systems_into_top_level  sè   € ñ 1H˜$Ÿ(™( 8Ô,ÈTˆô ˜(¤CÔ(©Xð  hÑ/Ñ0ô ˜(¤DÔ)ô �h”àð 	ô !&ñ &
à*ô&
ó !
ˆð
 '6à%÷9
àØˆä>HÈÈYÉÔY\Ô>]˜&¨#¨i©.Ñ9Ñ:ÐcfÐgpÑcqò9
ð ò ð9
Øó9
ñ '
ˆñ Ø#ˆD�ŠNà�H‰H�X˜tÕ$ùó9
s   Á#1B5rî   c                 ód   — |€y| |u ryt        | t        «      xr t        |t        «      xr | |k(  S )zFMatch the hoisted prompt by identity, or by value after serialization.FT©r\   rŸ   )rv   rî   s     r7   Ú_is_hoisted_top_level_systemz5AnthropicMessagesHandler._is_hoisted_top_level_system"  sA   € ð "Ð)ØØÐ,Ñ,Øä�w¤Ó%Òx¬*Ð5KÌTÓ*RÒxÐW^ÐbxÑWxð	
r6   c                 ó„   — t        | t        «      xr/ t        | j                  d«      xs d«      j	                  «       dk(  S )z1Whether the row is an in-sequence system message.r}   rb   rÎ   )r\   rŸ   rE   re   rÐ   )rv   s    r7   Ú
_is_systemz#AnthropicMessagesHandler._is_system-  s8   € ô ˜'¤4Ó(Ò_¬S°·±¸VÓ1DÒ1JÈÓ-K×-QÑ-QÓ-SÐW_Ñ-_Ð_r6   rà   c                 ó^  — ddl m} t        | «      D ��cg c]  \  }}t        j	                  |«      s|‘Œ }}} ||D �cg c]  }| |   ‘Œ	 c}«      D �ci c]  }t        |«      dkD  r||d      ||d      “Œ! }}g }g }d}	t        | «      D ]~  \  }}t        j	                  |«      r||	k  r|j                  |«       Œ2|j                  ||	«      }	|j                  |«       ||	k\  sŒ[|sŒ^|j                  |«       |j                  «        Œ€ |j                  |«       |S c c}}w c c}w c c}w )zhHold a system row until the tool exchange around it completes so the call/result pair converts together.r   )Úgroup_tool_exchangesr”   éÿÿÿÿ)
Ú3litellm.litellm_core_utils.prompt_templates.factoryr*  rõ   rO   r(  rº   r¡   re   ÚextendÚclear)
rà   r*  r–   rv   Únon_system_positionsÚgroupÚexchange_end_for_startÚorderedÚdeferred_systemsÚopen_exchange_ends
             r7   Ú$_defer_systems_inside_tool_exchangesz=AnthropicMessagesHandler._defer_systems_inside_tool_exchanges2  sV  € õ
 	]ô #,Ð,?Ó"@÷2
á��wÜ+×6Ñ6°wÔ?ò ð2
Ðñ 2
ñ .ÐWkÖ.lÈeÐ/BÀ5Ó/IÒ.lÓmö9
àÜ�5‹z˜AŠ~ð !  q¡Ñ*Ð,@ÀÀrÁÑ,KÑKð9
Ðð 9
ð
  "ˆØ(*ÐØÐÜ'Ð(;Ó<ò 	)‰NˆE�7Ü'×2Ñ2°7Ô;ÀÐHYÒ@YØ ×'Ñ'¨Ô0ØØ 6× :Ñ :¸5ÐBSÓ TÐØ�N‰N˜7Ô#ØÐ)Ó)Ò.>Ø—‘Ð/Ô0Ø ×&Ñ&Õ(ð	)ð 	�‰Ð'Ô(Øˆùó/2
ùò /mùò9
s   •!D¿D%Á$D*rï   c                 óæ  ‡‡‡‡‡‡— ddl mŠmŠ t        j                  Št        | j                  d«      xs d«      Šg Šdt        ddfˆˆˆˆfd„}t        j                  |«      }t        ˆfd	„t        |«      D «       t        |«      «      }|d| }t        ˆfd
„|D «       «      }|r!|dk(  r|st        j                  | |‰du ¬«       g }	|}
||d D ]{  } ‰|«      s|	j                  |«       Œ ||	«       |	j                  «        |
st        j!                  |‰«      rd}
ŒP|sŒSt        j#                  |«      }|€Œk‰j                  |«       Œ}  ||	«       t        ˆfd„‰D «       «      s‰j%                   ‰g ‰d¬«      «       ‰D ]c  }|j                  d«      }t'        |t        «      sŒ%|D ]:  }t'        |t(        «      sŒ|j                  d«      dk(  sŒ)|j+                  dd«       Œ< Œe ‰| d<   y)zOWrite a guardrail's structured-message rewrite back without losing corrections.r   )Úanthropic_messages_ptr*  ra   rb   ÚrunrY   Nc           
      ó€   •—  ‰| «      D ]-  }‰j                   ‰|D �cg c]  }| |   ‘Œ	 c}‰d¬«      «       Œ/ y c c}w )NÚ	anthropic©rÈ   ra   Úllm_provider)r-  )r8  r0  r–   r7  Ú	convertedr*  ra   s      €€€€r7   Ú_convert_runzNAnthropicMessagesHandler._write_back_structured_messages.<locals>._convert_runc  sK   ø€ Ù-¨cÓ2ò �Ø× Ñ Ù)Ø:?Ö!@° # e£*Ò!@Ø#Ø%0ôõñùò "As   ž;c              3   ó:   •K  — | ]  \  }} ‰|«      rŒ|–— Œ y ­wrQ   r5   )r^   r–   rv   r(  s      €r7   r`   zKAnthropicMessagesHandler._write_back_structured_messages.<locals>.<genexpr>o  s   øè ø€ ÒW‘~�u˜gÁ:ÈgÕCVŒUÑWùs   ƒ”c              3   óJ   •K  — | ]  }t         j                  |‰«      –— Œ y ­wrQ   )rO   r&  )r^   rv   rî   s     €r7   r`   zKAnthropicMessagesHandler._write_back_structured_messages.<locals>.<genexpr>s  s'   øè ø€ ò (
àô %×AÑAÀ'ÐKa×bñ(
ùs   ƒ #r”   )r  Tc              3   ó0   •K  — | ]  } ‰|«       –— Œ y ­wrQ   r5   )r^   rv   r(  s     €r7   r`   zKAnthropicMessagesHandler._write_back_structured_messages.<locals>.<genexpr>�  s   øè ø€ ÒD¨w‘z 'Ó*Ô*ÑDùs   ƒr:  r;  r~   ry   Úthinkingr  rÈ   )r,  r7  r*  rO   r(  rE   re   rˆ   r5  Únextrõ   rº   rò   r#  r¡   r.  r&  r  r-  r\   rŸ   r  )r­   rà   rî   rï   r>  r2  Úleading_countr  Úhoisted_in_leadingr8  Úhoisted_droppedrv   Úanthropic_systemÚmsgr~   r½   r(  r7  r=  r*  ra   s     `             @@@@@r7   rø   z8AnthropicMessagesHandler._write_back_structured_messagesR  s  ý€ ÷	
ô
 5×?Ñ?ˆ
Ü˜4Ÿ8™8 GÓ,Ò2°Ó3ˆØ!#ˆ	ð	œdð 	 t÷ 	ð 	ô 2×VÑVÐWjÓkˆÜ#ÛW¬°7Ó);ÔWÜ�‹Ló 
ˆð ")¨¨-Ð!8ˆÜ$'ó (
à*ô(
ó %
Ðñ  M°QÒ$6Ñ;MÜ$×IÑIØØØ(>À$Ð(Fð Jô ð
 ˆØ,ˆØ˜}˜~Ð.ò 	7ˆGÙ˜gÔ&Ø—
‘
˜7Ô#ØÙ˜ÔØ�I‰IŒKÙ"Ô'?×'\Ñ'\ØÐ/ô(ð #'�ØÚ'Ü#;×#_Ñ#_Ð`gÓ#hÐ Ø#Ñ/Ø×$Ñ$Ð%5Õ6ð	7ñ 	�SÔÜÓD¸)ÔDÔDØ×ÑÑ2¸BÀeÐZeÔfÔgØò 	9ˆCØ—g‘g˜iÓ(ˆGÜ˜'¤4Õ(Ø$ò 9�EÜ! %¬Õ.°5·9±9¸VÓ3DÈ
Ó3RØŸ	™	 /°4Õ8ñ9ð	9ð %ˆˆZÒr6   r.   c                 ó  ‡‡— | j                  d«      }t        |t        «      r)|st        S t	        t        |t        ‰«      «      fd¬«      S t        |t        «      st        S t	        t        ˆˆfd„t        |«      D «       «      d¬«      S )zOMatch the adapter's filtering so positional guardrail write-back stays aligned.r~   r5   rL   c              3   óÞ   •K  — | ]d  \  }}t        |t        «      rO|j                  d «      dk(  r;t        |j                  d«      xŠt        «      r‰rt	        ‰t        ‰|«      «      –— Œf y­w)ry   rC   N)r\   rŸ   re   rE   rB   r9   )r^   r:   Úcontent_itemr.   Útext_strs      €€r7   r`   zHAnthropicMessagesHandler._extract_midturn_system_text.<locals>.<genexpr>§  sf   øè ø€ ò á-�K Ü˜l¬DÔ1Ø ×$Ñ$ VÓ,°Ò6Ü¨<×+;Ñ+;¸FÓ+CÐC˜xÄSÔIÙô ˜HÔ&<¸WÀkÓ&R×Sñùs   ƒA*A-)
re   r\   rE   rM   rH   rB   r-   rˆ   rK   rõ   )rv   r.   r~   rL  s    ` @r7   Ú_extract_midturn_system_textz5AnthropicMessagesHandler._extract_midturn_system_text™  s�   ù€ ð !Ÿ™ YÓ/ˆÜ�gœsÔ#ÙÜ,Ð,Ü!¬;°wÔ@TÐU\Ó@]Ó+^Ð*`ÐikÔlÐlÜ˜'¤4Ô(Ü(Ð(ÜÜô ä1:¸7Ó1Côó ð ô

ð 
	
r6   c                 óx   — |j                  d«      xs g D ��cg c]  }t        |«      D ]  }|‘Œ Œ c}}S c c}}w )z Extract every tool name in an Anthropic messages request: tools[].name, plus
        tools[].function.name for OpenAI-format tools the bridge forwards verbatim.rÕ   )re   r   )rU   r­   rê   Únames       r7   Úextract_request_tool_namesz3AnthropicMessagesHandler.extract_request_tool_names²  s9   € ð "&§¡¨'Ó!2Ò!8°b×`˜ÔEYÐZ^ÓE_Ò`¸T’Ð`�Ó`Ð`ùÓ`s   ™6r×   rØ   rÒ   c                 ó  ‡ ‡‡‡— t        |j                  d«      xs d«      }|dk(  r‰rt        S ‰ j                  |‰¬«      S ‰r|j	                  «       dk(  rt        S |j                  dd«      }t        |t         «      r)‰rt        S t        t        |t        ‰«      «      fd¬	«      S t        |t        «      st        S t        ˆ ˆˆˆfd
„t        |«      D «       «      }t        t        d„ |D «       «      t        d„ |D «       «      ¬	«      S )zèExtract text content and images from a message.

        In-sequence system entries are scanned even when ``skip_system_message`` is set:
        that flag covers only the trusted top-level prompt, which never appears here.
        r}   rb   rÎ   )rv   r.   rê   r~   Nr5   rL   c              3   óp   •K  — | ]-  \  }}t        |t        «      r‰j                  |‰|‰‰¬ «      –— Œ/ y­w))rK  r.   r:   rØ   rÒ   N)r\   rŸ   Ú_extract_content_block)r^   r:   rK  Úclsr.   rÒ   rØ   s      €€€€r7   r`   zJAnthropicMessagesHandler._extract_input_text_and_images.<locals>.<genexpr>Õ  sH   øè ø€ ò 

ñ *�˜\Ü˜,¬Ô-ð ×&Ñ&Ø)ØØ'Ø"3Ø'=ð '÷ ñ

ùs   ƒ36c              3   óB   K  — | ]  }|j                   D ]  }|–— Œ Œ y ­wrQ   rÛ   )r^   r½   r¬   s      r7   r`   zJAnthropicMessagesHandler._extract_input_text_and_images.<locals>.<genexpr>á  s    è ø€ ÒM 5¸u¿}¹}ÒM°tœ$ÐM˜$ÑMùrÝ   c              3   óB   K  — | ]  }|j                   D ]  }|–— Œ Œ y ­wrQ   )rJ   )r^   r½   r  s      r7   r`   zJAnthropicMessagesHandler._extract_input_text_and_images.<locals>.<genexpr>â  s    è ø€ ÒM 5ÀÇÁÒM°uœÐM˜ÑMùrÝ   )rE   re   rM   rM  rÐ   r\   rH   rB   r-   rˆ   rK   rõ   )	rT  rv   r.   r×   rØ   rÒ   r}   r~   r  s	   ` ` ``   r7   rÙ   z7AnthropicMessagesHandler._extract_input_text_and_images·  sõ   û€ ô ˜'Ÿ+™+ fÓ-Ò3°Ó4ˆØ�8ÒÙ%Ü,Ð,Ø×3Ñ3¸GÈWÐ3ÓUÐUÙ §¡£°Ò!7Ü(Ð(à Ÿ™ Y°Ó5ˆÜ�gœsÔ#Ù%Ü,Ð,Ü!¬;°wÔ@TÐU\Ó@]Ó+^Ð*`ÐikÔlÐlÜ˜'¤4Ô(Ü(Ð(äö 

ô .7°wÓ-?ô

ó 

ˆô ÜÑM¨FÔMÓMÜÑM¨FÔMÓMô
ð 	
r6   rK  r:   c           	      ó6  — |j                  d«      dk(  r|rt        S | j                  |||¬«      S |rt        S |j                  dd «      }t        |€dnt	        |t        ||«      «      f|j                  d«      dk(  r| j                  |«      ¬«      S d¬«      S )Nry   Útool_result)rK  r.   r:   rC   r5   r  rL   )re   rM   Ú_extract_tool_resultrH   rB   r9   Ú_image_sources)rT  rK  r.   r:   rØ   rÒ   rL  s          r7   rS  z/AnthropicMessagesHandler._extract_content_blockå  s±   € ð ×Ñ˜FÓ# }Ò4Ù Ü,Ð,Ø×+Ñ+¸ÈwÐdoÐ+ÓpÐpá!Ü(Ð(à&×*Ñ*¨6°4Ó8ˆÜàÐ&‘¬[¸ÔCYÐZaÐcnÓCoÓ-pÐ,rà7C×7GÑ7GÈÓ7OÐSZÒ7Z�3×%Ñ% lÓ3ô	
ð 	
ð acô	
ð 	
r6   c           	      óT  ‡ ‡‡— |j                  d«      }t        |t        «      r"t        t	        |t        ‰‰«      «      fd¬«      S t        |t        «      st        S t        d„ t        |«      D «       «      }t        t        ˆˆfd„|D «       «      t        ˆ fd„|D «       «      ¬«      S )Nr~   r5   rL   c              3   óL   K  — | ]  \  }}t        |t        «      sŒ||f–— Œ y ­wrQ   r%  )r^   r@   r½   s      r7   r`   z@AnthropicMessagesHandler._extract_tool_result.<locals>.<genexpr>  s*   è ø€ ò 
Ù#3 9¨eÔYcÐdiÔkoÕYpˆY˜Ôñ
ùs   ‚$›	$c           	   3   ó–   •K  — | ]@  \  }}t        |j                  d «      t        «      rt        |d    t	        ‰‰|«      «      –— ŒB y­w)rC   N)r\   re   rE   rB   r?   )r^   r@   r½   r:   r.   s      €€r7   r`   z@AnthropicMessagesHandler._extract_tool_result.<locals>.<genexpr>  sF   øè ø€ ò á$�I˜uÜ˜eŸi™i¨Ó/´Ô5ô ˜E &™MÔ+DÀWÈkÐ[dÓ+e×fñùs   ƒAA	c              3   ó~   •K  — | ]4  \  }}|j                  d «      dk(  sŒ‰j                  |«      D ]  }|–— Œ Œ6 y­w)ry   r  N)re   rZ  )r^   Ú_r½   r  rT  s       €r7   r`   z@AnthropicMessagesHandler._extract_tool_result.<locals>.<genexpr>  sI   øè ø€ ò Ù"˜!˜U°·	±	¸&Ó0AÀWÓ0LÐZ]×ZlÑZlÐmrÓZsòØQV”ðØñùs   ƒ= =)
re   r\   rE   rH   rB   r=   rˆ   rM   rK   rõ   )rT  rK  r.   r:   Útool_result_contentr  s   ` ``  r7   rY  z-AnthropicMessagesHandler._extract_tool_resultþ  s´   ú€ ð &2×%5Ñ%5°iÓ%@ÐäÐ)¬3Ô/Ü!Ü$Ð%8Ô:PÐQXÐZeÓ:fÓgÐiØôð ô Ð-¬tÔ4Ü(Ð(äñ 
Ü7@ÐATÓ7Uô
ó 
ˆô Üô à(.ôó ô
 ó Ø&,ôó ô	
ð 		
r6   r½   .c                 óv   — | j                  d«      }t        |t        «      sy|j                  d«      }|r|fS dS )NÚsourcer5   r­   )re   r\   r   )r½   rb  r­   s      r7   rZ  z'AnthropicMessagesHandler._image_sources  s:   € àŸ	™	 (Ó+ˆÜ˜&¤'Ô*Øà—j‘j Ó(ˆÙ�ˆwÐ& BÐ&r6   rÈ   rð   rI   c              ƒ   óø  K  — t        ||«      D ]ç  \  }}|j                  }||j                     }|j                  dd«      }|€Œ6|xt        d˜ x�\    t        |t        «      sŒU||d<   Œ[ xt        d˜ x�\  }	 t        |t        «      sŒ{|||	   d<   Œ„ xt        d˜ x�\  }	 t        |t        «      sŒ¤|||	   d<   Œ­ t        d˜ x�$\  }	}
t        |t        «      sŒÌ|||	   d   |
   d<   ŒÛ 	 t        |«       Œé y­w)zC
        Apply guardrail responses back to input messages.
        r~   Nr5   )r:   rC   )r:   r@   )ÚziprD   r.   re   r-   r\   rE   r9   rˆ   r=   r?   r   )rU   rÈ   rð   rI   r¬   Úguardrail_responserD   rv   r~   r:   r@   s              r7   rú   z<AnthropicMessagesHandler._apply_guardrail_responses_to_input&  s  è ø€ ô ),¨G°YÓ(?ò 	)Ñ$ˆDÐ$Ø—[‘[ˆFØ˜vŸ~™~Ñ.ˆGØ—k‘k )¨TÓ2ˆGØˆØàØ+Ô)Ö+Ü! '¬3Õ/à.ð   	Ò*ð ,ð
 EÔ+×DÜ! '¬4Õ0à.ð   Ñ,¨VÒ4ð Eð
 EÔ+×DÜ! '¬4Õ0à.ð   Ñ,¨YÒ7ð Eô
 /×\Ü! '¬4Õ0à.ð   Ñ,¨YÑ7¸	ÑBÀ6ÒJð ]ð
 Ü  Õ(ñ;	)ùs   ‚A!C:Á$%C:Â
(C:Â3'C:ÃC:r_   r)   Úuser_api_key_dictzUserAPIKeyAuth | Nonec              ƒ   ó–  K  — g }g }g }g }	| j                  |«      }
|
s|S | j                  |
|||	|«       |s|rt| j                  |||d¬«      }| j                  ||||«      }|j	                  ||d|¬«      ƒ d{  –—† }|j                  dg «      }| j                  |||	¬«      ƒ d{  –—†  t        j                  d|«       |S 7 ŒJ7 Œ­w)a»  
        Process output response by applying guardrails to text content and tool calls.

        Args:
            response: Anthropic MessagesResponse object
            guardrail_to_apply: The guardrail instance to apply
            litellm_logging_obj: Optional logging object
            user_api_key_dict: User API key metadata to pass to guardrails

        Returns:
            Modified response with guardrail applied to content

        Response Format Support:
            - List content: response.content = [
                {"type": "text", "text": "text here"},
                {"type": "tool_use", "id": "...", "name": "...", "input": {...}},
                ...
            ]
        r_   ©rü   râ   Nrß   )r_   rð   Útask_mappingsz1Anthropic Messages: Processed output response: %s)	Ú_get_response_contentÚ_extract_from_content_blocksÚ_prepare_request_dataÚ_build_guardrail_inputsrö   re   Ú$_apply_guardrail_responses_to_outputr   rû   )rU   r_   rË   rÌ   rf  rX   r  r  Útool_calls_to_checkri  Úresponse_contentrã   r  r	  s                 r7   Úprocess_output_responsez0AnthropicMessagesHandler.process_output_responseN  s(  è ø€ ð6 ,.ˆØ,.ˆØHJÐØ=?ˆà"&×"<Ñ"<¸XÓ"FÐÙØˆOð 	×)Ñ)ØØØØØô	
ñ Ñ0Ø×5Ñ5ØØØ!Øð	 6ó ˆLð !×8Ñ8ØØØ#Øó	ˆFð /A×.PÑ.PØØ)Ø%Ø/ð	 /Qó /÷ )Ðð (:×'=Ñ'=¸gÀrÓ'JÐð ×;Ñ;Ø!Ø+Ø+ð <ó ÷ ð ô 	×"Ñ"Ð#VÐX`Ôaàˆð%)øðús$   ‚A8C	Á:CÁ;-C	Â(CÂ)C	ÃC	c              ƒ   óÈ  K  — ddl m} | j                  |«      }|�rt        j                  |t        d|«      d¬«      }|�×t        |d«      rË|j                  r¿t        t        |«      }	t        t        |	j                  d   «      }
t        t        t           dz  |
j                  j                  «      }|
j                  j                  }t        «       }|r|g|d<   |r||d	<   	 | j!                  ||	|d
¬«      }|j#                  ||d
|¬«      ƒ d{  –—† }|S t)        j*                  d«       |S | j-                  |«      }	 | j!                  |||d¬«      }|j#                  d|gi|d
|¬«      ƒ d{  –—† }|S 7 Œf# |$ r-}|j$                  €|xs | j'                  ||«      |_        ‚ d}~ww xY w7 Œ=# |$ r)}|j$                  €| j'                  ||«      |_        ‚ d}~ww xY w­w)zÔ
        Process output streaming response by applying guardrails to text content.

        Get the string so far, check the apply guardrail to the string so far, and return the list of responses so far.
        r   )r%   ÚLiteLLMLoggingObjrb   )rc   rÌ   ra   NÚchoicesrß   Ú
tool_callsr_   rh  râ   z9Skipping output guardrail - model response has no choicesrð   )Ú%litellm.integrations.custom_guardrailr%   Ú_check_streaming_has_endedr   Ú"_build_complete_streaming_responser
   Úhasattrrt  r#   r!   rˆ   r    rv   ru  r~   r"   rl  rö   r{   rj   r   rû   Úget_streaming_string_so_far)rU   rW   rË   rÌ   rf  rX   r%   Ú	has_endedÚbuilt_responseÚmodel_responseÚfirst_choiceÚtool_calls_listÚstring_so_farÚguardrail_inputsÚprepared_request_dataÚ_guardrailed_inputsÚes                    r7   Ú!process_output_streaming_responsez:AnthropicMessagesHandler.process_output_streaming_responseŸ  sH  è ø€ õ 	Rà×:Ñ:Ð;KÓLˆ	Úä$F×$iÑ$iØ+Ü$(Ð)<Ð>QÓ$RØô%ˆNð Ð)¬g°nÀiÔ.PÐUc×UkÒUkÜ(,¬]¸NÓ(K�Ü&*¬7°N×4JÑ4JÈ1Ñ4MÓ&N�Ü)-ÜÔ6Ñ7¸$Ñ>Ø ×(Ñ(×3Ñ3ó*�ð !-× 4Ñ 4× <Ñ <�Ü*CÓ*EÐ Ù Ø1>°Ð$ WÑ-Ù"Ø5DÐ$ \Ñ2ðØ,0×,FÑ,FØ$Ø&Ø)Ø&ð	 -Gó -Ð)ð 1C×0RÑ0RØ/Ø%:Ø#-Ø$7ð	 1Só 1÷ +Ð'ð $Ð#ô %×*Ñ*Ð+fÔgØ#Ð#à×8Ñ8Ð9IÓJˆð	Ø$(×$>Ñ$>ØØ Ø!Øð	 %?ó %Ð!ð );×(JÑ(JØ - Ð1Ø2Ø%Ø/ð	 )Kó )÷ #Ðð  ÐðE+ùð /ò Ø×*Ñ*Ð2Ø.<ò /À×@dÑ@dØ,¨lóA˜Ô+ð ûðúð$#ùð 'ò 	Ø×"Ñ"Ð*Ø&*×&JÑ&JÐK[Ð]iÓ&j�Ô#Øûð	üsr   ‚C!G"Ã$-E: ÄE8ÄE: Ä*G"Å0F1 Å1F/Å2F1 Å6G"Å8E: Å:F,Å?(F'Æ'F,Æ,G"Æ/F1 Æ1GÆ6$GÇGÇG"rü   c                 ó^   — |€||i}n	||vr|||<   d|vr| j                  |«      }|r||d<   |S )zGEnsure request_data has the response/responses_so_far key and metadata.Úlitellm_metadata)Ú'transform_user_api_key_dict_to_metadata)rU   rX   r_   rf  rü   Úuser_metadatas         r7   rl  z.AnthropicMessagesHandler._prepare_request_datañ  sR   € ð ÐØ ˜?‰Là˜,Ñ&Ø$,�˜SÑ!à \Ñ1Ø#'×#OÑ#OÐPaÓ#bˆMÙØ3@�Ð/Ñ0ØÐr6   c                 óŒ   — t        | t        «      r| j                  dg «      xs g S t        | d«      rt	        | dd«      xs g S g S )z4Extract content list from a dict or object response.r~   N)r\   rŸ   re   ry  r‡   r�   s    r7   rj  z.AnthropicMessagesHandler._get_response_content  sG   € ô �h¤Ô%Ø—<‘< 	¨2Ó.Ò4°"Ð4Ü�X˜yÔ)Ü˜8 Y°Ó5Ò;¸Ð;Øˆ	r6   rp  r  r  ri  ro  r   c           	      ót  — t        |«      D ]ª  \  }}i }t        |t        «      r/|j                  d«      }	t	        t        t
        t        f   |«      }nHt        |d«      r;t        |dd«      }	t        |d«      r|j                  «       }n|	t        |dd«      dœ}nŒ�|	dv sŒ”| j                  ||||||¬«       Œ¬ y)z9Extract text, images, and tool calls from content blocks.ry   NÚ
model_dumprC   rx   )rC   Útool_use)r˜   r:   r  r  ri  ro  )rõ   r\   rŸ   re   r
   rE   Úobjectry  r‡   rŒ  Ú_extract_output_text_and_images)
rU   rp  r  r  ri  ro  r:   r˜   Ú
block_dictÚ
block_types
             r7   rk  z5AnthropicMessagesHandler._extract_from_content_blocks  sÍ   € ô +4Ð4DÓ*Eò 	Ñ&ˆK˜Ø,.ˆJÜ˜-¬Ô.Ø*×.Ñ.¨vÓ6�
Ü!¤$¤s¬F {Ñ"3°]ÓC‘
Ü˜¨Ô/Ü$ ]°F¸DÓA�
Ü˜=¨,Ô7Ø!.×!9Ñ!9Ó!;‘Jð !+Ü '¨°v¸tÓ Dñ"‘Jð
 àÐ1Ò1Ø×4Ñ4Ø",Ø +Ø#1Ø$3Ø"/Ø(;ð 5õ ñ%	r6   r"   c                 óÂ   — t        | ¬«      }|r||d<   |r||d<   d}t        |t        «      r|j                  d«      }nt	        |d«      rt        |dd«      }|r||d<   |S )zHBuild GenericGuardrailAPIInputs with optional images, tool calls, model.rÞ   rJ   ru  Nra   )r"   r\   rŸ   re   ry  r‡   )r  r  ro  r_   rã   Úresponse_models         r7   rm  z0AnthropicMessagesHandler._build_guardrail_inputs2  sn   € ô 2¸ÔGˆÙØ.ˆF�8ÑÙØ#6ˆF�<Ñ ØˆÜ�h¤Ô%Ø%Ÿ\™\¨'Ó2‰NÜ�X˜wÔ'Ü$ X¨w¸Ó=ˆNÙØ,ˆF�7‰OØˆr6   c                 ó0  — d}|D ]Ž  }t        |t        «      r|| j                  |«      z  }Œ(t        |t        «      sŒ9|j	                  d«      r|j	                  d«      nd}|sŒ`|j	                  d«      dk(  sŒu|j	                  dd«      }|sŒŠ||z  }Œ� |S )a¥  
        Parse streaming responses and extract accumulated text content.

        Handles two formats:
        1. Raw bytes in SSE (Server-Sent Events) format from Anthropic API
        2. Parsed dict objects (for backwards compatibility)

        SSE format example:
            b'event: content_block_delta\ndata: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" curious"}}\n\n'

        Dict format example:
            {
                "type": "content_block_delta",
                "index": 0,
                "delta": {
                    "type": "text_delta",
                    "text": " curious"
                }
            }
        rb   r›   Nry   rš   rC   )r\   r]   Ú_extract_text_from_sserŸ   re   )rU   rW   Útext_so_farr_   r›   rC   s         r7   rz  z4AnthropicMessagesHandler.get_streaming_string_so_farH  s”   € ð* ˆØ(ò 
	,ˆHä˜(¤EÔ*Ø˜t×:Ñ:¸8ÓDÑD‘ä˜H¤dÕ+Ø19·±¸gÔ1F˜Ÿ™ WÔ-ÈD�Ú˜UŸY™Y vÓ.°,Ó>Ø Ÿ9™9 V¨RÓ0�DÚØ# tÑ+™ð
	,ð Ðr6   Ú	sse_bytesc                 óØ  — d}	 |j                  d«      }|j                  d«      }|D ]á  }|j                  «       sŒ|j                  «       j                  d«      }d}d}|D ]L  }	|	j                  d«      r|	dd j                  «       }Œ(|	j                  d«      sŒ:|	d	d j                  «       }ŒN |d
k(  sŒŽ|sŒ‘	 t	        j
                  |«      }
|
j                  di «      }|j                  d«      dk(  r||j                  dd«      z  }Œã 	 |S # t        j                  $ r t        j                  d|«       Y �Œw xY w# t        $ r!}t        j                  d|«       Y d}~|S d}~ww xY w)zÝ
        Extract text content from Server-Sent Events (SSE) format.

        Args:
            sse_bytes: Raw bytes in SSE format

        Returns:
            Accumulated text from all content_block_delta events
        rb   r¯   rŽ   r²   Núevent:é   r³   é   r™   r›   ry   rš   rC   ú&Failed to parse JSON from SSE data: %sz"Error extracting text from SSE: %s)rµ   r¶   r·   r¸   r�   r¹   re   r»   r   ÚwarningÚ	ExceptionÚerror)rU   r—  rC   Ú
sse_stringr¼   ÚeventÚlinesr‹   Ú	data_liner¾   r­   r›   r„  s                r7   r•  z/AnthropicMessagesHandler._extract_text_from_ssek  sq  € ð ˆð!	Pà )× 0Ñ 0°Ó 9ˆJð '×,Ñ,¨VÓ4ˆFàò j�Ø—{‘{”}Øð Ÿ™›×+Ñ+¨DÓ1�Ø!�
Ø �	à!ò 5�DØ—‘ xÔ0Ø%)¨!¨" X§^¡^Ó%5™
ØŸ™¨Õ1Ø$(¨¨ H§N¡NÓ$4™	ð	5ð Ð!6Ó6º9ðjÜ#Ÿz™z¨)Ó4˜Ø $§¡¨°"Ó 5˜Ø Ÿ9™9 VÓ,°Ò<Ø  E§I¡I¨f°bÓ$9Ñ9˜Døñ+jð8 ˆøô  ×/Ñ/ò jÜ,×4Ñ4Ð5]Ð_h×iðjûô ò 	PÜ ×&Ñ&Ð'KÈQ×OÐOàˆûð	PúsI   „BD? ÂD? Â6D? Â:ADÄ
D? Ä)D<Ä8D? Ä;D<Ä<D? Ä?	E)ÅE$Å$E)c                 ó~  — |D �]Z  }t        |t        «      rø	 |j                  d«      }|j                  d«      }|D ]Î  }|j	                  «       sŒ|j	                  «       j                  d«      }d}d}|D ]L  }	|	j                  d«      r|	dd j	                  «       }Œ(|	j                  d«      sŒ:|	dd j	                  «       }ŒN |d	k(  sŒŽ|sŒ‘	 t        j                  |«      }
|
j                  d
i «      }|j                  d«      }|�  yŒÐ �Œt        |t        «      s�Œ|j                  d«      d	k(  s�Œ4|j                  d
i «      }|j                  d«      }|€�Œ[ y y# t        j                  $ r t        j                  d|«       Y �ŒRw xY w# t        $ r!}t        j                  d|«       Y d}~�Œ´d}~ww xY w)aö  
        Check if streaming response has ended by looking for non-null stop_reason.

        Handles two formats:
        1. Raw bytes in SSE (Server-Sent Events) format from Anthropic API
        2. Parsed dict objects (for backwards compatibility)

        SSE format example:
            b'event: message_delta\ndata: {"type":"message_delta","delta":{"stop_reason":"tool_use","stop_sequence":null},...}\n\n'

        Dict format example:
            {
                "type": "message_delta",
                "delta": {
                    "stop_reason": "tool_use",
                    "stop_sequence": null
                }
            }

        Returns:
            True if stop_reason is set to a non-null value, indicating stream has ended
        r¯   rŽ   r²   Nr™  rš  r³   r›  rœ   r›   r   Trœ  z'Error checking streaming end in SSE: %sry   F)r\   r]   rµ   r¶   r·   r¸   r�   r¹   re   r»   r   r�  rž  rŸ  rŸ   )rU   rW   r_   r   r¼   r¡  r¢  r‹   r£  r¾   r­   r›   r   r„  s                 r7   rw  z3AnthropicMessagesHandler._check_streaming_has_ended›  s·  € ð. )ó -	$ˆHä˜(¤EÔ*ð"]à!)§¡°Ó!9�Jð (×-Ñ-¨fÓ5�Fà!'ò r˜Ø$Ÿ{™{œ}Ø$ð !&§¡£× 3Ñ 3°DÓ 9˜Ø%)˜
Ø$(˜	à$)ò =˜DØ#Ÿ™¨xÔ8Ø-1°!°"¨X¯^©^Ó-=¡
Ø!%§¡°Õ!9Ø,0°°¨H¯N©NÓ,<¡	ð	=ð &¨Ó8ºYðrÜ'+§z¡z°)Ó'< Ø(,¯©°¸"Ó(= Ø.3¯i©i¸Ó.F Ø#.Ð#:Ú+/ð $;ò+rô< ˜H¤dÖ+Ø—<‘< Ó'¨?Ô:Ø$ŸL™L¨°"Ó5�EØ"'§)¡)¨MÓ":�KØ"Ò.Ù#ð[-	$ð^ øô $(×#7Ñ#7ò rÜ 4× <Ñ <Ð=eÐgp× qðrûô !ò ]Ü(×.Ñ.Ð/XÐZ[×\Ò\ûð]úsN   ˜BFÂ/FÃ
FÃ:E"ÄFÄFÅ")FÆFÆFÆFÆ	F<ÆF7Æ7F<c                 ó  — t        |t        «      r|j                  dg «      }nt        |dd«      xs g }|sy|D ]N  }t        |t        «      sŒ|j                  d«      dk(  sŒ)|j                  d«      }|sŒ=t        |t        «      sŒN y y)z‡
        Check if response has any text content to process.

        Override this method to customize text content detection.
        r~   NFry   rC   T)r\   rŸ   re   r‡   rE   )rU   r_   rp  r˜   Úcontent_texts        r7   Ú_has_text_contentz*AnthropicMessagesHandler._has_text_contentã  s‰   € ô �h¤Ô%Ø'Ÿ|™|¨I°rÓ:Ñä& x°¸DÓAÒGÀRÐáØØ-ò 	 ˆMä˜-¬Õ.°=×3DÑ3DÀVÓ3LÐPVÓ3VØ,×0Ñ0°Ó8�Ú¤J¨|¼SÕ$AÙð	 ð r6   r˜   c                 ó(  — |j                  d«      }|dk(  rJ|j                  d«      }|r6t        |t        «      r%|j                  |«       |j                  |df«       yyy|dk(  r-t	        j
                  ||¬«      }	|€g }|j                  |	«       yy)zª
        Extract text content, images, and tool calls from a response content block.

        Override this method to customize text/image/tool extraction logic.
        ry   rC   Nr�  )Úanthropic_tool_contentr–   )re   r\   rE   r¡   r   Ú!convert_tool_use_to_openai_format)
rU   r˜   r:   r  r  ri  ro  Úcontent_typer¦  Ú	tool_calls
             r7   r�  z8AnthropicMessagesHandler._extract_output_text_and_imagesø  s£   € ð ,×/Ñ/°Ó7ˆð ˜6Ò!Ø"/×"3Ñ"3°FÓ";ˆLÙ¤
¨<¼Ô =à×%Ñ% lÔ3Ø×$Ñ$ k°4Ð%8Õ9ð !>ˆ|ð ˜ZÒ'Ü.×PÑPØ'4Ø!ô ˆIð #Ð*Ø&(Ð#Ø×&Ñ& yÕ1ð (r6   c              ƒ   ó  K  — t        |«      D ]ö  \  }}||   }t        t        |d   «      }g }t        |t        «      r|j                  dg «      xs g }n!t        |d«      rt        |dd«      }	|	xs g }nŒh|sŒk|t        |«      k\  rŒz||   }
t        |
t        «      r6|
j                  d«      dk(  sŒ¤|t        t        t        t        f   |
«      d<   ŒÅt        |
d«      sŒÒt        |
dd«      dk(  sŒãt        |
d«      sŒð||
_        Œø y­w)zŠ
        Apply guardrail responses back to output response.

        Override this method to customize how responses are applied.
        r   r~   Nry   rC   )rõ   r
   r3   r\   rŸ   re   ry  r‡   rº   rE   rŽ  rC   )rU   r_   rð   ri  Útask_idxre  Úmappingr:   rp  r~   r˜   s              r7   rn  z=AnthropicMessagesHandler._apply_guardrail_responses_to_output  s  è ø€ ô -6°iÓ,@ò 	<Ñ(ˆHÐ(Ø# HÑ-ˆGÜœs G¨A¡JÓ/ˆKð +-ÐÜ˜(¤DÔ)Ø#+§<¡<°	¸2Ó#>Ò#DÀ"Ñ Ü˜ 9Ô-Ü! (¨I°tÓ<�Ø#*¢=¨bÑ àá#Øð œcÐ"2Ó3Ò3Øà,¨[Ñ9ˆMô ˜-¬Ô.Ø ×$Ñ$ VÓ,°Ó6ØEW”Dœœc¤6˜kÑ*¨MÓ:¸6ÒBÜ˜¨Õ/´G¸MÈ6ÐSWÓ4XÐ\bÓ4bä˜=¨&Õ1Ø);�MÕ&ñ?	<ùs   ‚B/DÂ2-DÃ DÃ1DÃ>
D)FNrQ   )NF)FFF)F)NNN)<r0   r1   r2   Ú__doc__rS   Ústaticmethodrˆ   rŽ  rŸ   r#   rj   Úboolr]   rp   ro   rn   rK   r3   r    rE   r§   r   rÆ   r   rÊ   r   r  ró   r  r   r#  r&  r(  r5  rø   r   rH   rM  rP  ÚclassmethodrÙ   rS  rY  rZ  rB   rú   rq  r…  rl  rj  rk  rm  rz  r•  rw  r§  r   r�  rn  Ú__classcell__)rV   s   @r7   rO   rO   t   s±  ø„ ñô9ð ðØ˜v™,ðà˜T‘kðð 
˜Ñ	òó ðð$  %Ø04ñ	2à&ð2ð ð2ð ˜v™,¨Ñ-ð	2ð
 
ˆe‰ó2ð2RÐ,Eð RÈ$ÈuÉ+ó Rð,.Ð.Gð .Ð[_Ð`fÑ[gð .ÐlpÐqvÑlwó .ð` ð%Ø˜v™,ð%à	ˆs�T‰z˜3 ™:Ð%Ñ	&ò%ó ð%ð4 ð˜vð ¨$¨t°C¸°KÑ/@Ñ*Aò ó ðð62¨ð 2Ð2Gó 2ð*¨Dð *°TÐ:JÑ5KÈdÑ5Ró *ð( ;?ñ	PàðPð .ðPð 8ð	Pð
 
óPðd/Øð/à	˜DÑ	 ó/ð" ð
Ø�c˜6�kÑ"ð
à	ˆc�6ˆkÑ	˜TÑ	!ò
ó ð
ð< ð%Ø�3˜�;Ñð%à! &Ñ)ð%ð "&ð%ð 
ò	%ó ð%ð@ ð
¨fð 
Èfð 
ÐY]ò 
ó ð
ð ð`˜Fð ` tò `ó ð`ð ðØ!ðà	òó ðð> ð *.Ø).ñ	D%ØðD%à!ðD%ð !'ðD%ð #'ð	D%ð
 
òD%ó ðD%ðL ð
Ø˜˜f˜Ñ%ð
àð
ð 
ò
ó ð
ð0a¨tð a¸¸S¹	ó að
 ð
 %*Ø"'Ø',ñ+
à˜˜f˜Ñ%ð+
ð ð+
ð "ð	+
ð
  ð+
ð !%ð+
ð 
ò+
ó ð+
ðZ ð (-ñ
à˜c 3˜hÑ'ð
ð ð
ð ð	
ð
  ð
ð !%ð
ð 
ò
ó ð
ð0 ð
à˜c 6˜kÑ*ð
ð ð
ð ð	
ð
 
ò
ó ð
ð< ð'˜g c¨6 kÑ2ð '°u¸SÀ#¸X±ò 'ó ð'ð&)à�t˜C ˜KÑ(Ñ)ð&)ð ˜‘9ð&)ð �{ CÐ'Ñ(ð	&)ð
 
ó&)ðX ;?Ø59Ø$(ñOà-ðOð .ðOð 8ð	Oð
 3ðOð ˜T‘kðOð 
%óOðj ;?Ø59Ø$(ñP à˜s™)ðP ð .ðP ð 8ð	P ð
 3ðP ð ˜T‘kðP ð 
ˆc‰óP ðdà˜T‘kðð ðð 3ð	ð
 ðð 
óð( ð¨ð °4¸±9ò ó ðð"à˜s™)ð"ð ˜S™	ð"ð ˜c™ð	"ð
 ˜E # s¨T¡z /Ñ2Ñ3ð"ð "Ð"?Ñ@ð"ð 
ó"ðH ðØ˜S™	ðà˜c™ðð "Ð"?Ñ@ðð ð	ð
 
%òó ðð*!¸DÀ¹Ið !È#ó !ðF.°ð .¸#ó .ð`F¸4À¹9ð FÈó FðPÐ*Eð È$ó ð8 IMñ 2à˜C ˜KÑ(ð 2ð ð 2ð ˜S™	ð	 2ð
 ˜c™ð 2ð ˜E # s¨T¡z /Ñ2Ñ3ð 2ð "Ð"=Ñ>ÀÑEð 2ð 
ó 2ðD*<à-ð*<ð ˜‘9ð*<ð ˜E # s¨T¡z /Ñ2Ñ3ð	*<ð
 
÷*<r6   rO   )Er°  r�   Úcollections.abcr   r   rÃ   r   Údataclassesr   Útypingr   r   r	   r
   Útyping_extensionsr   Úlitellm._loggingr   Ú*litellm.llms.anthropic.chat.transformationr   ÚHlitellm.llms.anthropic.experimental_pass_through.adapters.transformationr   r   Ú<litellm.llms.base_llm.guardrail_translation.base_translationr   r„   r   r   r   r   r   r   r   r   Ú`litellm.proxy.pass_through_endpoints.llm_provider_handlers.anthropic_passthrough_logging_handlerr   Úlitellm.types.llms.anthropicr   r   Úlitellm.types.llms.openair   r   r   r   r…   r    r!   r"   r#   rv  r$   r%   Ú*litellm.litellm_core_utils.litellm_loggingr&   rs  Úlitellm.proxy._typesr'   Ú8litellm.types.llms.anthropic_messages.anthropic_responser)   r-   r9   r=   r?   rF   rB   rH   rM   r4   rO   r5   r6   r7   ú<module>rÃ     su  ðòó ß -Ý Ý !ß 2Ó 2å *å 1Ý F÷õ Y÷	÷ 	ó 	õ÷÷ó ÷ó ñ ÷õ XÝ3õñ
 �$˜dÔ#÷ð ó $ðñ �$˜dÔ#÷ð ó $ðñ
 �$˜dÔ#÷ð ó $ðñ
 �$˜dÔ#÷ð ó $ðð Ð1Ñ1Ð4JÑJÐMfÑfð ñ
 �$˜dÔ#÷!ð !ó $ð!ñ
 �$˜dÔ#÷ð ó $ðñ
  .°bÀÔDÐ �uÓ DôP<˜õ P<r6   