Ë
    uPêjA  ã                  ó€  — U d Z ddlmZ ddlZddlZddlmZmZmZm	Z	 ddl
mZ ddlmZmZm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 ddl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%ddh«      Z&de'd<    eee(e)f   «      Z*de'd<   dZ+de'd<    e%h d£«      Z,de'd<    G d„ de«      Z- G d„ de«      Z. G d„ de«      Z/ G d„ d e«      Z0	 	 	 	 	 	 	 	 	 	 d;d!„Z1 G d"„ d#«      Z2 e2«       Z3d$e'd%<    ed&¬'«       G d(„ d)«      «       Z4 e4«       Z5d*e'd+<   e3e3e3d,œ	 	 	 	 	 	 	 d<d-„Z6d=d.„Z7d>d/„Z8d?d0„Z9d@d1„Z:dAd2„Z;	 	 	 	 	 	 dBd3„Z<	 	 	 	 	 	 	 	 	 	 	 	 	 	 dCd4„Z=dDd5„Z>	 	 	 	 	 	 	 	 dEd6„Z?	 	 	 	 	 	 dFd7„Z@	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dGd8„ZA	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dGd9„ZB	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dHd:„ZCy)Ia5  Thin Python wrapper for the native Rust chat completions bridge.

The Rust core owns the conversation translation, the provider call, and the
response normalization for the subset of `/chat/completions` requests it
accepts. This module only marshals inputs and hands the normalized result to
LiteLLM's existing `ModelResponse` builder.

``None`` means the provider was never called, so the caller is free to serve the
request on the Python path. A failure after the call was issued raises instead:
retrying it there would bill the customer for the same work twice.
é    )ÚannotationsN)Ú	AwaitableÚCallableÚMappingÚSequence)Ú	dataclass)ÚTYPE_CHECKINGÚFinalÚProtocol)ÚTypeAdapterÚValidationError)Úverbose_logger)ÚAPIError)Ú convert_to_model_response_object)Ú!bedrock_request_metadata_is_owned)Úget_native_bridge)Útimeout_to_seconds)ÚModelResponse)ÚLoggingÚ	anthropicÚbedrockr
   ÚRUST_CHAT_COMPLETIONS_PROVIDERSÚ_LITELLM_METADATA_ADAPTERzx-litellm-rustÚRUST_RESPONSE_HEADER>   Ú1ÚonÚyesÚtrueÚ_TRUTHY_ENV_VALUESc                  ó8   — e Zd Z	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dd„Zy)ÚRustChatCompletionsc	                ó   — t         ‚©N©ÚNotImplementedError©	ÚselfÚmodelÚmessagesÚoptional_paramsÚapi_keyÚapi_baseÚcustom_llm_providerÚextra_headersÚtimeout_secondss	            úi/home/oem/CyberBrain26-unified/.venv/lib/python3.12/site-packages/litellm/rust_bridge/chat_completions.pyÚ__call__zRustChatCompletions.__call__3   ó
   € ô "Ð!ó    N)r(   Ústrr)   úSequence[object]r*   úMapping[str, object] | Noner+   ú
