Ë
    tPêjø¯  ã                   óÂ  — U d dl Z d dlZd dlmZmZ d dlmZmZmZm	Z	m
Z
 d dl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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"m#Z# er4d 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l0m1Z1m2Z2m3Z3 d dl4m5Z5 e(ez  Z'neZ'eZ-eZ/eZ1eZ2eZ3eZ6e	e7d<   eZ8e	e7d<   eZ5 e jr                  de jt                  «      Z;e	e7d<    G d„ d«      Z<y)é    N)ÚAsyncGeneratorÚMapping)ÚTYPE_CHECKINGÚAnyÚClassVarÚFinalÚOptional)Ú	BaseModel©Úverbose_logger)Ú/DEFAULT_MAX_RECURSE_DEPTH_SENSITIVE_DATA_MASKER)ÚArgillaItem©ÚAgenticLoopPlan)ÚAllMessageValuesÚChatCompletionRequest)Ú
PromptSpec)	ÚAdapterCompletionStreamWrapperÚ	CallTypesÚCallTypesLiteralÚLLMResponseTypesÚModelResponseÚModelResponseStreamÚStandardAuditLogPayloadÚStandardCallbackDynamicParamsÚStandardLoggingPayload)ÚHTTPException)ÚSpan)Ú	DualCache)ÚLogging)ÚUserAPIKeyAuth)ÚMCPPostCallResponseObjectÚMCPPreCallRequestObjectÚMCPPreCallResponseObject)ÚPreRoutingHookResponseÚMCPDuringCallRequestObjectÚMCPDuringCallResponseObjectzOdata:(?:application|image|audio|video)/[a-zA-Z0-9.+-]+;base64,[A-Za-z0-9+/=\s]+Ú_BASE64_INLINE_PATTERNc                    ó>  — e Zd ZU  e«       Zeee      ed<   dZe	ed<   	 	 	 d‡de	de	ddfd„Z
edˆd	edz  dee   fd
„«       Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zdededededz  fd„Zd„ Zd„ Zd‰d„Z	 	 	 	 	 	 dŠdedee   dededz  dedz  dedededz  dee   dz  d edz  d!edz  d"e	dz  d#e	dz  deeee   ef   fd$„Z 	 	 	 	 	 d‹dedee   dededz  dedz  dededz  d edz  d!edz  d"e	dz  d#e	dz  deeee   ef   fd%„Z!	 	 	 	 dŒded&edeeee"f      dz  d'eez  dz  d(e	dz  de#dz  fd)„Z$	 	 d�ded*edee   dz  d&edz  d+e%dz  dee   fd,„Z&deee"f   d-e'dz  dedz  fd.„Z(d/ed+e%dz  dedz  fd0„Z)d/ededz  fd1„Z*d2ed3e+d-e'dz  de+dz  fd4„Z,	 dˆd2e-ee.f   d5e/d-e'dz  d6edz  ddf
d7„Z0d2ed8e"d-e'dz  de"dz  fd9„Z1d5e/d:edz  defd;„Z2d:eded<e/fd=„Z3d:eded<e/fd>„Z4de5dz  fd?„Z6d3e7de8dz  fd@„Z9dAe"de:dz  fdB„Z;dCe<dDe=dz  de<dz  fdE„Z>	 dFe?dGdHdIed-e@de/ez  ez  dz  f
dJ„ZA	 	 d�dIedFe?d3e"dKeeef   dz  dLeee"f   dz  deeef   dz  fdM„ZB	 dˆd2ed<e/dFe?dNedz  deCdO   f
dP„ZDdIedFe?d3e+de"fdQ„ZEdedRe"d-edeee"f   fdS„ZFdedRe"d-edeee"f   fdT„ZGdIedFe?d-e@de"fdU„ZHdFe?d3ede"fdV„ZIdFe?d3e"d2edeJeKdf   fdW„ZLdX„ ZMdY„ ZNdZ„ ZOd[„ ZPd\eQdeQdz  fd]„ZRd3e"dedee   dee   dz  d^e	d_ededee	ef   fd`„ZSdededee   d3e"dae"dbedcddd^e	dede"fde„ZTdededee   d3e"dae"dbedcddd^e	dedeUfdf„ZVd3e"dgeUdede"fdh„ZWdgeUdeddfdi„ZXd3e"dedee   dee   dz  d^e	d_ededee	ef   fdj„ZYdededee   d3e"dkedcddd^e	dede"fdl„ZZdededee   d3e"dkedcddd^e	dedeUfdm„Z[dne=fdo„Z\dne=dpedqeddfdr„Z]dsedqedefdt„Z^dˆd&edz  dedz  fdu„Z_dvedefdw„Z`dxededz  fdy„Zad	efdz„Zbecfd{d|d}edd|fd~„Zdecfd{d|d}edd|fd„Zed€ecfd�e"d‚ed}ede"fdƒ„Zfd„e"de	fd…„Zgecfdee"   d}edeeee"f      fd†„Zhy)ŽÚCustomLoggerÚserver_fulfilled_tool_namesFÚenforces_request_contentÚturn_off_message_loggingÚmessage_loggingÚreturnNc                 ó    — || _         || _        y)a  
        Args:
            turn_off_message_logging: bool - if True, the message logging will be turned off. Message and response will be redacted from StandardLoggingPayload.
            message_logging: bool - deprecated param, use `turn_off_message_logging` instead
        N)r.   r-   )Úselfr-   r.   Úkwargss       úg/home/oem/CyberBrain26-unified/.venv/lib/python3.12/site-packages/litellm/integrations/custom_logger.pyÚ__init__zCustomLogger.__init__S   s   € ð  /ˆÔØ(@ˆÕ%ó    Úcallback_namec                 óî   — | €g S | j                  «       }ddi}|j                  ||«      }	 ddlm}  |«       }t        ||d«      }|€g S t        |dd«      }|sg S t        |«      S # t        $ r g cY S w xY w)a2  
        Return the environment variables associated with a given callback
        name as defined in the proxy callback registry.

        Args:
            callback_name: The name of the callback to look up.

        Returns:
            List[str]: A list of required environment variable names.
        NÚlangfuse_otelÚlangfuser   )ÚAllCallbacksÚlitellm_callback_params)ÚlowerÚgetÚlitellm.proxy._typesr:   Ú	ExceptionÚgetattrÚlist)r6   Únormalized_nameÚ	alias_mapÚlookup_namer:   Ú	callbacksÚcallback_infoÚparamss           r3   Úget_callback_env_varsz"CustomLogger.get_callback_env_varsb   sž   € ð Ð ØˆIà!.×!4Ñ!4Ó!6ˆð ˜Zð
ˆ	ð 'Ÿ]™]¨?¸OÓLˆð	Ý9ñ (›>ˆ	Ü& y°+¸tÓDˆØÐ ØˆIä Ð/HÈ$ÓOˆÙØˆIä�F‹|Ðøô ò 	ØŠIð	ús   ¬A& Á&A4Á3A4c                  ó   — y ©N© ©r1   ÚmodelÚmessagesr2   s       r3   Úlog_pre_api_callzCustomLogger.log_pre_api_callˆ   ó   € Ør5   c                  ó   — y rJ   rK   ©r1   r2   Úresponse_objÚ
start_timeÚend_times        r3   Úlog_post_api_callzCustomLogger.log_post_api_call‹   rP   r5   c                  ó   — y rJ   rK   rR   s        r3   Úlog_stream_eventzCustomLogger.log_stream_eventŽ   rP   r5   c                  ó   — y rJ   rK   rR   s        r3   Úlog_success_eventzCustomLogger.log_success_event‘   rP   r5   c                  ó   — y rJ   rK   rR   s        r3   Úlog_failure_eventzCustomLogger.log_failure_event”   rP   r5   c              ƒ   ó   K  — y ­wrJ   rK   rR   s        r3   Úasync_log_stream_eventz#CustomLogger.async_log_stream_event™   ó	   è ø€ Øùó   ‚c              ƒ   ó   K  — y ­wrJ   rK   rL   s       r3   Úasync_log_pre_api_callz#CustomLogger.async_log_pre_api_callœ   r_   r`   rM   rN   r2   c              ƒ   ó   K  — y­w)aŽ  
        Hook called before making the API request to allow modifying request parameters.

        This is specifically designed for modifying the request before it's sent to the provider.
        Unlike async_log_pre_api_call (which is for logging), this hook is meant for transformations.

        Args:
            model: The model name
            messages: The messages list
            kwargs: The request parameters (tools, stream, temperature, etc.)

        Returns:
            Optional[Dict]: Modified kwargs to use for the request, or None if no modifications

        Example:
            ```python
            async def async_pre_request_hook(self, model, messages, kwargs):
                # Convert native tools to standard format
                if kwargs.get("tools"):
                    kwargs["tools"] = convert_tools(kwargs["tools"])
                return kwargs
            ```
        NrK   rL   s       r3   Úasync_pre_request_hookz#CustomLogger.async_pre_request_hookŸ   ó   è ø� ùr`   c              ƒ   ó   K  — y ­wrJ   rK   rR   s        r3   Úasync_log_success_eventz$CustomLogger.async_log_success_event¸   r_   r`   c              ƒ   ó   K  — y ­wrJ   rK   rR   s        r3   Úasync_log_failure_eventz$CustomLogger.async_log_failure_event»   r_   r`   c              ƒ   ó   K  — y­w)zFCalled when an audit log is created. Override in subclasses to handle.NrK   )r1   Ú	audit_logs     r3   Úasync_log_audit_log_eventz&CustomLogger.async_log_audit_log_event¾   re   r`   Únon_default_paramsÚ	prompt_idÚprompt_variablesÚdynamic_callback_paramsÚlitellm_logging_objÚprompt_specÚtoolsÚprompt_labelÚprompt_versionÚignore_prompt_manager_modelÚ%ignore_prompt_manager_optional_paramsc              ƒ   ó   K  — |||fS ­w©ax  
        Returns:
        - model: str - the model to use (can be pulled from prompt management tool)
        - messages: List[AllMessageValues] - the messages to use (can be pulled from prompt management tool)
        - non_default_params: dict - update with any optional params (e.g. temperature, max_tokens, etc.) to use (can be pulled from prompt management tool)
        rK   )r1   rM   rN   rm   rn   ro   rp   rq   rr   rs   rt   ru   rv   rw   s                 r3   Ú async_get_chat_completion_promptz-CustomLogger.async_get_chat_completion_promptÃ   s   è ø€ ð, �hÐ 2Ð2Ð2ùs   ‚c                 ó   — |||fS ry   rK   )r1   rM   rN   rm   rn   ro   rp   rr   rt   ru   rv   rw   s               r3   Úget_chat_completion_promptz'CustomLogger.get_chat_completion_promptÛ   s   € ð( �hÐ 2Ð2Ð2r5   Úrequest_kwargsÚinputÚspecific_deploymentc              ƒ   ó   K  — y­w)z¯
        This hook is called before the routing decision is made.

        Used for the litellm auto-router to modify the request before the routing decision is made.
        NrK   )r1   rM   r}   rN   r~   r   s         r3   Úasync_pre_routing_hookz#CustomLogger.async_pre_routing_hookö   s   è ø€ ð ùr`   Úhealthy_deploymentsÚparent_otel_spanc              ƒ   ó   K  — |S ­wrJ   rK   )r1   rM   r‚   rN   r}   rƒ   s         r3   Úasync_filter_deploymentsz%CustomLogger.async_filter_deployments  s   è ø€ ð #Ð"ùó   ‚Ú	call_typec              ƒ   ó   K  — y­w)a  
        Allow modifying the request just before it's sent to the deployment.

        Use this instead of 'async_pre_call_hook' when you need to modify the request AFTER a deployment is selected, but BEFORE the request is sent.

        Used in managed_files.py
        NrK   )r1   r2   r‡   s      r3   Úasync_pre_call_deployment_hookz+CustomLogger.async_pre_call_deployment_hook  re   r`   Ú
deploymentc              ƒ   ó   K  — y ­wrJ   rK   )r1   rŠ   rƒ   s      r3   Úasync_pre_call_checkz!CustomLogger.async_pre_call_check  r_   r`   c                  ó   — y rJ   rK   )r1   rŠ   s     r3   Úpre_call_checkzCustomLogger.pre_call_check  rP   r5   Úrequest_dataÚresponsec              ƒ   ó   K  — y­w)zh
        Allow modifying / reviewing the response just after it's received from the deployment.
        NrK   )r1   r�   r�   r‡   s       r3   Ú'async_post_call_success_deployment_hookz4CustomLogger.async_post_call_success_deployment_hook  re   r`   Ú	exceptionÚfallback_depthc              ƒ   ó   K  — y­w)a	  
        Called once per failed deployment attempt - attempt 1, every retry, and
        every fallback chain step - because the router re-invokes the wrapped
        function on each attempt, re-entering this hook's call site fresh
        every time.

        This is a DEPLOYMENT-LEVEL signal, distinct from the REQUEST-LEVEL
        ``async_log_failure_event``, which fires once per logical client
        request behind a dedup gate. ``request_data`` is mostly this
        attempt's own kwargs, with one exception: it omits
        ``attempted_targets``, the router's own bookkeeping of which fallback
        targets this request has already tried, since that one object *is*
        shared by reference across every hop of the live fallback walk.

        Pairs with ``async_pre_call_deployment_hook`` and
        ``async_post_call_success_deployment_hook`` to complete the
        pre-call/success/failure lifecycle for a single deployment attempt.

        ``fallback_depth`` is best-effort: ``None`` on the first attempt and on
        any call made without a ``Router`` (a bare SDK call has no fallback
        chain to be at a depth in), ``1`` on the first fallback hop, ``2`` on
        the second, and so on. It reflects ``Router``'s own internal fallback
        bookkeeping (``kwargs["fallback_depth"]``), not a value this hook
        computes or guarantees the shape of across versions. It tracks
        fallback hops only, not retries within the same model group - a
        retry-only failure (no fallback yet) also reports ``None``. If an
        override predates this field it's simply never passed, rather than
        raising - safe to leave off an override written before it existed.

        ``exception`` is a same-class snapshot, not the exact object about to
        be re-raised to the real caller: read it freely, but setting an
        attribute on it (e.g. ``status_code``) has no effect on what the
        caller actually receives.

        Default: no-op. Opt in by overriding. Keep overrides fast - this
        runs on the request's exception path, so a slow implementation
        delays error propagation to the caller. The reported failure
        duration is captured before this hook runs, so a slow override
        doesn't inflate that metric, but the caller still waits for it.
        NrK   )r1   r�   r“   r‡   r”   s        r3   Ú'async_post_call_failure_deployment_hookz4CustomLogger.async_post_call_failure_deployment_hook(  re   r`   Úresponse_chunkc              ƒ   ó   K  — y­w)zž
        Allow modifying streaming chunks just before they're returned to the user.

        This is called for each streaming chunk in the response.
        NrK   )r1   r�   r—   r‡   s       r3   Ú)async_post_call_streaming_deployment_hookz6CustomLogger.async_post_call_streaming_deployment_hookX  re   r`   Úoriginal_model_groupc              ƒ   ó   K  — y ­wrJ   rK   )r1   r“   rš   r2   s       r3   Ú log_model_group_rate_limit_errorz-CustomLogger.log_model_group_rate_limit_errore  s   è ø€ ð 	ùr`   Úoriginal_exceptionc              ƒ   ó   K  — y ­wrJ   rK   ©r1   rš   r2   r�   s       r3   Úlog_success_fallback_eventz'CustomLogger.log_success_fallback_eventj  r_   r`   c              ƒ   ó   K  — y ­wrJ   rK   rŸ   s       r3   Úlog_failure_fallback_eventz'CustomLogger.log_failure_fallback_eventm  r_   r`   c                  ó   — y)zt
        Translates the input params, from the provider's native format to the litellm.completion() format.
        NrK   )r1   r2   s     r3   Ú!translate_completion_input_paramsz.CustomLogger.translate_completion_input_paramsr  ó   � r5   c                  ó   — y)z\
        Translates the output params, from the OpenAI format to the custom format.
        NrK   )r1   r�   s     r3   Ú"translate_completion_output_paramsz/CustomLogger.translate_completion_output_paramsw  r¥   r5   Úcompletion_streamc                  ó   — y)z^
        Translates the streaming chunk, from the OpenAI format to the custom format.
        NrK   )r1   r¨   s     r3   Ú,translate_completion_output_params_streamingz9CustomLogger.translate_completion_output_params_streaming|  r¥   r5   Úlogged_itemÚstandard_logging_payloadc              ƒ   ó    K  — t        d«      ‚­w)zÁ
        - Decide if the result should be logged to Argilla.
        - Modify the result before logging to Argilla.
        - Return None if the result should not be logged to Argilla.
        z"async_dataset_hook not implemented)ÚNotImplementedError)r1   r«   r¬   s      r3   Úasync_dataset_hookzCustomLogger.async_dataset_hook…  s   è ø€ ô "Ð"FÓGÐGùs   ‚Úuser_api_key_dictÚcacher   Údatac              ƒ   ó   K  — y ­wrJ   rK   )r1   r°   r±   r²   r‡   s        r3   Úasync_pre_call_hookz CustomLogger.async_pre_call_hook–  s   è ø€ ð 	ùr`   Úrequest_headersÚlitellm_call_infoc              ƒ   ó   K  — y­w)aÏ  
        Called after an LLM API call (success or failure) to allow injecting custom HTTP response headers.

        Args:
            - data: dict - The request data.
            - user_api_key_dict: UserAPIKeyAuth - The user API key dictionary.
            - response: Any - The response object (None for failure cases).
            - request_headers: Optional[Dict[str, str]] - The original request headers.
            - litellm_call_info: Optional[Dict[str, Any]] - Normalized routing metadata:
                - custom_llm_provider: str - The LLM provider (e.g. "openai", "azure")
                - model_info: dict - The model_info from router config
                - api_base: str - The API base URL used
                - model_id: str - The deployment model ID

        Returns:
            - Optional[Dict[str, str]]: A dictionary of headers to inject into the HTTP response.
                                        Return None to not inject any headers.
        NrK   )r1   r²   r°   r�   rµ   r¶   s         r3   Ú%async_post_call_response_headers_hookz2CustomLogger.async_post_call_response_headers_hook¡  s   è ø€ ð4 ùr`   Útraceback_strr   c              ƒ   ó   K  — y­w)au  
        Called after an LLM API call fails. Can return or raise HTTPException to transform error responses.

        Args:
            - request_data: dict - The request data.
            - original_exception: Exception - The original exception that occurred.
            - user_api_key_dict: UserAPIKeyAuth - The user API key dictionary.
            - traceback_str: Optional[str] - The traceback string.

        Returns:
            - Optional[HTTPException]: Return an HTTPException to transform the error response sent to the client.
                                      Return None to use the original exception.
        NrK   )r1   r�   r�   r°   r¹   s        r3   Úasync_post_call_failure_hookz)CustomLogger.async_post_call_failure_hook½  re   r`   c              ƒ   ó   K  — y ­wrJ   rK   )r1   r²   r°   r�   s       r3   Úasync_post_call_success_hookz)CustomLogger.async_post_call_success_hookÒ  ó   è ø€ ð 	ùr`   Úresultc              ƒ   ó   K  — ||fS ­w©zUFor masking logged request/response. Return a modified version of the request/result.rK   ©r1   r2   r¿   r‡   s       r3   Úasync_logging_hookzCustomLogger.async_logging_hookÚ  s   è ø€ à�vˆ~Ðùó   ‚c                 ó
   — ||fS rÁ   rK   rÂ   s       r3   Úlogging_hookzCustomLogger.logging_hookÞ  s   € à�vˆ~Ðr5   c              ƒ   ó   K  — y ­wrJ   rK   )r1   r²   r°   r‡   s       r3   Úasync_moderation_hookz"CustomLogger.async_moderation_hookâ  r¾   r`   c              ƒ   ó   K  — y ­wrJ   rK   )r1   r°   r�   s      r3   Úasync_post_call_streaming_hookz+CustomLogger.async_post_call_streaming_hookê  s   è ø€ ð
 	ùr`   c                ó4   K  — |2 3 d {  –—† }|­–— Œ7 Œ
6 y ­wrJ   rK   )r1   r°   r�   r�   Úitems        r3   Ú'async_post_call_streaming_iterator_hookz4CustomLogger.async_post_call_streaming_iterator_hookñ  s$   è ø€ ð #÷ 	ð 	�$ØŒJð	ø™(ùs   ‚…‰Š�”–c                 ó¢   — 	 ||d<   ||d<   d|d<    ||«        |d|› �«       y # t         $ r   |dt        j                  «       › �«       Y y w xY w©NrM   rN   Úpre_api_callÚlog_event_typez$Custom Logger - model call details: úCustom Logger Error - ©r?   Ú	tracebackÚ
format_exc©r1   rM   rN   r2   Úprint_verboseÚcallback_funcs         r3   Úlog_input_eventzCustomLogger.log_input_eventü  sn   € ð		MØ#ˆF�7‰OØ!)ˆF�:ÑØ'5ˆFÐ#Ñ$ÙØôñ Ð@ÀÀÐIÕJøÜò 	MÙÐ2´9×3GÑ3GÓ3IÐ2JÐKÖLð	Mús   ‚"% ¥&AÁAc              ƒ   ó¾   K  — 	 ||d<   ||d<   d|d<    ||«      ƒ d {  –—†   |d|› �«       y 7 Œ# t         $ r   |dt        j                  «       › �«       Y y w xY w­wrÏ   rÓ   rÖ   s         r3   Úasync_log_input_eventz"CustomLogger.async_log_input_event  s‚   è ø€ ð		MØ#ˆF�7‰OØ!)ˆF�:ÑØ'5ˆFÐ#Ñ$ÙØó÷ ð ñ Ð@ÀÀÐIÕJðùô ò 	MÙÐ2´9×3GÑ3GÓ3IÐ2JÐKÖLð	Müs1   ‚A„1 ž/Ÿ1 ®A¯1 ±&AÁAÁAÁAc                 ó~   — 	 d|d<    |||||«       y # t         $ r   |dt        j                  «       › �«       Y y w xY w©NÚpost_api_callrÑ   rÒ   rÓ   ©r1   r2   rS   rT   rU   r×   rØ   s          r3   Ú	log_eventzCustomLogger.log_event  sT   € ð		MØ'6ˆFÐ#Ñ$ÙØØØØõ	øô ò 	MÙÐ2´9×3GÑ3GÓ3IÐ2JÐKÖLð	Mús   ‚ “&<»<c              ƒ   óš   K  — 	 d|d<    |||||«      ƒ d {  –—†  y 7 Œ# t         $ r   |dt        j                  «       › �«       Y y w xY w­wrÝ   rÓ   rß   s          r3   Úasync_log_eventzCustomLogger.async_log_event!  sa   è ø€ ð		MØ'6ˆFÐ#Ñ$ÙØØØØó	÷ ò ùô ò 	MÙÐ2´9×3GÑ3GÓ3IÐ2JÐKÖLð	Müs1   ‚A„ —˜ œA� Ÿ&AÁAÁAÁArS   c              ƒ   ó   K  — y­w)aF  
        This log gets called after the MCP tool call is made.

        Useful if you want to modify the standard logging payload after the MCP tool call is made.

        To change what the caller sends back to the MCP client, mutate ``response_obj``
        in place: every call site discards the returned object, because the
        dispatcher unwraps it to ``mcp_tool_call_response`` (a raw content list, not
        a ``CallToolResult``) which the tool-call paths cannot forward. Guardrails
        that mask or reject tool output should use ``post_mcp_call`` instead.
        NrK   rR   s        r3   Úasync_post_mcp_tool_call_hookz*CustomLogger.async_post_mcp_tool_call_hook2  s   è ø€ ð ùr`   ÚstreamÚcustom_llm_providerc              ƒ   ó   K  — di fS ­w)aí  
        Hook to determine if agentic loop should be executed.

        Called after receiving response from model, before returning to user.

        USE CASE: Enables transparent server-side tool execution for models that
        don't natively support server-side tools. User makes ONE API call and gets
        back the final answer - the agentic loop happens transparently on the server.

        Example use cases:
        - WebSearch: Intercept WebSearch tool calls for Bedrock/Claude, execute
          litellm.search(), return final answer with search results
        - Code execution: Execute code in sandboxed environment, return results
        - Database queries: Execute queries server-side, return data to model
        - API calls: Make external API calls and inject responses back into context

        Flow:
        1. User calls litellm.messages.acreate(tools=[...])
        2. Model responds with tool_use
        3. THIS HOOK checks if tool should run server-side
        4. If True, async_run_agentic_loop executes the tool
        5. User receives final answer (never sees intermediate tool_use)

        Args:
            response: Response from model (AnthropicMessagesResponse or AsyncIterator)
            model: Model name
            messages: Original messages sent to model
            tools: List of tool definitions from request
            stream: Whether response is streaming
            custom_llm_provider: Provider name (e.g., "bedrock", "anthropic")
            kwargs: Additional request parameters

        Returns:
            (should_run, tools):
                should_run: True if agentic loop should execute
                tools: Dict with tool_calls and metadata for execution

        Example:
            # Detect WebSearch tool call
            if has_websearch_tool_use(response):
                return True, {
                    "tool_calls": extract_tool_calls(response),
                    "tool_type": "websearch"
                }
            return False, {}
        FrK   ©r1   r�   rM   rN   rs   rå   ræ   r2   s           r3   Úasync_should_run_agentic_loopz*CustomLogger.async_should_run_agentic_loopF  s   è ø€ ðp �bˆyÐùrÄ   Ú"anthropic_messages_provider_configÚ*anthropic_messages_optional_request_paramsÚlogging_objÚLiteLLMLoggingObjc
              ƒ   ó   K  — y­w)aI	  
        Hook to execute agentic loop based on context from should_run hook.

        Called only if async_messages_should_run_agentic_loop returns True.

        USE CASE: Execute server-side tools and orchestrate the agentic loop to
        return a complete answer to the user in a single API call.

        What to do here:
        1. Extract tool calls from tools dict
        2. Execute the tools (litellm.search, code execution, DB queries, etc.)
        3. Build assistant message with tool_use blocks
        4. Build user message with tool_result blocks containing results
        5. Make follow-up litellm.messages.acreate() call with results
        6. Return the final response

        Args:
            tools: Dict from async_should_run_agentic_loop
                  Contains tool_calls and metadata
            model: Model name
            messages: Original messages sent to model
            response: Original response from model (with tool_use)
            anthropic_messages_provider_config: Provider config for making requests
            anthropic_messages_optional_request_params: Request parameters (tools, etc.)
            logging_obj: LiteLLM logging object
            stream: Whether response is streaming
            kwargs: Additional request parameters

        Returns:
            Final response after executing agentic loop
            (AnthropicMessagesResponse with final answer)

        Example:
            # Extract tool calls
            tool_calls = agentic_context["tool_calls"]

            # Execute searches in parallel
            search_results = await asyncio.gather(
                *[litellm.asearch(tc["input"]["query"]) for tc in tool_calls]
            )

            # Build messages with tool results
            assistant_msg = {"role": "assistant", "content": [...tool_use blocks...]}
            user_msg = {"role": "user", "content": [...tool_result blocks...]}

            # Make follow-up request
            from litellm.anthropic_interface import messages
            final_response = await messages.acreate(
                model=model,
                messages=messages + [assistant_msg, user_msg],
                max_tokens=anthropic_messages_optional_request_params.get("max_tokens"),
                **anthropic_messages_optional_request_params
            )

            return final_response
        NrK   ©
