o
    ưiQ                     @   s   d dl Z d dlZd dlZd dlZd dlZd dlmZ d dlmZmZ d dl	m
Z
mZmZmZ d dl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mZ d d	lmZmZ d d
lT d dlmZmZ dd Z G dd deZ!dS )    N)uuid)datetimetimezone)AnyDictListOptional)	BaseModel)verbose_logger)CustomBatchLogger)should_use_langsmith_mockcreate_mock_langsmith_client)get_async_httpx_clienthttpxSpecialProvider)*)StandardCallbackDynamicParamsStandardLoggingPayloadc                 C   s   t jt jt jtf}t| | S )N)typesCoroutineTypeFunctionTypeGeneratorTyper	   
isinstance)valueZnon_serializable_types r   U/home/app/Keep/.python/lib/python3.10/site-packages/litellm/integrations/langsmith.pyis_serializable   s   r   c                       sT  e Zd Z					d.dee dee dee dee dee f
 fddZ				d/dee dee dee dee d	ef
d
dZdefddZ	dd Z
dd Zdd Zdd Z	d0dededed	efddZdedee fddZd	eeef fd d!Zd"eeef d	efd#d$Zd"eeef d	efd%d&Zd'd( Zd)d* Zd+efd,d-Z  ZS )1LangsmithLoggerNlangsmith_api_keylangsmith_projectlangsmith_base_urllangsmith_sampling_ratelangsmith_tenant_idc                    s   t  | _t jd
i |d| ji t | _| jr"t  t	d | j
||||d| _tdd urEtd  rE|pDttdnd| _tdd| _ttjd| _td	d p^tj}|rft|| _g | _t |   d S )N
flush_lockz:[LANGSMITH MOCK] LangSmith logger initialized in mock moder   r   r   r!   ZLANGSMITH_SAMPLING_RATEg      ?ZLANGSMITH_DEFAULT_RUN_NAMEZLLMRun)Zllm_providerZLANGSMITH_BATCH_SIZEr   )asyncioLockr"   super__init__r   is_mock_moder   r
   debugget_credentials_from_envdefault_credentialsosgetenvstripisdigitfloatsampling_ratelangsmith_default_run_namer   r   ZLoggingCallbackasync_httpx_clientlitellmZlangsmith_batch_sizeint
batch_size	log_queuecreate_taskZperiodic_flush)selfr   r   r   r    r!   kwargsZ_batch_size	__class__r   r   r'   )   s@   
	
	
zLangsmithLogger.__init__returnc           	      C   sP   |pt d}|pt dpd}|pt dpd}|pt d}t||||dS )NLANGSMITH_API_KEYLANGSMITH_PROJECTzlitellm-completionLANGSMITH_BASE_URLzhttps://api.smith.langchain.comLANGSMITH_TENANT_ID)r>   r@   r?   rA   )r,   r-   LangsmithCredentialsObject)	r9   r   r   r   r!   Z_credentials_api_keyZ_credentials_projectZ_credentials_base_urlZ_credentials_tenant_idr   r   r   r*   V   s   z(LangsmithLogger.get_credentials_from_envcredentialsc              
   C   sR  z| di p	i }| di pi }| d|d }| d| j}	| d| dd }
| dd }| d	d }| d
d }| dd }td| d|	  | dd }|d u r\td|d }t|}| d}|rt|trdD ]}||v r||vr|| ||< qr|	d||d ||d |d |d |d	}|d d ur|d dkr|d |d< |
r|
|d< |r||d< |r||d	< |r||d
< |r||d< | d}
d|vs|d d u r	 tt	 }
|
|d< d	|vs|d	 d u r|
d urt|
tr|
|d	< d|vs|d d u r|
d urt|
tr| j
|
d|d< td| |W S  ty(    w )NZlitellm_paramsmetadataproject_namer?   run_nameidrun_idparent_run_idtrace_id
session_iddotted_orderz"Langsmith Logging - project_name: z, run_name Zstandard_logging_objectz,Error logging request payload. Payload=none.requester_metadata)rK   	thread_idZconversation_idZllmresponseZ	startTimeZendTimeZrequest_tags)	nameZrun_typeZinputsZoutputsZsession_name
start_timeend_timetagsextraZ	error_strstatusZfailureerror)rH   z'Langsmith Logging data on langsmith: %s)getr2   r
   r)   	Exceptiondictr   strr   uuid4make_dot_order)r9   r:   response_objrQ   rR   rC   Z_litellm_paramsrD   rE   rF   rH   rI   rJ   rK   rL   payloadZextra_metadatarM   keydatar   r   r   _prepare_log_datao   s   