str | Noner,   r7   r-   r7   r.   r6   r/   úfloat | NoneÚreturnúMapping[str, object]©Ú__name__Ú
__module__Ú__qualname__r1   © r3   r0   r!   r!   2   s_   „ ð"àð"ð #ð"ð 5ð	"ð
 ð"ð ð"ð (ð"ð 3ð"ð &ð"ð 
ô"r3   r!   c                  ó8   — e Zd Z	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dd„Zy)ÚRustAchatCompletionsc	                ó   — t         ‚r#   r$   r&   s	            r0   r1   zRustAchatCompletions.__call__B   r2   r3   N)r(   r4   r)   r5   r*   r6   r+   r7   r,   r7   r-   r7   r.   r6   r/   r8   r9   zAwaitable[Mapping[str, object]]r;   r?   r3   r0   rA   rA   A   s_   „ ð"àð"ð #ð"ð 5ð	"ð
 ð"ð ð"ð (ð"ð 3ð"ð &ð"ð 
)ô"r3   rA   c                  ó(   — e Zd Z	 	 	 	 	 	 	 	 	 	 dd„Zy)ÚRustChatCompletionsDeclinec                ó   — t         ‚r#   r$   )r'   r(   r)   r*   r-   s        r0   r1   z#RustChatCompletionsDecline.__call__Q   s
   € ô "Ð!r3   N)
r(   r4   r)   r5   r*   r6   r-   r7   r9   r7   r;   r?   r3   r0   rD   rD   P   s7   „ ð"àð"ð #ð"ð 5ð	"ð
 (ð"ð 
ô"r3   rD   c                  ó   — e Zd ZdZdd„Zy)ÚResponseObservera   Invoked with the payload the core returned, on success only.

    Lets the caller emit its own `post_call` on whichever path served the
    request. Both entry points call it, so the synchronous and asynchronous
    paths cannot drift apart the way the pre_call suppression once did.
    c               ó   — t         ‚r#   r$   )r'   Úrust_responses     r0   r1   zResponseObserver.__call__c   s   € Ü!Ð!r3   N©rI   r:   r9   ÚNone)r<   r=   r>   Ú__doc__r1   r?   r3   r0   rG   rG   [   s   „ ñô"r3   rG   c                ó    ‡ ‡‡‡— dˆˆˆ ˆfd„}|S )aÎ  A `ResponseObserver` that emits the caller's `post_call` for a Rust-served
    request.

    The core owns the provider call, so the Python transform that normally
    raises this event never runs; without it every `post_call` callback goes
    silent on a Rust-served request and `original_response` stays unset. The
    payload is the core's normalized response rather than the provider's wire
    body, which is the closest thing that crosses the bridge.
    c               óV   •— ‰j                  ‰‰t        j                  | «      ‰¬«       y )N)Úinputr+   Úoriginal_responseÚadditional_args)Ú	post_callÚjsonÚdumps)rI   rQ   r+   Úlogging_objr)   s    €€€€r0   Úlogzresponse_logger.<locals>.logx   s+   ø€ Ø×ÑØØÜ"Ÿj™j¨Ó7Ø+ð	 	õ 	
r3   rJ   r?   )rU   r)   r+   rQ   rV   s   ```` r0   Úresponse_loggerrW   g   s   û€ ÷"
ð 
ð €Jr3   c                  ó   — e Zd Zy)Ú_UnsetN)r<   r=   r>   r?   r3   r0   rY   rY   ƒ   s   „ Ør3   rY   zFinal[_Unset]Ú_UNSETT)Úslotsc                  ó8   — e Zd ZU dZded<   dZded<   dZded<   y)Ú_RustChatCompletionsStateNúRustChatCompletions | NoneÚchat_completionsúRustAchatCompletions | NoneÚachat_completionsú!RustChatCompletionsDecline | NoneÚdecline)r<   r=   r>   r_   Ú__annotations__ra   rc   r?   r3   r0   r]   r]   Š   s%   … à37ÐÐ0Ó7Ø59ÐÐ2Ó9Ø15€GÐ.Ô5r3   r]   z Final[_RustChatCompletionsState]Ú_STATE©r_   ra   rc   c                ó¨   — t        | t        «      s| t        _        t        |t        «      s|t        _        t        |t        «      s|t        _        yy)zdInject the native callables, so tests can supply a double instead of
    patching module attributes.N)Ú