r1   rs   rM   rN   r�   rê   rë   rì   rå   r2   s
             r3   Úasync_run_agentic_loopz#CustomLogger.async_run_agentic_loop€  re   r`   c
              ƒ   ó"   K  — t        d¬«      S ­w)zå
        Build a typed rerun plan for Anthropic Messages agentic loops.

        Override this method to separate callback decision/tool execution from
        follow-up request execution (handled by BaseLLMHTTPHandler).
        F©Úrun_agentic_loopr   rï   s
             r3   Úasync_build_agentic_loop_planz*CustomLogger.async_build_agentic_loop_planÅ  s   è ø€ ô$ °Ô6Ð6ùó   ‚Úplanc              ƒ   ó   K  — |S ­w)aR  
        Post-process the response returned by the agentic-loop follow-up call.

        Called after BaseLLMHTTPHandler executes ``AgenticLoopPlan.request_patch``
        and receives the final response from the provider. Lets callbacks shape
        what the client sees without bypassing the loop's safety / observability
        machinery (depth tracking, fingerprinting, etc.).

        Use ``plan.metadata`` to carry whatever the build step decided to expose
        for post-processing (e.g. native tool_result blocks to inject).

        Default returns ``response`` unchanged.
        rK   )r1   r�   rö   r2   s       r3   Ú%async_post_agentic_loop_response_hookz2CustomLogger.async_post_agentic_loop_response_hookÙ  s   è ø€ ð& ˆùr†   c              ƒ   ó   K  — y­w)aå  
        Release resources held for an agentic-loop iteration.

        Runs in a ``finally`` around the follow-up provider call, so it fires
        whether the rerun returns normally, hits a loop safety abort, or raises
        an upstream error. Implementations must be idempotent because the
        post-response hook may already have released the same resource on the
        success path. Use ``plan.metadata`` to locate what to clean up.

        Default does nothing.
        NrK   )r1   rö   r2   s      r3   Úasync_agentic_loop_cleanup_hookz,CustomLogger.async_agentic_loop_cleanup_hookî  s   è ø€ ð  	ùr`   c              ƒ   ó   K  — di fS ­w)zW
        Hook to determine if chat completion agentic loop should be executed.
        FrK   rè   s           r3   Ú-async_should_run_chat_completion_agentic_loopz:CustomLogger.async_should_run_chat_completion_agentic_loop   s   è ø€ ð �bˆyÐùrÄ   Úoptional_paramsc	              ƒ   ó   K  — y­w)ze
        Hook to execute chat completion agentic loop based on context from should_run hook.
        NrK   ©	r1   rs   rM   rN   r�   rý   rì   rå   r2   s	            r3   Ú&async_run_chat_completion_agentic_loopz3CustomLogger.async_run_chat_completion_agentic_loop  re   r`   c	              ƒ   ó"   K  — t        d¬«      S ­w)zN
        Build a typed rerun plan for chat-completions agentic loops.
        Frò   r   rÿ   s	            r3   Ú-async_build_chat_completion_agentic_loop_planz:CustomLogger.async_build_chat_completion_agentic_loop_plan  s   è ø€ ô °Ô6Ð6ùrõ   Ústandard_logging_objectc                 óF   — d}g d¢}|D ]  }| j                  |||¬«       Œ y)a  
        Truncate error strings and message content in logging payload

        Some loggers like DataDog/ GCS Bucket have a limit on the size of the payload. (1MB)

        This function truncates the error string and the message content if they exceed a certain length.
        i'  )Ú	error_strrN   r�   )r  Ú
