o
    ưiP.                     @   sf   d dl Z d dlZd dlmZmZmZ d dlmZ d dlm	Z	 er'd dl
mZ neZG dd de	ZdS )    N)TYPE_CHECKINGAnyOptional)verbose_logger)CustomLogger)StandardLoggingPayloadc                   @   s   e Zd Zdd Zdd Zdd Zdd Zd	d
 Zdd Zdd Z	dd Z
dd Zdd Zdd Zdd Zdee defddZdd Zdedefd d!Zd"d# Zd$S )%MlflowLoggerc                 C   s(   ddl m} | | _i | _t | _d S )Nr   )MlflowClient)Zmlflow.trackingr	   _client_stream_id_to_span	threadingLock_lock)selfr	    r   R/home/app/Keep/.python/lib/python3.10/site-packages/litellm/integrations/mlflow.py__init__   s   zMlflowLogger.__init__c                 C      |  |||| d S N_handle_successr   kwargsresponse_obj
start_timeend_timer   r   r   log_success_event      zMlflowLogger.log_success_eventc                       |  |||| d S r   r   r   r   r   r   async_log_success_event      z$MlflowLogger.async_log_success_eventc                 C   s   ddl m} z7td |dr| |||| W d
S | ||}t| d }| 	||| | j
|||j|d W d
S  tyN   tjddd	 Y d
S w )z
        Log the success event as an MLflow span.
        Note that this method is called asynchronously in the background thread.
        r   SpanStatusCodez&MLflow logging start for success eventstream    eAspanoutputsstatusend_time_nszMLflow Logging ErrorT
stack_infoN)mlflow.entitiesr"   r   debugget_handle_stream_event_start_span_or_traceint	timestamp _extract_and_set_chat_attributes_end_span_or_traceOK	Exception)r   r   r   r   r   r"   r&   r)   r   r   r   r      s"   

zMlflowLogger._handle_successc                 C   s   zddl m} ddl m} W n
 ty   Y d S w | |}|dg }dd t|dg D }g || }	r<|||	 |d }
rJ|||
 d S d S )	Nr   )set_span_chat_messages)set_span_chat_toolsmessagesc                 S   s   g | ]	}|j jd dqS )T)Zexclude_none)message
model_dump).0cr   r   r   
<listcomp>?   s    zAMlflowLogger._extract_and_set_chat_attributes.<locals>.<listcomp>choicestools)Zmlflow.tracing.utilsr7   r8   ImportError_construct_inputr.   getattr)r   r&   r   r   r7   r8   inputsZinput_messagesZoutput_messagesr9   r@   r   r   r   r3   6   s    


z-MlflowLogger._extract_and_set_chat_attributesc                 C   r   r   _handle_failurer   r   r   r   log_failure_eventH   r   zMlflowLogger.log_failure_eventc                    r   r   rE   r   r   r   r   async_log_failure_eventK   r    z$MlflowLogger.async_log_failure_eventc              
   C   s   ddl m}m} z1| ||}t| d }|d }	r&|||	 | 	||| | j
|||j|d W d	S  tyV }
 ztjd|
 dd W Y d	}
~
d	S d	}
~
ww )
z
        Log the failure event as an MLflow span.
        Note that this method is called *synchronously* unlike the success handler.
        r   )	SpanEventr"   r$   	exceptionr%   zMLflow Logging Error - Tr*   N)r,   rI   r"   r0   r1   r2   r.   	add_eventfrom_exceptionr3   r4   ERRORr6   r   r-   )r   r   r   r   r   rI   r"   r&   r)   rJ   er   r   r   rF   N   s"   "zMlflowLogger._handle_failurec           
      C   s  ddl m} |d}|| jvr3| j || jvr$| ||}|| j|< W d   n1 s.w   Y  | j| }| || |dpG|d}|rt| d }	| 	||| | j
|||j|	d | j | j| W d   dS 1 sxw   Y  dS dS )	a  
        Handle the success event for a streaming response. For streaming calls,
        log_success_event handle is triggered for every chunk of the stream.
        We create a single span for the entire stream request as follows:

        1. For the first chunk, start a new span and store it in the map.
        2. For subsequent chunks, add the chunk as an event to the span.
        3. For the final chunk, end the span and remove the span from the map.
        r   r!   litellm_call_idNZcomplete_streaming_responseZ!async_complete_streaming_responser$   r%   )r,   r"   r.   r   r   r0   _add_chunk_eventsr1   r2   r3   r4   r5   pop)
