
    j J                         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 d d
lmZmZ d Z G d de      Zy)    N)uuid)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     w/Users/manta/Documents/Projects/TheRoad-I1/backend/.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   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dedededef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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_urllangsmith_sampling_ratec                    t        j                         | _        t        |   d	i |d| j                  i | j                  |||      | _        t        j                  d      St        j                  d      j                         j                         r"|xs  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.                  | j1                                y )
N
flush_lockr   r    r!   LANGSMITH_SAMPLING_RATEg      ?LANGSMITH_DEFAULT_RUN_NAMELLMRun)llm_providerLANGSMITH_BATCH_SIZE )asyncioLockr$   super__init__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create_taskperiodic_flush)selfr   r    r!   r"   kwargs_batch_size	__class__s          r   r/   zLangsmithLogger.__init__%   s'    ",,.>6>doo>#'#@#@//1 $A $
  yy23?		34::<DDF $ ;RYY89:  	 +-))((+
' #9-==#
 II,d3Sw7S7S 	 !+.DO57D//12r   returnc                     |xs t        j                  d      }|xs t        j                  d      xs d}|xs t        j                  d      xs d}t        |||      S )NLANGSMITH_API_KEYLANGSMITH_PROJECTzlitellm-completionLANGSMITH_BASE_URLzhttps://api.smith.langchain.com)rH   rJ   rI   )r2   r3   LangsmithCredentialsObject)rB   r   r    r!   _credentials_api_key_credentials_project_credentials_base_urls          r   r0   z(LangsmithLogger.get_credentials_from_envJ   sr      1RBII>Q4RW+>!?WCW 	  1yy-.10 	 *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_namerI   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)
getr8   r   debug	Exceptionstrr   uuid4r   make_dot_order)rB   rC   response_objrf   rg   rO   _litellm_paramsrR   rS   rT   rV   rW   rX   rY   rZ   payloaddatas                    r   _prepare_log_dataz!LangsmithLogger._prepare_log_data`   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                 f   	 | j                  |      }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)	NrC   >Skipping Langsmith logging. Sampling rate={}, random_sample={}z;Langsmith Sync Layer Logging - kwargs: %s, response_obj: %srC   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)%_get_sampling_rate_to_use_for_requestrandomr   infoformatro   #_get_credentials_to_use_for_requestrx   r?   appendLangsmithQueueObjectflush_intervallenr>   _send_batchrp   	exception	rB   rC   rt   rf   rg   r7   random_samplerO   rw   s	            r   log_success_eventz!LangsmithLogger.log_success_event   s4   &	X FFfFUM"MMOM},##T[[%}
   M BB&BQK)))%!' * D NN!!$ +   A$BUBUAVVab 4>>"doo5  " 6  	X$$%VW	Xs   AD B:D D0/D0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   r{   z<Langsmith Async Layer Logging - kwargs: %s, response_obj: %sr|   r}   1Langsmith logging: queue length %s, batch size %sz:Langsmith Layer Error - error logging async success event.)r~   r   r   r   r   ro   r   rx   r?   r   r   r   r>   flush_queuerp   r   r   s	            r   async_log_success_eventz'LangsmithLogger.async_log_success_event   s?    '	 FFfFUM"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   r{   z Langsmith Failure Event Logging!r|   r}   r   z:Langsmith Layer Error - error logging async failure event.)r~   r   r   r   r   r   rx   r?   r   r   ro   r   r>   r   rp   r   r   s	            r   async_log_failure_eventz'LangsmithLogger.async_log_failure_event  s5    BB&BQ=(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   )rB   batch_groupsbatch_groups      r   async_send_batchz LangsmithLogger.async_send_batch8  sg     " ~~99;'..0K..'33)77 /    1s   AA'A%A'urlendpointapi_versionc                 p    ||vr|j                  d       | }|j                  d      r| | S | d| S )N/)rstripendswith)rB   r   r   r   s       r   _add_endpoint_to_urlz$LangsmithLogger._add_endpoint_to_urlS  sO     c!ZZ_%k]3C<<U8*%%az""r   r   c                 2  K   |d   }|d   }| j                  |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()
        rJ   rH   z
runs/batch	x-api-keyrw   z%Sending batch of %s runs to Langsmithpost)r   jsonheadersNi,  zLangsmith Error: z - z	Batch of z runs successfully createdzLangsmith HTTP Error: zLangsmith Layer Error - )r   r   ro   r   r:   r   raise_for_statusstatus_coderm   textr?   httpxHTTPStatusErrorr   r]   rp   	traceback
format_exc)rB   rO   r   langsmith_api_baser   r   r   queue_objectelements_to_logr]   es              r   r   z'LangsmithLogger._log_batch_on_langsmith]  s    " ))=>'(;<''(:LI 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C9FAD  8C>9AD  F,D  8F>D   FAEF6FFFFc                    i }| j                   D ]x  }|d   }|d   |d   t        j                  d|d   |d          0t        |d   |d   |d         }||vrt	        |g       ||<   ||   j
                  j                  |       z |S )z@Groups queue objects by credentials using a proper key structurerO   rH   rI   zBLangsmith Logging - credentials missing - api_key: %s, project: %srJ   )api_keyprojectbase_urlr   )r?   r   warningCredentialsKey
BatchGroupr   r   )rB   log_queue_by_credentialsr   rO   keys        r   r   z-LangsmithLogger._group_batches_by_credentials  s    EG  NNL&}5K /0823;&&X 34 34
  #$78#$78$%9:C 220: +21(- %S)77>>|L1 +4 ('r   rC   c                     |j                  dd       }| j                  }||j                  d      }|t        |      }|S )N standard_callback_dynamic_paramsr"   )rn   r7   r6   )rB   rC   r   r7   _sampling_rates        r   r~   z5LangsmithLogger._get_sampling_rate_to_use_for_request  sT    JJ94@ 	)  $11+7=AA)N ) %n 5r   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.
        r   Nr   r    r!   r%   )rn   r0   r1   )rB   rC   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)rB   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 )NrH   rJ   z/runs/r   )r   r   )r1   r;   module_level_clientrn   r   )rB   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strftimerq   )rB   rV   stid_s       r   rs   zLangsmithLogger.make_dot_order  s2    \\(,,'{{-.S99r   )NNNN)NNN)z/api/v1)__name__
__module____qualname__r	   rq   r6   r/   rK   r0   rx   r   r   r   r   r   r   r   r   r   r   r   r   r   r~   r   r   r   rs   __classcell__)rE   s   @r   r   r   $   sg    ,0+/,037#3#C=#3 $C=#3 %SM	#3
 "*%#3N ,0+/,0	
#C=
 $C=
 %SM	

 
$
,] 0]~'XR(T$L8 ;D##"%#47#	#1/1 011f(tNJ4N/O (@DcN u 38n	#:1$:S :r   r   )r,   r2   r   r   r   litellm._uuidr   r   r   typingr   r   r   r	   r   pydanticr
   r;   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X:' X:r   