field_nameÚ
max_lengthN)Ú_truncate_field)r1   r  ÚMAX_STR_LENGTHÚfields_to_truncateÚfields        r3   Ú)truncate_standard_logging_payload_contentz6CustomLogger.truncate_standard_logging_payload_content0  s=   € ð !'ˆò %JÐØ'ò 	ˆEØ× Ñ Ø(?Ø Ø)ð !õ ñ	r5   r  r  c                 óŒ   — |j                  |«      }|r1t        |«      }t        |«      |kD  r| j                  ||¬«      ||<   yyy)aP  
        Helper function to truncate a field in the logging payload

        This converts the field to a string and then truncates it if it exceeds the max length.

        Why convert to string ?
        1. User was sending a poorly formatted list for `messages` field, we could not predict where they would send content
            - Converting to string and then truncating the logged content catches this
        2. We want to avoid modifying the original `messages`, `response`, and `error_str` in the logging payload since these are in kwargs and could be returned to the user
        )Útextr  N)r=   ÚstrÚlenÚ_truncate_text)r1   r  r  r  Úfield_valueÚ	str_values         r3   r  zCustomLogger._truncate_fieldF  sS   € ð  5×8Ñ8¸ÓDˆÙÜ" ;Ó/ˆIÜ�9‹~ 
