Ë
    uPêjV  ã                   ó  — U d dl 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	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 d
dlmZ d
dlmZ d
dlmZ d
dlm Z   e«       Z!ee"d<   de	jF                  de$fd„Z% G d„ d«      Z&y)é    N)Údatetime)ÚMappingProxyType)ÚAnyÚFinal)Úurlparse)ÚLogging)Ú&PassThroughEndpointLoggingResultValues)Ú!PassthroughStandardLoggingPayload)Ú!StandardPassThroughResponseObjecté   )Ú"AnthropicPassthroughLoggingHandler)Ú#AssemblyAIPassthroughLoggingHandler)ÚCoherePassthroughLoggingHandler)ÚCursorPassthroughLoggingHandler)ÚGeminiPassthroughLoggingHandler)ÚVertexPassthroughLoggingHandler)Úhas_upstream_reported_usageÚ"cohere_passthrough_logging_handlerÚhttpx_responseÚreturnc                 óN   — 	 | j                   S # t        j                  $ r Y yw xY w)zö
    Streamed passthrough responses are relayed to the client without being read
    into memory, so accessing .text on them raises ResponseNotRead. Their body is
    intentionally uninspected; log an empty string instead of failing the row.
    Ú )ÚtextÚhttpxÚResponseNotRead)r   s    úy/home/oem/CyberBrain26-unified/.venv/lib/python3.12/site-packages/litellm/proxy/pass_through_endpoints/success_handler.pyÚ_safe_response_textr   '   s+   € ðØ×"Ñ"Ð"øÜ× Ñ ò Ùðús   ‚ Ž$£$c                   óò  — e Zd Zd„ Zdedeez  ez  dede	de	de
