Ë
    tPêjå  ã                  ó�   — d Z ddlmZ ddlZddlmZmZ ddlmZ ddl	m
Z
mZ dd„Zdd„Zdd	„Zd
dœ	 	 	 	 	 dd„Zdd„Zdd„Zdd„Zy)a`  Anthropic SSE <-> ModelResponse conversion for guardrail streaming hooks.

`/v1/messages` streams reach a guardrail's `async_post_call_streaming_iterator_hook` as raw SSE
frames rather than chunk objects, which `stream_chunk_builder` cannot assemble. These helpers let a
hook scan such a stream, and re-emit it when the guardrail rewrote the response.
é    )ÚannotationsN)ÚMappingÚSequence)ÚFinal)ÚChoicesÚModelResponsec                ó&   — t        d„ | D «       «      S )Nc              3  óH   K  — | ]  }t        |t        t        f«      –— Œ y ­w©N)Ú
isinstanceÚstrÚbytes©Ú.0Úchunks     úk/home/oem/CyberBrain26-unified/.venv/lib/python3.12/site-packages/litellm/proxy/guardrails/anthropic_sse.pyú	<genexpr>z$is_raw_sse_stream.<locals>.<genexpr>   s   è ø€ ÒG°5Œz˜%¤#¤u ×.ÑGùs   ‚ ")Úany)Ú
all_chunkss    r   Úis_raw_sse_streamr      s   € ÜÑG¸JÔGÓGÐGó    c                ót   — dj                  d„ | D «       «      }	 |j                  d«      S # t        $ r Y y w xY w)Nr   c              3  óŽ   K  — | ]=  }t        |t        t        f«      r%t        |t        «      r|n|j                  d «      –— Œ? y­w)úutf-8N)r   r   r   Úencoder   s     r   r   z%_joined_sse_stream.<locals>.<genexpr>   s=   è ø€ ò àÜ�eœc¤5˜\Ô*ô ˜E¤5Ô)‰¨u¯|©|¸GÓ/DÓDñùs   ‚AAr   )ÚjoinÚdecodeÚUnicodeDecodeError)r   Úraws     r   Ú_joined_sse_streamr       sC   € Ø—‘ñ àôó €Cð
Ø�z‰z˜'Ó"Ð"øÜò Ùðús   š+ «	7¶7c                ó`   ‡‡‡— ddl mŠ t        ˆˆˆfd„‰j                  | «      D «       d «      S )Nr   ©Ú"AnthropicPassthroughLoggingHandlerc              3  ó²   •K  — | ]N  }‰j                  |«      xŠ�9‰j                  d«      dk(  r%t        ‰j                  d«      xŠt        «      r‰–— ŒP y ­w)NÚtypeÚmessage_startÚmessage)Ú_extract_sse_dataÚgetr   Údict)r   Úeventr#   Ú
event_datar'   s     €€€r   r   z+_anthropic_message_start.<locals>.<genexpr>'   sY   øè ø€ ò 	
àØ@×RÑRÐSXÓYÐY�
ÐfØ—‘˜vÓ&¨/Ò9Ü j§n¡n°YÓ&?Ð?˜7ÄÔFô	 ñ	
ùs   ƒAA)Ú`litellm.proxy.pass_through_endpoints.llm_provider_handlers.anthropic_passthrough_logging_handlerr#   ÚnextÚ_split_sse_chunk_into_events)Ú
sse_streamr#   r,   r'   s    @@@r   Ú_anthropic_message_startr1   !   s5   ú€ õô õ	
à;×XÑXÐYcÓdô	
ð 	ó	ð 	r   F)Úrestore_identityc               óŽ  — ddl m} t        | «      }|€yt        |«      }|€y|r|j	                  d«      nd}	 |j                  |fdt        |t        «      r|nd¬«      }t        |t        «      sy|s|S |j	                  d«      }t        |t        «      r||_
        t        |t        «      r	|r||_        |S # t        $ r Y yw xY w)a¨  Assemble raw Anthropic SSE frames into a ModelResponse.

    ``restore_identity`` stamps the upstream message id and model onto the result, which the
    assembler does not carry through. It is off by default so callers that re-emit the assembled
    response keep the wire shape they had before this helper was shared. The writes land on a
    freshly built object that is unreachable from caller state until returned.
    r   r"   NÚmodelÚ )r   Úlitellm_logging_objr4   Úid)r-   r#   r    r1   r)   Ú"_build_complete_streaming_responser   r   Ú	Exceptionr   r7   r4   )r   r2   r#   r0   r&   r4   Ú	assembledÚ
message_ids           r   Úassemble_anthropic_sse_streamr<   2   sÚ   € õô +¨:Ó6€JØÐØÜ3°JÓ?€MØÐØÙ1A�=×$Ñ$ WÔ-Àt€EðØ=×`Ñ`Ø"�}Ø $Ü% e¬SÔ1‘%°rð aó 
ˆ	ô �i¤Ô/ØÙØÐØ%×)Ñ)¨$Ó/€JÜ�*œcÔ"Ø!ˆ	ŒÜ�%œÔ¡%Øˆ	ŒØÐøô ò Ùðús   ¹'B8 Â8	CÃCc                óF   — dj                  d„ | j                  D «       «      S )zLAssistant text of a response, used to detect whether a guardrail rewrote it.r5   c              3  ó°   K  — | ]N  }t        |t        «      r<t        |j                  j                  t        «      r|j                  j                  –— ŒP y ­wr   )r   r   r'   Úcontentr   )r   Úchoices     r   r   z&model_response_text.<locals>.<genexpr>]   s@   è ø€ ò àÜ�fœgÔ&Ü�v—~‘~×-Ñ-¬sÔ3ð 	�‰×Õñùs   ‚AA)r   Úchoices©Úresponses    r   Úmodel_response_textrD   [   s&   € à�7‰7ñ à×&Ñ&ôó ð r   c                óV   — t        j                  | «      }d|› d�j                  «       fS )zÔAnthropic error event, for a failure discovered after the response headers were flushed.

    Once a keepalive ping has been sent a raise cannot reach the client, so the failure has to
    travel as a frame.
    zUevent: error
data: {"type": "error", "error": {"type": "guardrail_error", "message": z}}

)ÚjsonÚdumpsr   )r'   Úbodys     r   Úanthropic_sse_error_framesrI   e   s4   € ô —*‘*˜WÓ%€DðØ�V˜8ð	%ß%+¡V£Xðð r   c                ó€   — ddl m} ddlm}  |«       j	                  | ¬«      }t         ||¬«      j                  «      S )Nr   )ÚLiteLLMAnthropicMessagesAdapter)Ú#FakeAnthropicMessagesStreamIteratorrB   )ÚHlitellm.llms.anthropic.experimental_pass_through.adapters.transformationrK   ÚNlitellm.llms.anthropic.experimental_pass_through.messages.fake_stream_iteratorrL   Ú&translate_openai_response_to_anthropicÚtupleÚchunks)r:   rK   rL   Úanthropic_responses       r   Ú"anthropic_sse_chunks_from_responserS   r   sF   € õõñ !@Ó A× hÑ hØð !ió !Ðô Ñ4Ð>PÔQ×XÑXÓYÐYr   )r   úSequence[object]ÚreturnÚbool)r   rT   rU   z
str | None)r0   r   rU   zMapping[str, object] | None)r   rT   r2   rV   rU   zModelResponse | None)rC   r   rU   r   )r'   r   rU   útuple[bytes, ...])r:   r   rU   rW   )Ú__doc__Ú
__future__r   rF   Úcollections.abcr   r   Útypingr   Úlitellm.types.utilsr   r   r   r    r1   r<   rD   rI   rS   © r   r   ú<module>r^      s_   ðñõ #ã ß -Ý ç 6óHó	óð$ ?Dñ&Ø ð&Ø7;ð&àó&óRó
ôZr   