Ò*Ø6:×6IÑ6IÈyÐeoÐ6IÓ6pÐ'¨
Ò3ð +ð r5   r  c                 ó2   — t        |«      |kD  r|d| dz   S |S )z&Truncate text if it exceeds max_lengthNzC...truncated by litellm, this logger does not support large content)r  )r1   r  r  s      r3   r  zCustomLogger._truncate_text\  s1   € ô �4‹y˜:Ò%ð ��*ÐÐ eÑeð	
ð ð	
r5   c                 ó(   — ddl m}m} |€y||v r|S |S )z¦
        Select the metadata field to use for logging

        1. If `litellm_metadata` is in the request kwargs, use it
        2. Otherwise, use `metadata`
        r   )ÚLITELLM_METADATA_FIELDÚOLD_LITELLM_METADATA_FIELDN)Úlitellm.constantsr  r  )r1   r}   r  r  s       r3   Ú_select_metadata_fieldz#CustomLogger._select_metadata_fieldd  s%   € ÷ 	YàÐ!ØØ! ^Ñ3Ø)Ð)Ø)Ð)r5   Úmodel_call_detailsc                 ó0  — ddl m } ddl}ddlm}m}m} t        | dd«      }t        |dd«      }|du r|s|S  ||«      }	|j                  d«      }