fd„Z	 d!d
ej                  deeeeef      z  d	z  dedededede	de	de
ded	z  fd„Z	 d!d
ej                  deeeeef      z  d	z  dededede	de	de
dededed	z  fd„Zdede
fd„Zdefd„Zdede
fd„Zdefd„Zded	z  de
fd„Zded	z  de
fd„Zdefd„Zdefd„Zd!deded	z  fd„Zdefd„Zd!deded	z  fd„Zdede
fd„Zdededefd „Zy	)"ÚPassThroughEndpointLoggingc                 ó¦   — d| _         d| _        ddg| _        ddg| _        t	        «       | _        dg| _        g d¢| _        g d	¢| _        d
g| _	        y )N)	ÚgenerateContentÚstreamGenerateContentÚpredictÚ
rawPredictÚstreamRawPredictÚsearchÚpredictLongRunningÚembedContentÚbatchEmbedContents)ÚbatchPredictionJobsz	/messagesz/v1/messages/batchesz/v2/chatú	/v1/embedz
/langfuse/)r!   r"   r'   )z
/v0/agentsz/v0/mez
/v0/modelsz/v0/repositoriesz/vertex_ai/live)
ÚTRACKED_VERTEX_METHOD_ROUTESÚTRACKED_VERTEX_RESOURCE_ROUTESÚTRACKED_ANTHROPIC_ROUTESÚTRACKED_COHERE_ROUTESr   Ú&assemblyai_passthrough_logging_handlerÚTRACKED_LANGFUSE_ROUTESÚTRACKED_GEMINI_ROUTESÚTRACKED_CURSOR_ROUTESÚTRACKED_VERTEX_AI_LIVE_ROUTES)Úselfs    r   Ú__init__z#PassThroughEndpointLogging.__init__4   so   € ð
-
ˆÔ)ð /GˆÔ+ð *5Ð6LÐ(MˆÔ%ð '1°+Ð%>ˆÔ"Ü6YÓ6[ˆÔ3ð )5 ~ˆÔ$ò&
ˆÔ"ò&
ˆÔ"ð /@Ð-@ˆÕ*ó    Úlogging_objÚ standard_logging_response_objectÚresultÚ
start_timeÚend_timeÚ	cache_hitc           	   ‹   óš   K  —  |j                   dt        |t        «      rt        j                  |«      n|||dddœ|¤Žƒ d{  –—†  y7 Œ­w)z<Log pass-through success via the shared async dispatch path.FT)r:   r;   r<   r=   Úprefer_async_handlersN© )Údispatch_success_handlersÚ
isinstanceÚdictÚjsonÚdumps)r5   r8   r9   r:   r;   r<   r=   Úkwargss           r   Ú_handle_loggingz*PassThroughEndpointLogging._handle_logging^   sU   è ø€ ð( 4ˆk×3Ñ3ð 
Ü*4°V¼TÔ*B”D—J‘J˜vÔ&ÐHhØ!ØØØ"&ñ
ð ñ
÷ 	
ò 	
ús   ‚AAÁA	ÁANr   Úresponse_bodyÚrequest_bodyÚ	url_routeÚcustom_llm_providerc                 óª  — d |dœ}d }| j                  ||
«      r=t        j                  d|t        |t        «      r|ni ||||||	|dœ	|¤Ž}|d   }|d   }�nr| j                  |«      r*t        j                  d|||||||	|dœ|¤Ž}|d   }|d   }�n7| j                  |«      r=t        j                  d|t        |t        «      r|ni ||||||	|dœ	|¤Ž}|d   }|d   }�né| j                  |«      r=t        j                  d|t        |t        «      r|ni ||||||	|dœ	|¤Ž}|d   }|d   }�n›| j                  |«      rQ| j                  |«      r@ddlm}  |j$                  d|t        |t        «      r|ni ||||||	|dœ	|¤Ž}|d   }|d   }�n9| j'                  ||
«      r<t)        j*                  d|t        |t        «      r|ni ||||||	|dœ	|¤Ž}|d   }|d   }në| j-                  |
«      r,ddlm}  |j2                  d|||||||	|dœ|¤Ž}|d   }|d   }n®| j5                  |
«      rHdd	lm}  |j:                  d|t        |t        «      r|n
t=        i «      ||||||	|dœ	|¤Ž}|d   }|d   }nU| j?                  |«      rDdd
l m!}  |«       }t        |tD        «      r|ng } |jF                  d||||||dœ|¤Ž}|d   }|d   }||d<   ||d<   |S )N)r9   rF   )	r   rH   r8   rJ   r:   r;   r<   r=   rI   r:   rF   )r   r8   rJ   r:   r;   r<   r=   rI   r   ©ÚOpenAIPassthroughLoggingHandler)Ú*ComprehendMedicalPassthroughLoggingHandler)Ú!TypeSafePassthroughLoggingHandler)Ú%VertexAILivePassthroughLoggingHandler)Úwebsocket_messagesr8   rJ   r;   r<   rI   r9   r@   )$Úis_gemini_router   Úgemini_passthrough_handlerrB   rC   Úis_vertex_router   Úvertex_passthrough_handlerÚis_anthropic_router   Úanthropic_passthrough_handlerÚis_cohere_router   Úcohere_passthrough_handlerÚis_openai_routeÚ_is_supported_openai_endpointÚ8llm_provider_handlers.openai_passthrough_logging_handlerrN   Úopenai_passthrough_handlerÚis_cursor_router   Úcursor_passthrough_handlerÚis_comprehend_medical_routeÚDllm_provider_handlers.comprehend_medical_passthrough_logging_handlerrO   Ú&comprehend_medical_passthrough_handlerÚis_typesafe_routeÚ:llm_provider_handlers.typesafe_passthrough_logging_handlerrP   Útypesafe_passthrough_handlerr   Úis_vertex_ai_live_routeÚ@llm_provider_handlers.vertex_ai_live_passthrough_logging_handlerrQ   ÚlistÚ"vertex_ai_live_passthrough_handler)r5   r   rH   rI   r8   rJ   r:   r;   r<   r=   rK   rF   Úreturn_dictr9   Ú)gemini_passthrough_logging_handler_resultÚ)vertex_passthrough_logging_handler_resultÚ,anthropic_passthrough_logging_handler_resultÚ)cohere_passthrough_logging_handler_resultrN   Ú)openai_passthrough_logging_handler_resultÚ)cursor_passthrough_logging_handler_resultrO   Ú!comprehend_medical_handler_resultrP   Útypesafe_handler_resultrQ   Úvertex_ai_live_handlerrR   Úvertex_ai_live_handler_results                                r   Ú)normalize_llm_passthrough_logging_payloadzDPassThroughEndpointLogging.normalize_llm_passthrough_logging_payload{   sJ  € ð 15Øñ
ˆð 8<Ð(à×Ñ 	Ð+>Ô?Ü8W×8rÑ8rð 9Ø-Ü/9¸-ÌÔ/N™mÐTVØ'Ø#ØØ%Ø!Ø#Ø)ñ9ð ñ9Ð5ð 0YÐYaÑ/bÐ,Ø>¸xÑHŠFØ×!Ñ! )Ô,Ü8W×8rÑ8rð 
9Ø-Ø'Ø#ØØ%Ø!Ø#Ø)ñ
9ð ñ
9Ð5ð 0YÐYaÑ/bÐ,Ø>¸xÑHŠFØ×$Ñ$ YÔ/ä2×PÑPð Ø#1Ü3=¸mÌTÔ3R¡-ÐXZØ +Ø'Ø!Ø)Ø%Ø'Ø!-ñð ñð 9ð 0\Ð\dÑ/eÐ,ØAÀ(ÑKŠFØ×!Ñ! )Ô,Ü8Z×8uÑ8uð 9Ø-Ü/9¸-ÌÔ/N™mÐTVØ'Ø#ØØ%Ø!Ø#Ø)ñ9ð ñ9Ð5ð 0YÐYaÑ/bÐ,Ø>¸xÑHŠFØ×!Ñ! )Ô,°×1SÑ1SÐT]Ô1^õð 9sÐ8W×8rÑ8rð 9Ø-Ü/9¸-ÌÔ/N™mÐTVØ'Ø#ØØ%Ø!Ø#Ø)ñ9ð ñ9Ð5ð 0YÐYaÑ/bÐ,Ø>¸xÑHŠFà×!Ñ! )Ð-@ÔAÜ8W×8rÑ8rð 9Ø-Ü/9¸-ÌÔ/N™mÐTVØ'Ø#ØØ%Ø!Ø#Ø)ñ9ð ñ9Ð5ð 0YÐYaÑ/bÐ,Ø>¸xÑH‰FØ×-Ñ-Ð.AÔBõð
 bÐ:×aÑað 
Ø#1Ø +Ø'Ø!Ø)Ø%Ø'Ø!-ñ
ð ñ
ð .ð 0QÐQYÑ/ZÐ,Ø6°xÑ@‰FØ×#Ñ#Ð$7Ô8õð .lÐ-N×-kÑ-kð .Ø-Ü/9¸-ÌÔ/N™mÔTdÐegÓThØ'Ø#ØØ%Ø!Ø#Ø)ñ.ð ñ.Ð#ð 0GÀxÑ/PÐ,Ø,¨XÑ6‰FØ×)Ñ)¨)Ô4õñ -RÓ,SÐ"ô PZÐZgÔimÔOn¹mÐtvÐà3lÐ3I×3lÑ3lð 4Ø#5Ø'Ø#Ø%Ø!Ø)ñ4ð ñ4Ð)ð 0MÈXÑ/VÐ,Ø2°8Ñ<ˆFØ:ZˆÐ6Ñ7à &ˆ�HÑØÐr7   Úpassthrough_logging_payloadc              ‹   ó(  K  — d }|
|j                   d<   | j                  |«      rdt        j                  |j                  j
                  «      dury  | j                  j                  d
|t        |t        «      r|ni ||||||dœ|¤Ž y | j                  |«      ry  | j                  d
|||	|||||||dœ
|¤Ž}|d   }|d   }|€t        t        |«      ¬«      }| j                  ||
|¬«      } | j                  d
|||||||
d	œ|¤Žƒ d {  –—†  y 7 Œ­w)Nrw   T)r   rH   r8   rJ   r:   r;   r<   r=   )
r   rH   rI   r8   rJ   r:   r;   r<   r=   rK   r9   rF   )Úresponse)r8   rw   rF   )r8   r9   r:   r;   r<   r=   Ú%standard_pass_through_logging_payloadr@   )Úmodel_call_detailsÚis_assemblyai_router   Ú_should_log_requestÚrequestÚmethodr0   rB   rC   Úis_langfuse_routerv   r   r   Ú_set_cost_per_requestrG   )r5   r   rH   r8   rJ   r:   r;   r<   r=   rI   rw   rK   rF   r9   Ú*normalized_llm_passthrough_logging_payloads                  r   Ú"pass_through_async_success_handlerz=PassThroughEndpointLogging.pass_through_async_success_handler2  s‹  è ø€ ð [_Ð(ØHcˆ×&Ñ&Ð'DÑEØ×#Ñ# IÔ.Ü2×FÑFÀ~×G]ÑG]×GdÑGdÓeÐmqÑqØØ^ˆD×7Ñ7×^Ñ^ð 
Ø-Ü/9¸-ÌÔ/N™mÐTVØ'Ø#ØØ%Ø!Ø#ñ
ð ò
ð Ø×#Ñ# IÔ.àà@nÀ×@nÑ@nð AØ-Ø+Ø)Ø'Ø#ØØ%Ø!Ø#Ø$7ñAð ñAÐ6ð 0ZØ2ñ0Ð,ð @ÀÑIˆFØ+Ð3Ü/PÜ,¨^Ó<ô0Ð,ð ×+Ñ+Ø#Ø(CØð ,ó 
ˆð #ˆd×"Ñ"ð 	
Ø#Ø-MØØ!ØØØ2Mñ	
ð ñ	
÷ 		
ò 		
ús   ‚DDÄ
DÄDr   c                 ó~   ‡— t        ˆfd„| j                  D «       «      ryt        ˆfd„| j                  D «       «      S )Nc              3   ó,   •K  — | ]  }d |› �‰v –— Œ y­w)ú:Nr@   )Ú.0r   rJ   s     €r   ú	<genexpr>z=PassThroughEndpointLogging.is_vertex_route.<locals>.<genexpr>~  s   øè ø€ ÒY¨V��6�(ˆ|˜yÔ(ÑYùs   ƒTc              3   ó&   •K  — | ]  }|‰v –— Œ
 y ­w©Nr@   )r‡   ÚresourcerJ   s     €r   rˆ   z=PassThroughEndpointLogging.is_vertex_route.<locals>.<genexpr>€  s   øè ø€ Ò]¨X�8˜yÔ(Ñ]ùs   ƒ)Úanyr,   r-   )r5   rJ   s    `r   rU   z*PassThroughEndpointLogging.is_vertex_route}  s1   ø€ ÜÓY°t×7XÑ7XÔYÔYØÜÓ]¸×9\Ñ9\Ô]Ó]Ð]r7   c                 ó2   — | j                   D ]  }||v sŒ y y©NTF)r.   ©r5   rJ   Úroutes      r   rW   z-PassThroughEndpointLogging.is_anthropic_route‚  s'   € Ø×2Ñ2ò 	ˆEØ˜	Ò!Ùð	ð r7   c                 óF   — | j                   D ]  }||vrŒ|dk(  rd|v rŒ y y)Nr+   z/v1/embeddingsTF)r/   r�   s      r   rY   z*PassThroughEndpointLogging.is_cohere_routeˆ  s=   € Ø×/Ñ/ò 	ˆEØ˜IÑ%ØØ˜Ò#Ð(8¸IÑ(EØÙð	ð r7   c                 óV   — t        |«      }|j                  dk(  sd|j                  v ryy)Nzapi.assemblyai.comz/transcriptTF)r   ÚhostnameÚpath)r5   rJ   Ú
parsed_urls      r   r|   z.PassThroughEndpointLogging.is_assemblyai_route‘  s,   € Ü$ YÓ/ˆ
Ø×ÑÐ"6Ò6¸-È:Ï?É?Ñ:ZØØr7   c                 ó   — |dk(  S )NÚcomprehendmedicalr@   ©r5   rK   s     r   ra   z6PassThroughEndpointLogging.is_comprehend_medical_route—  s   € Ø"Ð&9Ñ9Ð9r7   c                 ó   — |dk(  S )NÚtypesafer@   r˜   s     r   rd   z,PassThroughEndpointLogging.is_typesafe_routeš  s   € Ø" jÑ0Ð0r7   c                 ó\   — t        |«      }| j                  D ]  }||j                  v sŒ y yrŽ   )r   r1   r”   )r5   rJ   r•   r�   s       r   r€   z,PassThroughEndpointLogging.is_langfuse_route�  s5   € Ü$ YÓ/ˆ
Ø×1Ñ1ò 	ˆEØ˜
Ÿ™Ò'Ùð	ð r7   c                 ó8   — |sy| j                   D ]  }||v sŒ y y)z?Check if the URL route is a Vertex AI Live API WebSocket route.FT)r4   r�   s      r   rg   z2PassThroughEndpointLogging.is_vertex_ai_live_route¤  s-   € áØØ×7Ñ7ò 	ˆEØ˜	Ò!Ùð	ð r7   c                 óì   — |dk(  ryt        |«      }|j                  rd|j                  v ry| j                  D ]9  }||v sŒ|j                  r|j                  n|}|j                  d«      sŒ4|dk(  c S  y)z:Check if the URL route is a Cursor Cloud Agents API route.ÚcursorTzapi.cursor.comz/v0/F)r   r“   r3   Úschemer”   Ú
startswith)r5   rJ   rK   r•   r�   r”   s         r   r_   z*PassThroughEndpointLogging.is_cursor_route­  s}   € à (Ò*ØÜ$ YÓ/ˆ
Ø×ÒÐ#3°z×7JÑ7JÑ#JØØ×/Ñ/ò 	;ˆEØ˜	Ò!Ø*4×*;Ò*;�z—’À�Ø—?‘? 6Õ*Ø.°(Ñ:Ò:ð		;ð
 r7   c                 ó$   — |syddl m}  ||«      S )a)  Check if the URL route is an OpenAI API route.

        Uses the URL-aware helper so that non-OpenAI Azure Cognitive Services
        (Speech, Vision, Language, ...) sharing the `*.cognitiveservices.azure.com`
        / `*.openai.azure.com` domains are not misclassified as OpenAI routes.
        Fr   )Ú_is_openai_compatible_url)r]   r¢   )r5   rJ   r¢   s      r   r[   z*PassThroughEndpointLogging.is_openai_route»  s   € ñ Øõ	
ñ )¨Ó3Ð3r7   c                 ó>   — | j                   D ]  }||v sŒ|dk(  sŒ y y)z-Check if the URL route is a Gemini API route.ÚgeminiTF)r2   )r5   rJ   rK   r�   s       r   rS   z*PassThroughEndpointLogging.is_gemini_routeÊ  s/   € à×/Ñ/ò 	ˆEØ˜	Ò!Ð&9¸XÓ&EÙð	ð r7   c                 óÈ   — ddl m} |j                  |«      xsJ |j                  |«      xs7 |j	                  |«      xs$ |j                  |«      xs |j                  |«      S )u3  Check if the OpenAI endpoint is supported by the passthrough logging handler.

        The Responses API route is included because
        `openai_passthrough_handler` has a dedicated `elif is_responses:`
        branch that knows how to extract usage + cost from the
        Responses-API on-the-wire shape. Without including it here, the
        outer dispatch filters Responses calls out before reaching the
        handler â€” the inner branch is then unreachable and Responses
        calls land in `LiteLLM_SpendLogs` with zero tokens / zero spend.
        r   rM   )r]   rN   Ú is_openai_chat_completions_routeÚis_openai_embeddings_routeÚ is_openai_image_generation_routeÚis_openai_image_editing_routeÚis_openai_responses_route)r5   rJ   rN   s      r   r\   z8PassThroughEndpointLogging._is_supported_openai_endpointÑ  sq   € õ	
ð
 ,×LÑLÈYÓWò TØ.×IÑIÈ)ÓTòTà.×OÑOÐPYÓZòTð /×LÑLÈYÓWòTð /×HÑHÈÓSð	
r7   rF   c                 ó¦   — t        |«      r|S |j                  d«      �2|j                  d«      |d<   |j                  d«      |j                  d<   |S )a¸  
        Helper function to set the cost per request in the logging object

        Only set the cost per request if it's set in the passthrough logging payload.
        If it's not set, don't set it in the logging object.

        An upstream that prices its own requests always wins: ``cost_per_request``
        is a flat per-request estimate for targets LiteLLM cannot price, and it
        defaults to 0.0 on every config-defined endpoint, so honoring it here
        would zero out the real cost the upstream reported. That holds even when
        the reported value was unusable, where the contract records 0 rather
        than billing an estimate the upstream just contradicted.
        Úcost_per_requestÚresponse_cost)r   Úgetr{   )r5   r8   rw   rF   s       r   r�   z0PassThroughEndpointLogging._set_cost_per_requestè  sZ   € ô, ' {Ô3ØˆMà&×*Ñ*Ð+=Ó>ÐJØ&A×&EÑ&EÐFXÓ&YˆF�?Ñ#Ø>Y×>]Ñ>]Ð^pÓ>qˆK×*Ñ*¨?Ñ;àˆr7   rŠ   ) Ú__name__Ú
__module__Ú__qualname__r6   ÚLiteLLMLoggingObjr   r	   rC   Ústrr   ÚboolrG   r   ÚResponseri   Úobjectrv   r
   rƒ   rU   rW   rY   r|   ra   rd   r€   rg   r_   r[   rS   r\   r�   r@   r7   r   r   r   3   sŒ  „ ò(AðT
à&ð
ð +LØ
0ñ+1à
ñ+ð
ð ð
ð ð
ð ð
ð ó
ðP +/ñuàŸ™ðuð ˜d 4¨¨V¨Ñ#4Ñ5Ñ5¸Ñ<ðuð ð	uð
 'ðuð ðuð ðuð ðuð ðuð ðuð ! 4™ZóuðF +/ñI
àŸ™ðI
ð ˜d 4¨¨V¨Ñ#4Ñ5Ñ5¸Ñ<ðI
ð 'ð	I
ð
 ðI
ð ðI
ð ðI
ð ðI
ð ðI
ð ðI
ð &GðI
ð ! 4™ZóI
ðV^¨ð ^°ó ^ð
¨Có ð¨ð °ó ð¨Só ð:¸sÀT¹zð :Èdó :ð1°S¸4±Zð 1ÀDó 1ð¨3ó ð°ó ñ¨ð À3ÈÁ:ó ð4¨ó 4ñ¨ð À3ÈÁ:ó ð
°sð 
¸tó 
ð.à&ðð &Gðð ô	r7   r   )'rD   r   Útypesr   Útypingr   r   Úurllib.parser   r   Ú*litellm.litellm_core_utils.litellm_loggingr   r²   Úlitellm.proxy._typesr	   Ú:litellm.types.passthrough_endpoints.pass_through_endpointsr
   Úlitellm.types.utilsr   Ú;llm_provider_handlers.anthropic_passthrough_logging_handlerr   Ú:llm_provider_handlers.assembly_passthrough_logging_handlerr   Ú8llm_provider_handlers.cohere_passthrough_logging_handlerr   Ú8llm_provider_handlers.cursor_passthrough_logging_handlerr   Ú8llm_provider_handlers.gemini_passthrough_logging_handlerr   Ú8llm_provider_handlers.vertex_passthrough_logging_handlerr   Úupstream_usage_headersr   r   Ú__annotations__rµ   r³   r   r   r@   r7   r   ú<module>rÆ      s}   ðÜ Ý Ý "ß Ý !ã å SÝ Gõõ Bõõõõõõõ @á,KÓ,MÐ " EÓ Mð	¨¯©ð 	¸3ó 	÷Rò Rr7   