z!LangsmithLogger._prepare_log_datac           	      C   s   zW| j |d}t }||krtd|| W d S td|| | j|d}| j|||||d}| j	t
||d td| j d t| j| jkrU|   W d S W d S  tyf   td Y d S w )	Nr:   >Skipping Langsmith logging. Sampling rate={}, random_sample={}z;Langsmith Sync Layer Logging - kwargs: %s, response_obj: %sr:   r]   rQ   rR   rC   r`   rC   z/Langsmith, event added to queue. Will flush in z seconds...z/Langsmith Layer Error - log_success_event error)%_get_sampling_rate_to_use_for_requestrandomr
   infoformatr)   #_get_credentials_to_use_for_requestra   r7   appendLangsmithQueueObjectZflush_intervallenr6   _send_batchrX   	exception	r9   r:   r]   rQ   rR   r1   Zrandom_samplerC   r`   r   r   r   log_success_event   sL   z!LangsmithLogger.log_success_eventc           	         s   z[| j |d}t }||krtd|| W d S td|| | j|d}| j|||||d}| j	t
||d tdt| j| j t| j| jkrZ|  I d H  W d S W d S  tyk   td Y d S w )Nrb   rc   z<Langsmith Async Layer Logging - kwargs: %s, response_obj: %srd   re   1Langsmith logging: queue length %s, batch size %sz:Langsmith Layer Error - error logging async success event.)rf   rg   r
   rh   ri   r)   rj   ra   r7   rk   rl   rm   r6   flush_queuerX   ro   rp   r   r   r   async_log_success_event   sV   
z'LangsmithLogger.async_log_success_eventc           	         s   | j |d}t }||krtd|| d S td z:| j|d}| j|||||d}| jt	||d t
dt| j| j t| j| jkrW|  I d H  W d S W d S  tyh   td Y d S w )Nrb   rc   z Langsmith Failure Event Logging!rd   re   rr   z:Langsmith Layer Error - error logging async failure event.)rf   rg   r
   rh   ri   rj   ra   r7   rk   rl   r)   rm   r6   rs   rX   ro   rp   r   r   r   async_log_failure_event(  sN   

z'LangsmithLogger.async_log_failure_eventc                    s>   | j sdS |  }| D ]}| j|j|jdI dH  qdS )aX  
        Handles sending batches of runs to Langsmith

        self.log_queue contains LangsmithQueueObjects
            Each LangsmithQueueObject has the following:
                - "credentials" - credentials to use for the request (langsmith_api_key, langsmith_project, langsmith_base_url)
                - "data" - data to log on to langsmith for the request


        This function
         - groups the queue objects by credentials
         - loops through each unique credentials and sends batches to Langsmith


        This was added to support key/team based logging on langsmith
        NrC   queue_objects)r7   _group_batches_by_credentialsvalues_log_batch_on_langsmithrC   rw   )r9   Zbatch_groupsZbatch_groupr   r   r   async_send_batchN  s   z LangsmithLogger.async_send_batch/api/v1urlendpointapi_versionc                 C   s>   ||vr| d | }|dr| | S | d| S )N/)rstripendswith)r9   r}   r~   r   r   r   r   _add_endpoint_to_urli  s
   
z$LangsmithLogger._add_endpoint_to_urlrw   c              
      sf  |d }|d }| d}| |d}d|i}|r||d< dd |D }zWtd	t| | jr6td
 | jj|d|i|dI dH }	|	  |	j	dkr]t
d|	j	 d|	j  W dS | jrntdt| d W dS tdt| j d W dS  tjy }
 ztd|
jj	 d|
jj  W Y d}
~
dS d}
~
w ty   tdt   Y dS w )aV  
        Logs a batch of runs to Langsmith
        sends runs to /batch endpoint for the given credentials

        Args:
            credentials: LangsmithCredentialsObject
            queue_objects: List[LangsmithQueueObject]

        Returns: None

        Raises: Does not raise an exception, will only verbose_logger.exception()
        r@   r>   rA   z