|
€|	S  ||
«      }|r|D ]
  }||v sŒ||= Œ |�r!d	}d
|xs g vr,|j                  d
«      � ||¬«      j                  «       g|d
<   d|xs g vrã|j                  d«      �Ò|d   }t        |t        «      r�d|v rŒddl m
}  ||«      }t        |j                  d«      t        «      rY|d   D ]Q  }t        |t        «      sŒd|v sŒt        |d   t        «      sŒ-|d   D ]  }t        |t        «      sŒd|v sŒ||d<   Œ ŒS ||d<   n- | | ||¬«      ¬«      g¬«      }|j                  «       }||d<   ||	d<   |	S )aÈ  
        Redacts or excludes fields from StandardLoggingPayload before callbacks receive it.

        This method handles two features:
        1. turn_off_message_logging: When True, redacts messages and responses
        2. standard_logging_payload_excluded_fields: Removes specified fields entirely

        Return a modified copy of the provided logging payload.

        This is useful for logging payloads that contain sensitive information.
        r   )ÚcopyN)ÚChoicesÚMessager   r-   FÚ(standard_logging_payload_excluded_fieldsr  zredacted-by-litellmrN   ©Úcontentr�   Úoutput)Údeepcopyr!  r  )Úmessage)Úchoices)r  Úlitellmr  r  r   r@   r=   Ú
