
    gwF                         d dl Z 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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 d d	lmZmZ d
 Z G d de      Zy)    N)datetimetimezone)AnyDictListOptional)	BaseModel)verbose_logger)CustomBatchLogger)get_async_httpx_clienthttpxSpecialProvider)*)StandardCallbackDynamicParamsStandardLoggingPayloadc                     t         j                  t         j                  t         j                  t        f}t        | |       S )N)typesCoroutineTypeFunctionTypeGeneratorTyper	   
isinstance)valuenon_serializable_typess     S/var/www/openai/venv/lib/python3.12/site-packages/litellm/integrations/langsmith.pyis_serializabler      s;    	 %!7888    c            	            e Zd Z	 	 	 ddee   dee   dee   f fdZ	 	 	 ddee   dee   dee   defdZdefdZd	 Z	d
 Z
d Zd Zdedee   fdZdeeef   fdZdeeef   defdZd Zd ZdefdZ xZS )LangsmithLoggerlangsmith_api_keylangsmith_projectlangsmith_base_urlc                    | j                  |||      | _        t        j                  d      Ot        j                  d      j	                         j                         rt        t        j                  d            nd| _        t        j                  dd      | _        t        t        j                        | _        t        j                  dd       xs t        j                  }|rt        |      | _        g | _        t%        j&                  | j)                                t%        j*                         | _        t/        | `  d	i |d| j,                  i y )
Nr   r   r    LANGSMITH_SAMPLING_RATE      ?LANGSMITH_DEFAULT_RUN_NAMELLMRun)llm_providerLANGSMITH_BATCH_SIZE
flush_lock )get_credentials_from_envdefault_credentialsosgetenvstripisdigitfloatsampling_ratelangsmith_default_run_namer   r   LoggingCallbackasync_httpx_clientlitellmlangsmith_batch_sizeint
batch_size	log_queueasynciocreate_taskperiodic_flushLockr)   super__init__)selfr   r   r    kwargs_batch_size	__class__s         r   r@   zLangsmithLogger.__init__%   s    $(#@#@//1 $A $
  yy23?		34::<DDF "))567 	 	 +-))((+
' #9-==#
 II,d3Sw7S7S 	 !+.DO57D//12!,,.>6>doo>r   returnc                    |xs t        j                  d      }|t        d      |xs t        j                  d      xs d}|t        d      |xs t        j                  d      xs d}|t        d      t        |||	      S )
NLANGSMITH_API_KEYz;Invalid Langsmith API Key given. _credentials_api_key=None.LANGSMITH_PROJECTzlitellm-completionz;Invalid Langsmith API Key given. _credentials_project=None.LANGSMITH_BASE_URLzhttps://api.smith.langchain.comz<Invalid Langsmith API Key given. _credentials_base_url=None.)rG   rI   rH   )r-   r.   	ExceptionLangsmithCredentialsObject)rA   r   r   r    _credentials_api_key_credentials_project_credentials_base_urls          r   r+   z(LangsmithLogger.get_credentials_from_envH   s      1RBII>Q4R'M  W+>!?WCW 	  'M   1yy-.10 	
 !(N  *242
 	
r   credentialsc           
         	 |j                  di       xs i }|j                  di       xs i }|j                  d|d         }|j                  d| j                        }	|j                  d|j                  dd             }
|j                  dd       }|j                  d	d       }|j                  d
d       }|j                  dd       }t        j                  d| d|	        |j                  dd       }|t	        d      |d   }|	d||d   ||d   |d   |d   |d	}|d   |d   dk(  r|d   |d<   |
r|
|d<   |r||d<   |r||d	<   |r||d
<   |r||d<   |j                  d      }
d|vs|d   #	 t        t        j                               }
|
|d<   d	|vs|d	   |
t        |
t
              r|
|d	<   d|vs|d   '|
%t        |
t
              r| j                  |
      |d<   t        j                  d|       |S # t        $ r  w xY w)Nlitellm_paramsmetadataproject_namerH   run_nameidrun_idparent_run_idtrace_id
session_iddotted_orderz"Langsmith Logging - project_name: z, run_name standard_logging_objectz,Error logging request payload. Payload=none.llmresponse	startTimeendTimerequest_tags)	namerun_typeinputsoutputssession_name
start_timeend_timetagsextra	error_strstatusfailureerror)rV   z'Langsmith Logging data on langsmith: %s)
getr3   r
   debugrJ   struuiduuid4r   make_dot_order)rA   rB   response_objrf   rg   rO   _litellm_paramsrR   rS   rT   rV   rW   rX   rY   rZ   payloaddatas                    r   _prepare_log_dataz!LangsmithLogger._prepare_log_datak   s   U	$jj)92>D"O&**:r:@bH#<<,? @L  ||J0O0OPH\\$Xt(DEF$LL$?M||J5H!lD9J#<<=L  4\N+hZX
 9?

)49G  NOOH
 !!!":. ,%k2#I./!
D {#/GH4E4R ' 4W#T
(5_%#+Z %/\"'3^$$(HHTNF44:#5 TZZ\*#T
 $&
#+'Jvs,C#)Z  d*'/'Jvs,C'+':':&':'I^$  !JDQK 		s   G:G= =Hc                    	 t        j                  d      Ot        j                  d      j                         j                         rt	        t        j                  d            nd}t        j
                         }||kD  r&t        j                  dj                  ||             y t        j                  d||       | j                  |      }| j                  |||||      }| j                  j                  t        ||             t        j                  d| j                   d	       t!        | j                        | j"                  k\  r| j%                          y y # t&        $ r t        j(                  d
       Y y w xY w)Nr#   r$   >Skipping Langsmith logging. Sampling rate={}, random_sample={}z;Langsmith Sync Layer Logging - kwargs: %s, response_obj: %srB   rB   rt   rf   rg   rO   rw   rO   z/Langsmith, event added to queue. Will flush in z seconds...z/Langsmith Layer Error - log_success_event error)r-   r.   r/   r0   r1   randomr
   infoformatro   #_get_credentials_to_use_for_requestrx   r:   appendLangsmithQueueObjectflush_intervallenr9   _send_batchrJ   	exception	rA   rB   rt   rf   rg   r2   random_samplerO   rw   s	            r   log_success_eventz!LangsmithLogger.log_success_event   sr   *	X 9967CII78>>@HHJ bii 9:; 	  #MMOM},##T[[%}
   M
 BB&BQK)))%!' * D NN!!$ +   A$BUBUAVVab 4>>"doo5  " 6  	X$$%VW	Xs   B$E# 'B:E# #FFc                   K   	 | j                   }t        j                         }||kD  r&t        j                  dj	                  ||             y t        j
                  d||       | j                  |      }| j                  |||||      }| j                  j                  t        ||             t        j
                  dt        | j                        | j                         t        | j                        | j                  k\  r| j                          d {    y y 7 # t        $ r t        j                  d       Y y w xY ww)Nrz   z<Langsmith Async Layer Logging - kwargs: %s, response_obj: %sr{   r|   r}   1Langsmith logging: queue length %s, batch size %sz:Langsmith Layer Error - error logging async success event.)r2   r~   r
   r   r   ro   r   rx   r:   r   r   r   r9   flush_queuerJ   r   r   s	            r   async_log_success_eventz'LangsmithLogger.async_log_success_event   s7    '	 ..M"MMOM},##T[[%}
   N
 BB&BQK)))%!' * D NN!!$ +   CDNN#
 4>>"doo5&&((( 6( 	$$L	sH   E
A
D& E
CD& D$D& "E
$D& &EE
EE
c                   K   | j                   }t        j                         }||kD  r&t        j                  dj	                  ||             y t        j                  d       	 | j                  |      }| j                  |||||      }| j                  j                  t        ||             t        j                  dt        | j                        | j                         t        | j                        | j                  k\  r| j                          d {    y y 7 # t        $ r t        j                  d       Y y w xY ww)Nrz   z Langsmith Failure Event Logging!r{   r|   r}   r   z:Langsmith Layer Error - error logging async failure event.)r2   r~   r
   r   r   r   rx   r:   r   r   ro   r   r9   r   rJ   r   r   s	            r   async_log_failure_eventz'LangsmithLogger.async_log_failure_event!  s-    **=(PWW!=
 >?	BB&BQK)))%!' * D NN!!$ +   CDNN#
 4>>"doo5&&((( 6( 	$$L	s=   A!E$B7D$ D"D$  E"D$ $EEEEc                    K   | j                   sy| j                         }|j                         D ]1  }| j                  |j                  |j
                         d{    3 y7 w)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rO   queue_objects)r:   _group_batches_by_credentialsvalues_log_batch_on_langsmithrO   r   )rA   batch_groupsbatch_groups      r   async_send_batchz LangsmithLogger.async_send_batchG  sg     " ~~99;'..0K..'33)77 /    1s   AA'A%A'r   c                   K   |d   }|d   }| d}d|i}|D cg c]  }|d   	 }}	 t        j                  dt        |             | j                  j	                  |d|i|       d	{   }	|	j                          |	j                  d
k\  r0t        j                  d|	j                   d|	j                          y	t        j                  dt        | j                         d       y	c c}w 7 # t        j                  $ rM}
t        j                  d|
j                  j                   d|
j                  j                          Y d	}
~
y	d	}
~
wt        $ r- t        j                  dt        j                                  Y y	w xY w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()
        rI   rG   z/runs/batch	x-api-keyrw   z%Sending batch of %s runs to Langsmithpost)urljsonheadersNi,  zLangsmith Error: z - z	Batch of z runs successfully createdzLangsmith HTTP Error: zLangsmith Layer Error - )r
   ro   r   r5   r   raise_for_statusstatus_coderm   textr:   httpxHTTPStatusErrorr   r]   rJ   	traceback
format_exc)rA   rO   r   langsmith_api_baser   r   r   queue_objectelements_to_logr]   es              r   r   z'LangsmithLogger._log_batch_on_langsmithb  s    " ))=>'(;<#$K0 12DQRML</MR	  7_9M "4499o. :  H
 %%'##s*$$'(<(<'=SP $$DNN 344NO% S $$ 	$$()?)?(@AJJOOCTU   	$$*9+?+?+A*BC	se   F
C,F
AC3 +C1,AC3 >F
?,C3 +F
1C3 3FAE	F
6FF
FF
c                     i }| j                   D ]P  }|d   }t        |d   |d   |d         }||vrt        |g       ||<   ||   j                  j	                  |       R |S )z@Groups queue objects by credentials using a proper key structurerO   rG   rH   rI   )api_keyprojectbase_urlr   )r:   CredentialsKey
BatchGroupr   r   )rA   log_queue_by_credentialsr   rO   keys        r   r   z-LangsmithLogger._group_batches_by_credentials  s    EG  NNL&}5K #$78#$78$%9:C 220: +21(- %S)77>>|L + ('r   rB   c                     |j                  dd      }|F| j                  |j                  dd      |j                  dd      |j                  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.
         standard_callback_dynamic_paramsNr   r   r    r"   )rn   r+   r,   )rA   rB   r   rO   s       r   r   z3LangsmithLogger._get_credentials_to_use_for_request  s     JJ94@ 	) ,777"B"F"F'# #C"F"F'# $D#G#G($$ 8 
K  22Kr   c                 R   | j                   sy	 t        j                         }|j                         r$t        j                  | j                                y|j                  | j                                y# t        $ r& t        j                  | j                                Y yw xY w)z'Calls async_send_batch in an event loopN)	r:   r;   get_event_loop
is_runningr<   r   run_until_completeRuntimeErrorrun)rA   loops     r   r   zLangsmithLogger._send_batch  s}    ~~	1))+D ##D$9$9$;< ''(=(=(?@ 	1KK--/0	1s   AA7 A7 7,B&%B&c                     | j                   d   }| j                   d   }| d| }t        j                  j                  |d|i      }|j	                         S )NrG   rI   z/runs/r   )r   r   )r,   r6   module_level_clientrn   r   )rA   rV   r   r   r   r]   s         r   get_run_by_idzLangsmithLogger.get_run_by_id  sl     445HI!556JK#$F6(3..22 "34 3 

 }}r   rV   c                     t        j                  t        j                        }|}|j	                  d      t        |      z   S )Nz%Y%m%dT%H%M%S%fZ)r   nowr   utcstrftimerp   )rA   rV   stid_s       r   rs   zLangsmithLogger.make_dot_order  s2    \\(,,'{{-.S99r   )NNN)__name__
__module____qualname__r   rp   r@   rK   r+   rx   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rs   __classcell__)rD   s   @r   r   r   $   s    ,0+/,0	!?#C=!? $C=!? %SM	!?J ,0+/,0	!
#C=!
 $C=!
 %SM	!

 
$!
F] 0]~+XZ(T$L61/1 011f(tNJ4N/O (*38n	#:1$:S :r   r   )r;   r-   r~   r   r   rq   r   r   typingr   r   r   r   r   pydanticr	   r6   litellm._loggingr
   (litellm.integrations.custom_batch_loggerr   &litellm.llms.custom_httpx.http_handlerr   r   $litellm.types.integrations.langsmithlitellm.types.utilsr   r   r   r   r*   r   r   <module>r      sR     	     ' , ,    + F 3 U9F:' F:r   