isinstancerY   re   r_   ra   rc   rf   s      r0   Úset_rust_chat_completionsri   ”   s@   € ô Ð&¬Ô/Ø"2ŒÔÜÐ'¬Ô0Ø#4ŒÔ Ü�gœvÔ&Ø Œ�ð 'r3   c                 óz   — t         j                  �t         j                  S t        «       } | €y t        | dd «      }|S )Nr_   )re   r_   r   Úgetattr©Únative_bridgeÚloadeds     r0   Úload_rust_chat_completionsro   ¤   s@   € Ü×ÑÐ*Ü×&Ñ&Ð&Ü,Ó.€MØÐØÜ)0°Ð@RÐTXÓ)Y€FØ€Mr3   c                 óz   — t         j                  �t         j                  S t        «       } | €y t        | dd «      }|S )Nra   )re   ra   r   rk   rl   s     r0   Úload_rust_achat_completionsrq   ®   s@   € Ü×ÑÐ+Ü×'Ñ'Ð'Ü,Ó.€MØÐØÜ*1°-ÐATÐVZÓ*[€FØ€Mr3   c                 ór   — t        j                  dd«      j                  «       j                  «       t        v S )NÚLITELLM_RUSTÚ )ÚosÚgetenvÚstripÚlowerr   r?   r3   r0   Ú_env_enables_rustry   ¸   s+   € Ü�9‰9�^ RÓ(×.Ñ.Ó0×6Ñ6Ó8Ô<NÐNÐNr3   c                 óz   — t         j                  �t         j                  S t        «       } | €y t        | dd «      }|S )NÚchat_completions_decline)re   rc   r   rk   rl   s     r0   Ú_load_rust_decliner|   ¼   s<   € Ü‡~�~Ð!Ü�~‰~ÐÜ,Ó.€MØÐØÜ07¸ÐGaÐcgÓ0h€FØ€Mr3   c                óœ   — | �| j                  d«      nd }	 t        j                  |«      }|j                  d«      d uS # t        $ r Y yw xY w)NÚmetadataFÚuser_id)Úgetr   Úvalidate_pythonr   )Úlitellm_paramsr~   Úentriess      r0   Ú#_anthropic_user_id_reaches_the_bodyr„   Æ   sY   € Ø8FÐ8R�n×(Ñ(¨Ô4ÐX\€HðÜ2×BÑBÀ8ÓLˆð �;‰;�yÓ!¨Ð-Ð-øô ò Ùðús   —? ¿	AÁ
Ac                óF   — | xdk(  r t        |«      S dk(  r
t        «       S 	 y)a°  Whether the Python transform would promote proxy-owned attribution into the
    provider request, below this gate and inside the function the Rust route replaces.

    `AnthropicConfig.transform_request` promotes a valid `metadata["user_id"]`
    into the Messages body, so the core never sees the key and would send the
    request to Anthropic with the abuse-detection attribution missing.

    `AmazonConverseConfig` resolves proxy-owned `requestMetadata` onto the
    Converse body whenever the operator armed `bedrock_request_metadata_fields`.
    Owning that field also means evicting a caller-supplied one, which the core
    cannot do either, so ownership alone is the condition rather than whether
    anything resolved.

    Deliberately a superset of Python's condition in both cases: declining a
    request Python would not have attributed anyway costs only the Rust path,
    while missing one loses the attribution silently.
    r   r   F)r„   r   )r-   r‚   s     r0   Ú&_litellm_metadata_reaches_the_providerr†   Ï   s'   € ð( ÝÜ6°~ÓFÐFÛÜ4Ó6Ð6ØØr3   c                ó�  — |t         vry|ry|duxr |j                  d«      du }|st        «       syt        ||«      rt	        j
                  d«       yt        «       }|€y	  || |||¬«      }|�t	        j
                  d|«       yy# t        $ r3}	t	        j
                  dt        |	«      j                  «       Y d}	~	yd}	~	ww xY w)	a*  Whether the Rust path will serve this request.

    Asked before the caller commits to either path, so pre-call logging is
    emitted exactly once, on whichever path actually runs. The core's own
    capability gate answers the second half; it resolves no credentials and
    performs no I/O.
    FNÚrustTzPRust chat completions declined (litellm metadata user_id); using the Python path)r(   r)   r*   r-   z@Rust chat completions gate raised %s; staying on the Python pathz:Rust chat completions declined (%s); using the Python path)
r   r€   ry   r†   r   Údebugr|   Ú	ExceptionÚtyper<   )
r(   r)   r*   r-   r‚   ÚstreamÚopted_inrc   ÚreasonÚ
rust_errors
             r0   Úrust_chat_completions_acceptsr�   ì   sà   € ð  Ô"AÑAØÙØØ$¨DÐ0ÒW°^×5GÑ5GÈÓ5OÐSWÐ5W€HÙÔ-Ô/ØÜ-Ð.AÀ>ÔRÜ×ÑÐoÔpØÜ'Ó)€GØ€ØðÙØØØ+Ø 3ô	