model_dumpÚ
isinstanceÚdictr#  rA   )r1   r  r  r&  r  r  r   r-   Úexcluded_fieldsÚmodel_call_details_copyr  Ústandard_logging_object_copyr  Úredacted_strr�   r#  Úresponse_copyÚoutput_itemÚcontent_itemÚmodel_responseÚmodel_response_dicts                        r3   Ú7redact_standard_logging_payload_from_model_call_detailszDCustomLogger.redact_standard_logging_payload_from_model_call_detailss  s  € õ 	ãß;Ñ;ä07¸Ð>XÐZ_Ó0`Ð Ü3:¸7ÐDnÐptÓ3uˆð $ uÑ,±_Ø%Ð%ñ *.Ð.@Ó)AÐØ);×)?Ñ)?Ð@YÓ)ZÐØ"Ð*Ø*Ð*ñ /3Ð3JÓ.KÐ$ñ Ø(ò <�ØÐ8Ò8Ø4°UÑ;ð<ò
 $Ø"7ˆLà /Ò"7°RÑ8Ð=Y×=]Ñ=]Ð^hÓ=iÐ=uÙ<CÈLÔ<Y×<dÑ<dÓ<fÐ;gÐ,¨ZÑ8à /Ò"7°RÑ8Ð=Y×=]Ñ=]Ð^hÓ=iÐ=uØ">¸zÑ"J�ä˜h¬Ô-°(¸hÑ2Få-á+3°HÓ+=�Mä! -×"3Ñ"3°HÓ"=¼tÔDØ+8¸Ñ+Bò P˜KÜ)¨+´tÕ<ÀÈkÒAYÜ#-¨k¸)Ñ.DÄdÕ#Kà8CÀIÑ8Nò %P¨Ü+5°lÄDÕ+IÈfÐXdÒNdØCO¨L¸Ò,@ñ%Pð	Pð @MÐ0°Ò<ñ -:Á7ÑSZÐcoÔSpÔCqÐBrÔ,s�NØ1?×1JÑ1JÓ1LÐ'Ø?RÐ0°Ñ<à=YÐÐ 9Ñ:Ø&Ð&r5   Ú