runs/batch	x-api-keyx-tenant-idc                 S   s   g | ]}|d  qS )r`   r   ).0queue_objectr   r   r   
<listcomp>  s    z;LangsmithLogger._log_batch_on_langsmith.<locals>.<listcomp>z%Sending batch of %s runs to LangsmithzB[LANGSMITH MOCK] Mock mode enabled - API calls will be interceptedpost)r}   jsonheadersNi,  zLangsmith Error: z - z[LANGSMITH MOCK] Batch of z runs successfully mockedz	Batch of z runs successfully createdzLangsmith HTTP Error: zLangsmith Layer Error - )rW   r   r
   r)   rm   r(   r3   r   raise_for_statusstatus_coderV   textr7   httpxZHTTPStatusErrorro   rO   rX   	traceback
format_exc)r9   rC   rw   langsmith_api_baser   r!   r}   r   Zelements_to_logrO   er   r   r   rz   s  sT   






z'LangsmithLogger._log_batch_on_langsmithc                 C   s   i }| j D ]C}|d }|d du s|d du r#td|d |d  qt|d |d |d |dd}||vr@t|g d	||< || j| q|S )
z@Groups queue objects by credentials using a proper key structurerC   r>   Nr?   zBLangsmith Logging - credentials missing - api_key: %s, project: %sr@   rA   )Zapi_keyprojectbase_urlZ	tenant_idrv   )r7   r
   warningCredentialsKeyrW   
BatchGrouprw   rk   )r9   Zlog_queue_by_credentialsr   rC   r_   r   r   r   rx     s.   

z-LangsmithLogger._group_batches_by_credentialsr:   c                 C   s8   | dd }| j}|d ur| d}|d urt|}|S )N standard_callback_dynamic_paramsr    )rW   r1   r0   )r9   r:   r   r1   Z_sampling_rater   r   r   rf     s   
z5LangsmithLogger._get_sampling_rate_to_use_for_requestc                 C   sT   | dd}|dur%| j| dd| dd| dd| ddd}|S | j}|S )z
        Handles key/team based logging

        If standard_callback_dynamic_params are provided, use those credentials.

        Otherwise, use the default credentials.
        r   Nr   r   r   r!   r#   )rW   r*   r+   )r9   r:   r   rC   r   r   r   rj     s(   
z3LangsmithLogger._get_credentials_to_use_for_requestc                 C   sf   | j sdS zt }| rt|   W dS ||   W dS  ty2   t|   Y dS w )z'Calls async_send_batch in an event loopN)	r7   r$   get_event_loop
is_runningr8   r{   run_until_completeRuntimeErrorrun)r9   loopr   r   r   rn     s   zLangsmithLogger._send_batchc                 C   sZ   | j d }| j d }| j d}| d| }d|i}|r!||d< tjj||d}| S )Nr>   r@   rA   z/runs/r   r   )r}   r   )r+   rW   r4   Zmodule_level_clientr   )r9   rH   r   r   r!   r}   r   rO   r   r   r   get_run_by_id  s   

zLangsmithLogger.get_run_by_idrH   c                 C   s"   t tj}|}|dt| S )Nz%Y%m%dT%H%M%S%fZ)r   nowr   utcstrftimerZ   )r9   rH   stZid_r   r   r   r\      s   zLangsmithLogger.make_dot_order)NNNNN)NNNN)r|   )__name__
__module____qualname__r   rZ   r0   r'   rB   r*   ra   rq   rt   ru   r{   r   r   rl   rz   r   r   r   rx   r   rf   rj   rn   r   r\   __classcell__r   r   r;   r   r   (   s    /

f)*&


=!

 r   )"r$   r,   rg   r   r   Zlitellm._uuidr   r   r   typingr   r   r   r   r   Zpydanticr	   r4   Zlitellm._loggingr
   Z(litellm.integrations.custom_batch_loggerr   Z*litellm.integrations.langsmith_mock_clientr   r   Z&litellm.llms.custom_httpx.http_handlerr   r   Z$litellm.types.integrations.langsmithZlitellm.types.utilsr   r   r   r   r   r   r   r   <module>   s&   