ˆð ÐÜ×ÑÐYÐ[aÔbØØøô ò Ü×ÑØNÜ�Ó×%Ñ%ô	
ô ûðús   Á#B	 Â		CÂ)C Ã Cc                 ób   — t        «       } | €yt        | dd«      }t        | dd«      }|�|€y||fS )zJ`(declined, upstream_failed)` from the native module, or None when absent.NÚRustBridgeDeclinedÚRustUpstreamError)r   rk   )rm   ÚdeclinedÚupstreams      r0   Ú_rust_bridge_exceptionsr–     sJ   € ä,Ó.€MØÐØÜ˜mÐ-AÀ4ÓH€HÜ˜mÐ-@À$ÓG€HØÐ˜8Ð+ØØ�XÐÐr3   c               ót  — t        «       }|€*t        j                  dt        | «      j                  «       y|\  }}t        | |«      rM| j                  }|r|d   nd}t        |«      dkD  r|d   nd}t        t        |«      xs dd|› �|xs d|¬«      ‚t        | |«      s| ‚t        j                  d	| «       y)
aŒ  Re-raise a failure the provider already saw, or return so the caller declines.

    A request that never reached the provider is safe to serve on the Python
    path. One that did is not: the provider has already done the work, so a
    second attempt bills for it twice. Those surface as an `APIError` carrying
    the upstream status, which LiteLLM's exception mapping already understands.
    NzCRust chat completions bridge raised %s; falling back to Python pathr   é   rt   iô  zlitellm rust chat completions: )Ústatus_codeÚmessageÚllm_providerr(   zVRust chat completions declined before calling the provider (%s); using the Python path)
r–   r   r‰   r‹   r<   rh   ÚargsÚlenr   Úint)	r�   r(   r-   Ú
exceptionsr”   Úupstream_failedrœ   Ústatusrš   s	            r0   Ú_reraise_or_decliner¢   (  sÉ   € ô 0Ó1€JØÐÜ×ÑØQÜ�Ó×%Ñ%ô	
ð 	Ø *Ñ€HˆoÜ�*˜oÔ.Ø —o‘oˆÙ#'˜˜Qš¨QˆÜ$'¨£I°¢M˜˜aš°rˆÜÜ˜F›Ò* sØ5°g°YÐ?Ø,Ò2°Øô	
ð 	
ô �j (Ô+ØÐÜ×ÑØ`Øõr3   c                ó¦   — t        t        | «      |dt        dii¬«      }t        |t        «      s!t        dt        |«      j                  › �«      ‚|S )NÚadditional_headersr   )Úresponse_objectÚmodel_response_objectÚhidden_paramsz1expected a ModelResponse from the rust path, got )r   Údictr   rh   r   Ú	TypeErrorr‹   r<   )rI   Úmodel_responseÚbuilts      r0   Ú_build_model_responser¬   O  sW   € ô 4Ü˜]Ó+Ø,Ø+Ô.BÀFÐ-KÐLô€Eô
 �eœ]Ô+ÜÐKÌDÐQVËK×L`ÑL`ÐKaÐbÓcÐcØ€Lr3   c        
        óÀ   — t        «       }
|
€y 	  |
| ||||||t        |«      ¬«      } |	|«       t	        ||«      S # t        $ r}t        || |¬«       Y d }~y d }~ww xY w©N)r(   r)   r*   r+   r,   r-   r.   r/   )r(   r-   )ro   r   rŠ   r¢   r¬   )r(   r)   r*   rª   r+   r,   r-   r.   ÚtimeoutÚon_responseÚrust_chat_completionsrI   r�   s                r0   r_   r_   ]  s{   € ô $>Ó#?ÐØÐ$ØðÙ4ØØØ+ØØØ 3Ø'Ü.¨wÓ7ô	 
ˆñ �ÔÜ  °Ó?Ð?øô	 ò Ü˜J¨eÐI\Õ]Üûðús   �< ¼	AÁAÁAc        
      ƒ  óÜ   K  — t        «       }
|
€y 	  |
| ||||||t        |«      ¬«      ƒ d {  –—† } |	|«       t	        ||«      S 7 Œ# t        $ r}t        || |¬«       Y d }~y d }~ww xY w­wr®   )rq   r   rŠ   r¢   r¬   )r(   r)   r*   rª   r+   r,   r-   r.   r¯   r°   Úrust_achat_completionsrI   r�   s                r0   ra   ra     s‰   è ø€ ô %@Ó$AÐØÐ%ØðÙ%;ØØØ+ØØØ 3Ø'Ü.¨wÓ7ô	&
÷ 	 
ˆñ �ÔÜ  °Ó?Ð?ð	 
ùô ò Ü˜J¨eÐI\Õ]Üûðüs=   ‚A,‘A ­A®A ²A,ÁA Á	A)ÁA$ÁA,Á$A)Á)A,c              ƒ  ór   K  — t        | |||||||||	¬«
      ƒ d{  –—† }|�|S  |
«       ƒ d{  –—† S 7 Œ7 Œ­w)a„  Await the Rust path, falling back to the caller's own Python path when
    the bridge is unavailable or the call fails.

    The caller supplies the fallback, so the bridge stays free of provider
    dispatch. This exists because a caller that dispatches asynchronously has
    already returned a coroutine by the time a Rust failure surfaces, and so
    cannot fall back on its own.
    )
r(   r)   r*   rª   r+   r,   r-   r.   r¯   r°   N)ra   )r(   r)   r*   rª   r+   r,   r-   r.   r¯   r°   Úpython_fallbackÚresponses               r0   Úachat_completions_or_fallbackr·   ¡  sY   è ø€ ô, .ØØØ'Ø%ØØØ/Ø#ØØô÷ €Hð ÐØˆÙ Ó"×"Ð"ðøð #ús   ‚7›3œ7®5¯7µ7)
rU   ÚLiteLLMLoggingObjr)   r5   r+   r4   rQ   r:   r9   rG   )r_   z#RustChatCompletions | None | _Unsetra   z$RustAchatCompletions | None | _Unsetrc   z*RustChatCompletionsDecline | None | _Unsetr9   rK   )r9   r^   )r9   r`   )r9   Úbool)r9   rb   )r‚   r6   r9   r¹   )r-   r7   r‚   r6   r9   r¹   )r(   r4   r)   r5   r*   r:   r-   r7   r‚   r6   rŒ   Úobjectr9   r¹   )r9   z6tuple[type[BaseException], type[BaseException]] | None)r�   ÚBaseExceptionr(   r4   r-   r7   r9   rK   )rI   r:   rª   r   r9   r   )r(   r4   r)   r5   r*   r:   rª   r   r+   r7   r,   r7   r-   r7   r.   r6   r¯   úfloat | httpx.Timeout | Noner°   rG   r9   zModelResponse | None)r(   r4   r)   r5   r*   r:   rª   r   r+   r7   r,   r7   r-   r7   r.   r6   r¯   r¼   r°   rG   rµ   zCallable[[], Awaitable[object]]r9   rº   )DrL   Ú
__future__r   rS   ru   Úcollections.abcr   r   r   r   Údataclassesr   Útypingr	   r
   r   ÚhttpxÚpydanticr   r   Úlitellm._loggingr   Úlitellm.exceptionsr   ÚFlitellm.litellm_core_utils.llm_response_utils.convert_dict_to_responser   Ú%litellm.llms.bedrock.request_metadatar   Úlitellm.rust_bridge.loaderr   Úlitellm.rust_bridge.timeoutsr   Úlitellm.types.utilsr   Ú*litellm.litellm_core_utils.litellm_loggingr   r¸   Ú	frozensetr   rd   r4   rº   r   r   r   r!   rA   rD   rG   rW   rY   rZ   r]   re   ri   ro   rq   ry   r|   r„   r†   r�   r–   r¢   r¬   r_   ra   r·   r?   r3   r0   ú<module>rÌ      sÃ  ðò