object_keyc              ƒ   ó   K  — y­w)z_
        Get the proxy server request from cold storage using the object key directly.
        NrK   )r1   r4  s     r3   Ú:get_proxy_server_request_from_cold_storage_with_object_keyzGCustomLogger.get_proxy_server_request_from_cold_storage_with_object_key½  re   r`   c                 óH  — 	 ddl }ddlm} |j                  j	                  «       }|D ]5  }t        |d«      sŒ |j                  d|«       |j                  |¬«        y  |j                  d|«       y# t        $ r$}ddlm}  |j                  d||«       Y d}~yd}~ww xY w)	z¯
        Handle callback logging failures by incrementing Prometheus metrics.

        Call this method in exception handlers within your callback when logging fails.
        r   Nr   Ú"increment_callback_logging_failurez+Incrementing callback failure metric for %s)r6   zyNo callback with increment_callback_logging_failure method found for %s. Ensure 'prometheus' is in your callbacks config.z+Error in handle_callback_failure for %s: %s)	r&  Úlitellm._loggingr   Úlogging_callback_managerÚ_get_all_callbacksÚhasattrÚdebugr8  r?   )r1   r6   r&  r   Úall_callbacksÚcallback_objÚes          r3   Úhandle_callback_failurez$CustomLogger.handle_callback_failureÅ  s±   € ð	bÛÝ7à#*×#CÑ#C×#VÑ#VÓ#XˆMà -ò �Ü˜<Ð)MÕNØ(�N×(Ñ(Ð)VÐXeÔfØ ×CÑCÐR_ÐCÔ`Ùð	ð !ˆN× Ñ ð LØõøô
 ò 	bÝ7à ˆN× Ñ Ð!NÐP]Ð_`×aÑaûð	bús"   ‚5A4 ¸&A4 ÁA4 Á4	B!Á=BÂB!Úpayloadr   Ú	max_depthc              ƒ   ó²  K  — |j                  dg «      }t        |t        «      r|ng }t        j                  dt        |«      «       |r| j                  ||¬«      |d<   d}|j                  dg «      xs g D ]D  }t        |t        «      sŒ|j                  dg «      }t        |t        «      sŒ7|t        |«      z  }ŒF t        j                  d|«       |S ­w©u   
        Removes or redacts base64-encoded file data (e.g., PDFs, images, audio)
        from messages and responses before sending to SQS.

        Behavior:
          â€¢ Drop entries with a 'file' key.
          â€¢ Drop entries with type == 'file' or any non-text type.
          â€¢ Keep untyped or text content.
          â€¢ Recursively redact inline base64 blobs in *any* string field, at any depth.
        rN   z0[CustomLogger] Stripping base64 from %s messages)rN   rC  r   r!  z@[CustomLogger] Completed base64 strip; retained %s content items©r=   r(  rA   r   r=  r  Ú_process_messagesr)  ©r1   rB  rC  Úraw_messagesrN   Útotal_itemsÚmr!  s           r3   Ú_strip_base64_from_messagesz(CustomLogger._strip_base64_from_messagesá  sÎ   è ø€ ð $+§;¡;¨z¸2Ó#>ˆÜ5?ÀÌdÔ5S¡\ÐY[ˆÜ×ÑÐOÔQTÐU]ÓQ^Ô_áØ"&×"8Ñ"8À(ÐV_Ð"8Ó"`ˆG�JÑàˆØ—‘˜Z¨Ó,Ò2°ò 	0ˆAÜ˜!œTÕ"ØŸ%™% 	¨2Ó.�Ü˜g¤tÕ,Ø¤3 w£<Ñ/‘Kð		0ô 	×ÑÐ_ÐalÔmØˆùs   ‚B	CÂ"CÂ/(Cc                 óª  — |j                  dg «      }t        |t        «      r|ng }t        j                  dt        |«      «       |r| j                  ||¬«      |d<   d}|j                  dg «      xs g D ]D  }t        |t        «      sŒ|j                  dg «      }t        |t        «      sŒ7|t        |«      z  }ŒF t        j                  d|«       |S rE  rF  rH  s           r3   Ú _strip_base64_from_messages_syncz-CustomLogger._strip_base64_from_messages_sync  sÊ   € ð $+§;¡;¨z¸2Ó#>ˆÜ5?ÀÌdÔ5S¡\ÐY[ˆÜ×ÑÐOÔQTÐU]ÓQ^Ô_áØ"&×"8Ñ"8À(ÐV_Ð"8Ó"`ˆG�JÑàˆØ—‘˜Z¨Ó,Ò2°ò 	0ˆAÜ˜!œTÕ"ØŸ%™% 	¨2Ó.�Ü˜g¤tÕ,Ø¤3 w£<Ñ/‘Kð		0ô 	×ÑÐ_ÐalÔmØˆr5   r   ÚvalueÚdepthc           
      óü  — ||kD  rt        j                  d|«       yt        |t        «      rFt        j                  |«      r/t        j                  d|dd «       t        j                  d|«      S |S t        |t        «      r%|D �cg c]  }| j                  ||dz   |¬«      ‘Œ c}S t        |t        «      r9|j                  «       D ��ci c]  \  }}|| j                  ||dz   |¬«      “Œ c}}S |S c c}w c c}}w )	z\Recursively redact inline base64 from any nested structure with a max recursion depth limit.zD[CustomLogger] Max recursion depth %s reached while redacting base64z[MAX_DEPTH_REACHED]z3[CustomLogger] Redacted inline base64 string: %s...Né(   z[BASE64_REDACTED]é   )rO  rP  rC  )r   Úwarningr(  r  r(   Úsearchr=  ÚsubrA   Ú_redact_base64r)  Úitems)r1   rO  rP  rC  ÚvÚks         r3   rW  zCustomLogger._redact_base64!  sö   € ð �9ÒÜ×"Ñ"Ð#iÐktÔuØ(ä�eœSÔ!Ü%×,Ñ,¨UÔ3Ü×$Ñ$Ð%ZÐ\aÐbeÐceÐ\fÔgÜ-×1Ñ1Ð2EÀuÓMÐMØˆLä�eœTÔ"Ø`eÖfÐ[\�D×'Ñ'¨a°u¸q±yÈIÐ'ÕVÒfÐfä�eœTÔ"Øfk×fqÑfqÓfs×tÑ^bÐ^_Ðab�A�t×*Ñ*°¸%À!¹)ÈyÐ*ÓYÑYÓtÐtàˆùò gùó us   ÂC3Ã"C8r!  c                 ó€   — t        |t        «      syd|v ry|j                  d«      }t        |t        «      xr |dk7   S )z4Return True if this content item should be retained.TÚfileFÚtyper  )r(  r)  r=   r  )r1   r!  Úctypes      r3   Ú_should_keep_contentz!CustomLogger._should_keep_content:  sA   € ä˜'¤4Ô(ØØ�WÑØØ—{‘{ 6Ó*ˆÜ˜u¤cÓ*Ò>¨u¸©Ð?Ð?r5   c                 óÌ  — g }|D ]Ü  }t        |t        «      sŒ|j                  d«      }t        |t        «      rDg }|D ]7  }| j	                  |¬«      sŒ|j                  | j                  ||¬«      «       Œ9 ||d<   n| j                  ||¬«      |d<   t        |j                  «       «      D ]!  \  }}	|dk7  sŒ| j                  |	|¬«      ||<   Œ# |j                  |«       ŒÞ |S )Nr!  r   )rO  rC  )r(  r)  r=   rA   r_  ÚappendrW  rX  )
r1   rN   rC  Úfiltered_messagesÚmsgÚcontentsÚcleanedÚcÚkeyÚvals
             r3   rG  zCustomLogger._process_messagesC  sþ   € ð
 :<ÐØò 	*ˆCÜ˜c¤4Ô(ØØŸG™G IÓ.ˆHÜ˜(¤DÔ)Ø%'�Ø!ò Z�AØ×0Ñ0¸Ð0Õ;ØŸ™ t×':Ñ':ÀÈiÐ':Ó'XÕYðZð ")��I’à!%×!4Ñ!4¸8ÈyÐ!4Ó!Y��I‘ä  §¡£Ó-ò S‘��SØ˜)Ó#Ø#×2Ñ2¸È	Ð2ÓR�C˜’HðSð ×$Ñ$ SÕ)ð!	*ð" !Ð r5   )FTrJ   )rk   r   )NNNNFF)NNNFF)NNF)NN)iÚ__name__Ú
__module__Ú__qualname__Ú	frozensetr+   r   r  Ú__annotations__r,   Úboolr4   ÚstaticmethodrA   rH   rO   rV   rX   rZ   r\   r^   rb   r)  rd   rg   ri   rl   r   r   rí   r   ÚintÚtuplerz   r|   r   r%   r�   r   r…   r   r‰   rŒ   rŽ   r   r’   r   Úobjectr?   r–   r™   rœ   r    r¢   r   r¤   r   r
   r§   r   rª   r   r   r¯   r!   r   r´   r¸   r	   r»   r½   rÃ   rÆ   rÈ   rÊ   r   r   rÍ   rÙ   rÛ   rà   râ   r"   rä   ré   rð   r   rô   rø   rú   rü   r   r  r  r  r  r  r3  r6  rA  r   rL  rN  rW  r_  rG  rK   r5   r3   r*   r*   =   s»  … á<E»KÐ ¨)°C©.Ñ!9ÓGà%*Ð˜dÓ*ðð& */à $ñ	Aà"&ðAð ð	Að 