r   r   r   r   r   r"   rO   r&   Zfinal_responser)   r   r   r   r/   i   s6   





"z!MlflowLogger._handle_stream_eventc              
   C   sf   ddl m} z|jD ]}||ddtj|jjtdid q
W d S  t	y2   t
jddd	 Y d S w )
Nr   )rI   Zstreaming_chunkdelta)default)name
attributesz!Error adding chunk events to spanTr*   )r,   rI   r?   rK   jsondumpsrR   r;   strr6   r   r-   )r   r&   r   rI   choicer   r   r   rP      s   
	zMlflowLogger._add_chunk_eventsc                 C   sh   d| di}| d }r||d< dD ]}| di |d }r&|||< q| d }r2||d< |S )z.Construct span inputs with optional parametersr9   r@   )Z	functionsr@   r#   Ztool_choiceuserZoptional_paramsN
prediction)r.   rQ   )r   r   rD   r@   keyvaluer[   r   r   r   rB      s   zMlflowLogger._construct_inputc                 C   s   | d| d| dd}| d}|rD|| d| d| d| d	| d
d| d| d| d| dd |S | di }|| d| d| d| d| dd |S )a  
        Extract span attributes from kwargs.

        With the latest version of litellm, the standard_logging_object contains
        canonical information for logging. If it is not present, we extract
        subset of attributes from other kwargs.
        rO   	call_typemodel)rO   r^   r_   Zstandard_logging_objectapi_base	cache_hitZprompt_tokensZcompletion_tokenstotal_tokens)Zinput_tokensZoutput_tokensrb   responseresponse_costsaved_cache_costrequest_tags)r`   ra   zmlflow.chat.tokenUsageZraw_llm_responserd   re   rf   litellm_paramscustom_llm_provider)r_   ra   rh   r`   rd   )r.   update)r   r   rU   Zstandard_objrg   r   r   r   _extract_attributes   s@   		z MlflowLogger._extract_attributesr^   returnc                 C   s.   ddl m} |dv r|jS |dkr|jS |jS )Nr   )SpanType)
completionZacompletionZ
embeddings)r,   rl   ZLLMZ	EMBEDDING)r   r^   rl   r   r   r   _get_span_type   s   zMlflowLogger._get_span_typec                 C   s   ddl }|dd}d| }| |}t| d }| |}| |}	|  }
r;| jj	||
j
|
j|||	|dS | jj||||	| |	dg |d	S )
z
        Start an MLflow span or a trace.

        If there is an active span, we start a new span as a child of
        that span. Otherwise, we start a new trace.
        r   Nr^   rm   zlitellm-r$   )rT   trace_id	parent_id	span_typerD   rU   start_time_nsrf   )rT   rq   rD   rU   tagsrr   )mlflowr.   rn   r1   r2   rB   rj   Zget_current_active_spanr
   Z
start_span
request_idspan_idZstart_trace_transform_tag_list_to_dict)r   r   r   rt   r^   Z	span_namerq   rr   rD   rU   Zactive_spanr   r   r   r0      s6   





z!MlflowLogger._start_span_or_tracetag_listc                 C   sH   i }|D ]}d|v r| dd\}}| || < qd|| < q|S )z
        Transform a list of colon-separated tags into a dictionary.
        Tags without colons are stored with empty string as the value.
        :    )splitstrip)r   rx   rs   tagkvr   r   r   rw     s   z(MlflowLogger._transform_tag_list_to_dictc                 C   sB   |j du r| jj|j|||d dS | jj|j|j|||d dS )zEnd an MLflow span or a trace.N)ro   r'   r(   r)   )ro   rv   r'   r(   r)   )rp   r
   Z	end_traceru   Zend_spanrv   )r   r&   r'   r)   r(   r   r   r   r4   "  s   


zMlflowLogger._end_span_or_traceN)__name__
__module____qualname__r   r   r   r   r3   rG   rH   rF   r/   rP   rB   rj   r   rX   rn   r0   listdictrw   r4   r   r   r   r   r      s"    .-
'r   )rV   r   typingr   r   r   Zlitellm._loggingr   Z"litellm.integrations.custom_loggerr   Zlitellm.types.utilsr   r   r   r   r   r   <module>   s    