õ #ã Û 	ß BÓ BÝ !ß 1Ñ 1ã ß 1å +Ý 'õõ TÝ 8Ý ;Ý -áÝWñ *3°KÀÐ3KÓ)LÐ  Ó Lñ $/¨w°s¸F°{Ñ/CÓ#DÐ ˜5Ó Dà.Ð �eÓ .á%Ò&@ÓAÐ �EÓ Aô"˜(ô "ô"˜8ô "ô" ô "ô	"�xô 	"ðà"ðð ðð ð	ð
 *ðð ó÷8	ñ 	ñ ›€ˆÓ  ñ �Ô÷6ð 6ó ð6ñ ,EÓ+F€Ð(Ó Fð
 =CØ>DØ:@ñ	!à9ð!ð <ð!ð 8ð	!ð
 
ó!ó óóOóó.ðØ#ðØ5Pðà	óð:-àð-ð ð-ð *ð	-ð
 $ð-ð 0ð-ð ð-ð 
ó-ó`	ð$Øð$ð ð$ð $ð	$ð
 
ó$ðNØ'ðà!ðð óð@àð@ð ð@ð *ð	@ð
 "ð@ð ð@ð ð@ð $ð@ð /ð@ð *ð@ð "ð@ð ó@ðD@àð@ð ð@ð *ð	@ð
 "ð@ð ð@ð ð@ð $ð@ð /ð@ð *ð@ð "ð@ð ó@ðD$#àð$#ð ð$#ð *ð	$#ð
 "ð$#ð ð$#ð ð$#ð $ð$#ð /ð$#ð *ð$#ð "ð$#ð 5ð$#ð ô$#r3   