óAð ñ#¨S°4©Zð #À4ÈÁ9ò #ó ð#òJòòòòò
òð°#ð Àð Ètð ÐX\Ð_cÑXcó ò2òóUð *.Ø#'Ø#'Ø%)Ø38Ø=Bñ3àð3ð Ð'Ñ(ð3ð !ð	3ð
 ˜‘:ð3ð  ™+ð3ð "?ð3ð /ð3ð   $Ñ&ð3ð �D‰z˜DÑ ð3ð ˜D‘jð3ð ˜d™
ð3ð &*¨D¡[ð3ð 04°d©{ð3ð 
ˆs�DÐ)Ñ*¨DÐ0Ñ	1ó3ð@ *.Ø#'Ø%)Ø38Ø=Bñ3àð3ð Ð'Ñ(ð3ð !ð	3ð
 ˜‘:ð3ð  ™+ð3ð "?ð3ð   $Ñ&ð3ð ˜D‘jð3ð ˜d™
ð3ð &*¨D¡[ð3ð 04°d©{ð3ð 
ˆs�DÐ)Ñ*¨DÐ0Ñ	1ó3ð.ð 15Ø#'Ø+0ñàðð ðð �t˜C ˜H‘~Ñ&¨Ñ-ð	ð
 �T‰z˜DÑ ðð " D™[ðð 
  $Ñ	&óð( '+Ø(,ñ#àð#ð "ð#ð Ð'Ñ(¨4Ñ/ð	#ð
 ˜t™ð#ð  ™+ð#ð 
ˆd‰ó#ð¸4ÀÀSÀ¹>ð ÐV_ÐbfÑVfð ÐkoÐrvÑkvó ð°Tð ÈTÐTXÉ[ð Ð]aÐdhÑ]hó ð¨ð °$¸±+ó ðàðð #ðð ˜tÑ#ð	ð
 
˜DÑ	 óð &*ñ.à˜c 6˜kÑ*ð.ð ð.ð ˜tÑ#ð	.ð
 ˜d™
ð.ð 
ó.ð`
àð
ð ð
ð ˜tÑ#ð	
ð
 
ˆt‰ó
ðØ"ðØ:=À¹*ðØNRóð
ÀSð ÐRVð Ðluó ðÀSð ÐRVð Ðluó ð
Ð;PÐSWÑ;Wó ð
¸=ð ÈYÐY]ÑM]ó ð
Ø!$ðà	'¨$Ñ	.óð
Hà ð
Hð #9¸4Ñ"?ð
Hð 
�tÑ	ó	
Hðð	à)ð	ð ð	ð ð		ð
 $ð	ð 	�C‰˜$Ñ Ñ%ó	ð  26Ø37ñàðð *ðð ð	ð
 ˜c 3˜h™¨$Ñ.ðð    S ™>¨DÑ0ðð 
ˆc�3ˆh‰˜$Ñ	óðB %)ñàðð &ðð *ð	ð
 ˜T‘zðð 
�/Ñ	"óð*àðð *ðð #ð	ð
 
óð¨tð ¸Sð ÈSð ÐUZÐ[_ÐadÐ[dÑUeó ð 4ð °ð Àð ÈÈtÐUXÈyÑIYó ðàðð *ðð $ð	ð
 
óðà)ðð ðð 
ó	ðà)ðð ðð ð	ð
 
Ð+¨TÐ1Ñ	2óò
Mò
MòMòMð"Ø$=ðà	" TÑ	)óð(8àð8ð ð8ð �t‘*ð	8ð
 �D‰z˜DÑ ð8ð ð8ð !ð8ð ð8ð 
ˆt�TˆzÑ	ó8ðtCàðCð ðCð �t‘*ð	Cð
 ðCð -0ðCð 59ðCð )ðCð ðCð ðCð 
óCðJ7àð7ð ð7ð �t‘*ð	7ð
 ð7ð -0ð7ð 59ð7ð )ð7ð ð7ð ð7ð 
ó7ð(àðð ðð ð	ð
 
óð*àðð ðð 
ó	ð$àðð ðð �t‘*ð	ð
 �D‰z˜DÑ ðð ðð !ðð ðð 
ˆt�TˆzÑ	óðàðð ðð �t‘*ð	ð
 ðð ðð )ðð ðð ðð 
óð7àð7ð ð7ð �t‘*ð	7ð
 ð7ð ð7ð )ð7ð ð7ð ð7ð 
ó7ð$à!7óð,qà!7ðqð ðqð ð	qð
 
óqð,
 3ð 
°Cð 
¸Có 
ñ*°T¸D±[ð *ÈCÐRVÉJó *ðH'ÐZ^ð H'Ðcgó H'ðTàðð 
�‰óðb°Só bð> Iñà)ðð ðð 
"ó	ðF Iñà)ðð ðð 
"ó	ðF ØHñ	àðð ðð ð	ð
 
óð2@¨Cð @°Dó @ð Iñ!à�s‘)ð!ð ð!ð 
ˆd�3˜�8‰nÑ	ô	!r5   r*   )=ÚrerÔ   Úcollections.abcr   r   Útypingr   r   r   r   r	   Úpydanticr
   r9  r   r  r   Ú"litellm.types.integrations.argillar   Ú(litellm.types.integrations.custom_loggerr   Úlitellm.types.llms.openair   r   Ú"litellm.types.prompts.init_promptsr   Úlitellm.types.utilsr   r   r   r   r   r   r   r   r   Úfastapir   Úopentelemetry.tracer   Ú_SpanÚlitellm.caching.cachingr   Ú*litellm.litellm_core_utils.litellm_loggingr    rí   r>   r!   Úlitellm.types.mcpr"   r#   r$   Úlitellm.types.routerr%   r&   rm  r'   ÚcompileÚ	MULTILINEr(   r*   rK   r5   r3   ú<module>r…     sÔ   ðô 
Û ß 3ß @Õ @å å +Ý MÝ :Ý Dß MÝ 9÷
÷ 
õ 
ñ Ý%Ý1å1ÝWÝ3÷ñ õ
 <à�3‰;�Dà€DØÐØ€NØ #ÐØ!ÐØ"ÐØ(+Ð Ó+Ø),Ð Ó,Ø Ðð !+ §
¡
ØVØ‡L�Ló!Ð ˜ó ÷]!ò ]!r5   