a
    `g;e                     @  s  d Z ddlmZ 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	Z	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mZmZmZmZmZmZmZmZm Z m!Z!m"Z" ddl#m$Z% ddl&Z&ddl'Z'ddl(m)Z) ddl*m+Z+ dd	l,m-Z. e/e0Z1G d
d de2Z3G dd de3Z4G dd de3Z5G dd de3Z6G dd de3Z7G dd de3Z8G dd de3Z9G dd de3Z:G dd de3Z;G dd de<Z=G dd de=Z>dd d!d"d#d$Z?d%d&d'd(Z@d)d*d+d,d-ZAd.d/d0d1d2ZBd3d4d5d6d7ZCejDd8d9d:d4d/d;d<d=ZEd>d4d?d@dAZFd>d>d?dBdCZGd>dDd?dEdFZHd>dGdHdIdJZId>dDdKdLdMZJd>d4dHdNdOZKd>d4dKdPdQZLejDd8d9dRd&dSdTZMdUdVd?dWdXZNdYd%dZd[d\ZOejDd]d9dd^d_d4d`dad`dbdcddZPejDd8d9dd`d&dfdgZQG dhdi diejRZSG djdk dkejRZTG dldm dme+ZUeV ZWejXdndodpdqdrdsZYd`d`dtdudvZZejXddwdxdpdydzd{Z[ejXdd|dxdpdyd}d~Z\d4d&ddZ]e dZ^dddd:d:ddddZ_dddddZ`d4d4d%dddZad4ddddZbe)dZcG dd deZdd`d4dddZed`d`dddZfd4d%dddZgejDdd9d`d4dddZhdd*d:d4dddZidd%dddZjdS )zGeneric utility functions.    )annotationsN)FutureThreadPoolExecutor)AnyCallableDict	GeneratorIterableIteratorListLiteralMappingOptionalSequenceTupleTypeVarUnioncast)parse)	ParamSpec)Retry)schemasc                   @  s   e Zd ZdZdS )LangSmithErrorz=An error occurred while communicating with the LangSmith API.N__name__
__module____qualname____doc__ r   r   ]/var/www/html/cobodadashboardai.evdpl.com/venv/lib/python3.9/site-packages/langsmith/utils.pyr   0   s   r   c                   @  s   e Zd ZdZdS )LangSmithAPIErrorz9Internal server error while communicating with LangSmith.Nr   r   r   r   r   r    4   s   r    c                   @  s   e Zd ZdZdS )LangSmithRequestTimeoutz*Client took too long to send request body.Nr   r   r   r   r   r!   8   s   r!   c                   @  s   e Zd ZdZdS )LangSmithUserErrorzAUser error caused an exception when communicating with LangSmith.Nr   r   r   r   r   r"   <   s   r"   c                   @  s   e Zd ZdZdS )LangSmithRateLimitErrorz7You have exceeded the rate limit for the LangSmith API.Nr   r   r   r   r   r#   @   s   r#   c                   @  s   e Zd ZdZdS )LangSmithAuthErrorz-Couldn't authenticate with the LangSmith API.Nr   r   r   r   r   r$   D   s   r$   c                   @  s   e Zd ZdZdS )LangSmithNotFoundErrorz%Couldn't find the requested resource.Nr   r   r   r   r   r%   H   s   r%   c                   @  s   e Zd ZdZdS )LangSmithConflictErrorzThe resource already exists.Nr   r   r   r   r   r&   L   s   r&   c                   @  s   e Zd ZdZdS )LangSmithConnectionErrorz&Couldn't connect to the LangSmith API.Nr   r   r   r   r   r'   P   s   r'   c                   @  s   e Zd ZdZdS )LangSmithWarningzBase class for warnings.Nr   r   r   r   r   r(   W   s   r(   c                   @  s   e Zd ZdZdS )LangSmithMissingAPIKeyWarningzWarning for missing API key.Nr   r   r   r   r   r)   [   s   r)   zOptional[dict]zUnion[bool, Literal['local']])ctxreturnc                 C  sT   ddl m}m} | p| }|d dur.|d S | r8dS tdtddd	d	}|d
kS )z"Return True if tracing is enabled.r   )get_current_run_treeget_tracing_contextenabledNTZ
TRACING_V2ZTRACING defaulttrue)Zlangsmith.run_helpersr,   r-   get_env_var)r*   r,   r-   ZtcZ
var_resultr   r   r   tracing_is_enabled_   s    
r4   boolr+   c                   C  s   t ddddkS )z"Return True if testing is enabled.ZTEST_TRACKINGr/   r0   falser3   r   r   r   r   test_tracking_is_disabledr   s    r9   zTuple[str, ...]r   )
arg_groupsr+   c                    s   ddd fdd}|S )z7Validate specified keyword args are mutually exclusive.r   )funcr+   c                   s&   t  dddd fdd}|S )Nr   )argskwargsr+   c                    s\    fddD }dd t |D }|rNfdd|D }tdd| | i  S )z3Validate exactly one arg in each group is not None.c                   s"   g | ]}t  fd d|D qS )c                 3  s    | ]}  |d urdV  qd S )N   )get).0argr=   r   r   	<genexpr>       zJxor_args.<locals>.decorator.<locals>.wrapper.<locals>.<listcomp>.<genexpr>)sum)r@   Z	arg_grouprB   r   r   
<listcomp>~   s   z@xor_args.<locals>.decorator.<locals>.wrapper.<locals>.<listcomp>c                 S  s   g | ]\}}|d kr|qS r>   r   )r@   icountr   r   r   rF      rD   c                   s   g | ]}d   | qS ), )join)r@   rH   r:   r   r   rF      rD   zFExactly one argument in each of the following groups must be defined: rJ   )	enumerate
ValueErrorrK   )r<   r=   countsZinvalid_groupsZinvalid_group_names)r:   r;   rB   r   wrapper{   s    
z,xor_args.<locals>.decorator.<locals>.wrapper)	functoolswraps)r;   rP   rL   )r;   r   	decoratorz   s    zxor_args.<locals>.decoratorr   )r:   rS   r   rL   r   xor_argsw   s    rT   z(Union[requests.Response, httpx.Response]None)responser+   c              
   C  sL   z|    W n: tjyF } z tt|| j|W Y d}~n
d}~0 0 dS )z&Raise an error with the response text.N)raise_for_statusrequests	HTTPErrorstrtext)rV   er   r   r   raise_for_status_with_text   s    r]   zUnion[enum.Enum, str]rZ   )enur+   c                 C  s   t | tjr| jS | S )zGet the value of a string enum.)
isinstanceenumEnumvalue)r^   r   r   r   get_enum_value   s    rc   r>   )maxsizeint)levelmessager+   c                 C  s   t | | dS )z4Log a message at the specified level, but only once.N)_LOGGERlog)rf   rg   r   r   r   log_once   s    rj   zMapping[str, Any])rg   r+   c                 C  sh   | st dd| v rDd| vr,t d|  d| d d dd S d	| vr\t d
|  d| d	 S d S )NMessage is empty.lcid*Unexpected format for serialized message: z Message does not have an id.Messager/   type&Unexpected format for stored message: z Message does not have a type.)rN   replacelowerrg   r   r   r   _get_message_type   s    

rv   c                 C  sX   | st dd| v r4d| vr,t d|  d| d S d| vrLt d|  d| d S d S )	Nrk   rl   r=   rn   z Message does not have kwargs.datarr   z Message does not have data.)rN   ru   r   r   r   _get_message_fields   s    

rx   zDict[str, Any]c                 C  s   t | }t| }||dS )z&Extract message from a message object.rq   rw   )rv   rx   )rg   Zmessage_typeZmessage_datar   r   r   _convert_message   s    rz   zList[Dict[str, Any]])inputsr+   c                 C  sD   d| v rdd | d D S d| v r0t | d gS td|  ddS )aG  Extract messages from the given inputs dictionary.

    Args:
        inputs (Mapping[str, Any]): The inputs dictionary.

    Returns:
        List[Dict[str, Any]]: A list of dictionaries representing
            the extracted messages.

    Raises:
        ValueError: If no message(s) are found in the inputs dictionary.
    messagesc                 S  s   g | ]}t |qS r   )rz   )r@   rg   r   r   r   rF      rD   z,get_messages_from_inputs.<locals>.<listcomp>rg   z-Could not find message(s) in run with inputs .N)rz   rN   )r{   r   r   r   get_messages_from_inputs   s
    r~   )outputsr+   c                 C  sr   d| vrt d|  d| d }t|dkrFt dt| d| d|d }d|vrft d	| d
t|d S )a'  Retrieve the message generation from the given outputs.

    Args:
        outputs (Mapping[str, Any]): The outputs dictionary.

    Returns:
        Dict[str, Any]: The message generation.

    Raises:
        ValueError: If no generations are found or if multiple generations are present.
    generations,No generations found in in run with output: r}   r>   z3Chat examples expect exactly one generation. Found z generations: r   rg   z"Unexpected format for generation: z%. Generation does not have a message.)rN   lenrz   r   r   Zfirst_generationr   r   r   #get_message_generation_from_outputs   s"    
r   c                 C  sX   d| v r| d S d| v rD| d }t |dkr4|d S td|  dtd|  dd	S )
zRetrieve the prompt from the given inputs.

    Args:
        inputs (Mapping[str, Any]): The inputs dictionary.

    Returns:
        str: The prompt.

    Raises:
        ValueError: If the prompt is not found or if multiple prompts are present.
    promptpromptsr>   r   z$Multiple prompts in run with inputs z!. Please create example manually.z)Could not find prompt in run with inputs r}   N)r   rN   )r{   r   r   r   r   get_prompt_from_inputs  s    
r   c                 C  s`   d| vrt d|  d| d }t|dkr:t d| |d }d|vrXt d| |d S )	z(Get the LLM generation from the outputs.r   r   r}   r>   zMultiple generations in run: r   r[   zNo text in generation: )rN   r   r   r   r   r   get_llm_generation_from_outputs  s    r   z	List[str]c                   C  s   z"t jg dt jt jd ddgW S  t jtfy   z$t jddgt jt jd dgW  Y S  t jtfyz   tdY n0 Y n0 dS )	z7Get the correct docker compose command for this system.)dockercompose	--version)stdoutstderrr   r   zdocker-composer   zNeither 'docker compose' nor 'docker-compose' commands are available. Please install the Docker server following the instructions for your operating system at https://docs.docker.com/engine/install/N)
subprocess
check_callDEVNULLCalledProcessErrorFileNotFoundErrorrN   r   r   r   r   get_docker_compose_command,  s&    
r   zls_schemas.BaseMessageLikedictc                 C  s<   | j d| jid}| jr8t| jdkr8i | j|d d< |S )z*Convert a LangChain message to an example.contentry   r   rw   additional_kwargs)rq   r   r   r   )rg   Z	convertedr   r   r   convert_langchain_messageG  s    r   object)objr+   c                 C  s@   t tt| ddttt| ddtt| do:tt| dtgS )zCheck if the given object is similar to BaseMessage.

    Args:
        obj (object): The object to check.

    Returns:
        bool: True if the object is similar to BaseMessage, False otherwise.
    r   Nr   rq   )allr_   getattrrZ   r   hasattr)r   r   r   r   is_base_message_likeS  s    	r   d   )Z	LANGSMITHZ	LANGCHAIN)
namespaceszOptional[str]r   )namer1   r   r+   c                  s<    fdd|D }|D ]  t j }|dur|  S q|S )a+  Retrieve an environment variable from a list of namespaces.

    Args:
        name (str): The name of the environment variable.
        default (Optional[str], optional): The default value to return if the
            environment variable is not found. Defaults to None.
        namespaces (Tuple, optional): A tuple of namespaces to search for the
            environment variable. Defaults to ("LANGSMITH", "LANGCHAINs").

    Returns:
        Optional[str]: The value of the environment variable if found,
            otherwise the default value.
    c                   s   g | ]}| d   qS )_r   )r@   	namespacer   r   r   rF   y  rD   zget_env_var.<locals>.<listcomp>N)osenvironr?   )r   r1   r   namesrb   r   r   r   r3   e  s    
r3   Tc              	   C  s&   t jdtdtd| rdndddS )z,Get the project name for a LangSmith tracer.ZHOSTED_LANGSERVE_PROJECT_NAMEZPROJECTZSESSIONr1   Nr0   )r   r   r?   r3   )Zreturn_default_valuer   r   r   get_tracer_project  s    r   c                      s:   e Zd ZdZddddd fddZdd	d
dZ  ZS )FilterPoolFullWarningzFFilter urrllib3 warnings logged when the connection pool isn't reused.r/   rZ   rU   )r   hostr+   c                   s   t  | || _dS )zInitialize the FilterPoolFullWarning filter.

        Args:
            name (str, optional): The name of the filter. Defaults to "".
            host (str, optional): The host to filter. Defaults to "".
        N)super__init___host)selfr   r   	__class__r   r   r     s    zFilterPoolFullWarning.__init__r5   r6   c                 C  s   |  }d|vrdS | j|vS )zJurllib3.connectionpool:Connection pool is full, discarding connection: ...z.Connection pool is full, discarding connectionT)
getMessager   r   recordmsgr   r   r   filter  s    zFilterPoolFullWarning.filter)r/   r/   )r   r   r   r   r   r   __classcell__r   r   r   r   r     s   
r   c                   @  s   e Zd ZdZddddZdS )FilterLangSmithRetryz!Filter for retries from this lib.r5   r6   c                 C  s   |  }d|vS )z!Filter retries from this library.LangSmithRetry)r   r   r   r   r   r     s    zFilterLangSmithRetry.filterN)r   r   r   r   r   r   r   r   r   r     s   r   c                   @  s   e Zd ZdZdS )r   z&Wrapper to filter logs with this name.Nr   r   r   r   r   r     s   r   zlogging.LoggerzSequence[logging.Filter]zGenerator[None, None, None])loggerfiltersr+   c                 c  s   t $ |D ]}| | q
W d   n1 s.0    Y  zddV  W t F |D ]0}z| | W qL tyz   td Y qL0 qLW d   q1 s0    Y  n\t F |D ]0}z| | W q ty   td Y q0 qW d   n1 s0    Y  0 dS )zTemporarily adds specified filters to a logger.

    Parameters:
    - logger: The logger to which the filters will be added.
    - filters: A sequence of logging.Filter objects to be temporarily added
        to the logger.
    NzFailed to remove filter)_FILTER_LOCK	addFilterremoveFilterBaseExceptionrh   warning)r   r   r   r   r   r   filter_logs  s"    *2r   )cacher+   c                 C  s   | dur| S t dddS )zGet the testing cache directory.

    Args:
        cache (Optional[str]): The cache path.

    Returns:
        Optional[str]: The cache path if provided, otherwise the value
        from the LANGSMITH_TEST_CACHE environment variable.
    NZ
TEST_CACHEr0   r8   )r   r   r   r   get_cache_dir  s    
r   zUnion[str, pathlib.Path]zOptional[Sequence[str]])pathignore_hostsr+   c                 #  s   zddl }W n ty&   tdY n0 ddlm} |  ddd fdd}tj| \}}|j|	d	sx|	d
r|dnd|dg dddg|d}|
| dV  W d   n1 s0    Y  dS )Use a cache for requests.r   NzNvcrpy is required to use caching. Install with:pip install -U "langsmith[vcr]")_patchr   )requestr+   c                   s(   rt  fddD rd S i  _ S )Nc                 3  s   | ]} j |V  qd S N)url
startswith)r@   r   r   r   r   rC     rD   z>with_cache.<locals>._filter_request_headers.<locals>.<genexpr>)anyheadersr   r   r   r   _filter_request_headers  s    z+with_cache.<locals>._filter_request_headersz.yamlz.ymlyamljsonZnew_episodes)urimethodr   bodyauthorizationz
Set-Cookie)
serializerZcassette_library_dirZrecord_modeZmatch_onZfilter_headersZbefore_record_request)vcrImportErrorZlangsmith._internalr   patch_urllib3r   r   splitZVCRendswithZuse_cassette)r   r   r   r   r   	cache_dirZ
cache_fileZls_vcrr   r   r   
with_cache  s0    
r   z"Optional[Union[str, pathlib.Path]]c                 c  sD   | dur:t | | dV  W d   q@1 s.0    Y  ndV  dS )r   N)r   )r   r   r   r   r   with_optional_cache  s    &r   c                  C  s&   t jt  } dd | D }d|S )Nc                 S  s   g | ]}d |vr|qS )z
langsmith/r   )r@   liner   r   r   rF     rD   z_format_exc.<locals>.<listcomp>r/   )	tracebackformat_exceptionsysexc_inforK   )Ztb_linesZfiltered_linesr   r   r   _format_exc  s    r   T   zDict[int, Any])valmemo	max_depth_depthr+   c                   s   t | }t|dd }|d ur:z
|W S  ty8   Y n0  krF| S t| trj fdd|  D S t| tr fdd| D S t| trt fdd| D S t| tr· fdd	| D S | S )
N__deepcopy__c              	     s2   i | ]*\}}t | d  t | d  qS rG   _middle_copy)r@   kvr   r   r   r   r   
<dictcomp>4  s   z _middle_copy.<locals>.<dictcomp>c                   s   g | ]}t | d  qS rG   r   r@   itemr   r   r   rF   ;  rD   z _middle_copy.<locals>.<listcomp>c                 3  s    | ]}t | d  V  qdS )r>   Nr   r   r   r   r   rC   =  rD   z_middle_copy.<locals>.<genexpr>c                   s   h | ]}t | d  qS rG   r   r   r   r   r   	<setcomp>?  rD   z_middle_copy.<locals>.<setcomp>)	rq   r   r   r_   r   itemslisttupleset)r   r   r   r   clscopierr   r   r   r   &  s(    




r   )r   r+   c              
   C  sV   i }zt | |W S  tyP } z&tdt| t| |W  Y d}~S d}~0 0 dS )zDeep copy a value with a compromise for uncopyable objects.

    Args:
        val: The value to be deep copied.

    Returns:
        The deep copied value.
    zFailed to deepcopy input: %sN)copydeepcopyr   rh   debugreprr   )r   r   r\   r   r   r   deepish_copyD  s    	r   )current_versiontarget_versionr+   c                 C  s(   ddl m} || }||}||kS )zGCheck if the current version is greater or equal to the target version.r   )version)	packagingr  r   )r   r   r  currenttargetr   r   r   is_version_greater_or_equalY  s    

r  zTuple[str, str, str])
identifierr+   c                 C  s   | r&|  ddks&| ds&| dr4td|  | dd}|d }t|dkr\|d nd}d|v r|dd\}}|r|std|  |||fS |std|  d||fS dS )	aE  Parse a string in the format of owner/name:hash, name:hash, owner/name, or name.

    Args:
        identifier (str): The prompt identifier to parse.

    Returns:
        Tuple[str, str, str]: A tuple containing (owner, name, hash).

    Raises:
        ValueError: If the identifier doesn't match the expected formats.
    /r>   zInvalid identifier format: :r   Zlatest-N)rI   r   r   rN   r   r   )r  partsZ
owner_namecommitownerr   r   r   r   parse_prompt_identifierb  s(    
r  Pc                      sN   e Zd ZdZddddd fddZd	d
ddddddd fddZ  ZS )ContextThreadPoolExecutorz?ThreadPoolExecutor that copies the context to the child thread.zCallable[P, T]zP.argszP.kwargsz	Future[T])r;   r<   r=   r+   c                   s6   t  ttdtf tjt j	|g|R i |S )aC  Submit a function to the executor.

        Args:
            func (Callable[..., T]): The function to submit.
            *args (Any): The positional arguments to the function.
            **kwargs (Any): The keyword arguments to the function.

        Returns:
            Future[T]: The future for the function.
        .)
r   submitr   r   r   rQ   partialcontextvarscopy_contextrun)r   r;   r<   r=   r   r   r   r    s    

z ContextThreadPoolExecutor.submitNr>   timeout	chunksizezCallable[..., T]zIterable[Any]zOptional[float]re   zIterator[T])fn	iterablesr  r  r+   c                  sL   dd t t|d D  ddd fdd}t j|g|R ||d	S )
a  Return an iterator equivalent to stdlib map.

        Each function will receive its own copy of the context from the parent thread.

        Args:
            fn: A callable that will take as many arguments as there are
                passed iterables.
            timeout: The maximum number of seconds to wait. If None, then there
                is no limit on the wait time.
            chunksize: The size of the chunks the iterable will be broken into
                before being passed to a child process. This argument is only
                used by ProcessPoolExecutor; it is ignored by
                ThreadPoolExecutor.

        Returns:
            An iterator equivalent to: map(func, *iterables) but the calls may
            be evaluated out-of-order.

        Raises:
            TimeoutError: If the entire result iterator could not be generated
                before the given timeout.
            Exception: If fn(*args) raises for any values.
        c                 S  s   g | ]}t  qS r   )r  r  )r@   r   r   r   r   rF     rD   z1ContextThreadPoolExecutor.map.<locals>.<listcomp>r   r   r   )r<   r+   c                    s      jg| R  S r   )popr  )r<   Zcontextsr  r   r   _wrapped_fn  s    z2ContextThreadPoolExecutor.map.<locals>._wrapped_fnr  )ranger   r   map)r   r  r  r  r  r  r   r  r   r    s    zContextThreadPoolExecutor.map)r   r   r   r   r  r  r   r   r   r   r   r    s
   r  )api_urlr+   c                 C  s@   | pt ttddd}| s&td| dddS )zBGet the LangSmith API URL from the environment or the given value.ZENDPOINTzhttps://api.smith.langchain.comr0   z!LangSmith API URL cannot be empty"'r  )r   rZ   r3   stripr"   rstrip)r  Z_api_urlr   r   r   get_api_url  s    r$  )api_keyr+   c                 C  s@   | dur| n
t ddd}|du s(| s,dS | ddS )z8Get the API key from the environment or the given value.NZAPI_KEYr0   r   r!  )r3   r"  )r%  Zapi_key_r   r   r   get_api_key  s    r&  )r   r+   c                 C  sZ   z>t | jdd }t|}|dkp<|dp<|dW S  tjyT   Y dS 0 dS )zCheck if the URL is localhost.

    Parameters
    ----------
    url : str
        The URL to check.

    Returns:
    -------
    bool
        True if the URL is localhost, False otherwise.
    r  r   z	127.0.0.1z0.0.0.0z::FN)urllib_parseurlsplitnetlocr   socketgethostbynamer   gaierror)r   r)  ipr   r   r   _is_localhost  s    
r.     )web_urlr  c                 C  s   | r| S t |}t|r d}nt|jdrZt|jddd }t |j|d}nt|jdrt|jddd }t |j|d}nFt|j	
drd}n0t|j	
d	rd
}nt|j	
drd}nd}|S )z1Get the host URL based on the web URL or API URL.zhttp://localhostz/apir>   r   )r   z/api/v1zeu.zhttps://eu.smith.langchain.comzdev.zhttps://dev.smith.langchain.comzbeta.z https://beta.smith.langchain.comzhttps://smith.langchain.com)r'  urlparser.  rZ   r   r   rsplit
urlunparse_replacer)  r   )r0  r  
parsed_urllinknew_pathr   r   r   get_host_url  s&    
r8  )r  depthr+   c                 C  s   |dkst | st| S t| dr(| jS t| tjrDt| j|d S t| dr|t| drlt| j	drl| j	jS t| j
|d S t| S )Nr/  r   r>   __call__r   )callablerZ   r   r   r_   rQ   r  _get_function_namer;   r   r:  )r  r9  r   r   r   r<    s    

r<  r   c                 C  s(   | du p&| dkp&| dkp&| dkp&| dkS )zCheck if the value is truish.

    Args:
        val (Any): The value to check.

    Returns:
        bool: True if the value is truish, False otherwise.
    Tr2   TrueTRUE1r   )r   r   r   r   	is_truish%  s    	r@  )N)N)T)N)N)r   r   )r   )kr   
__future__r   
contextlibr  r   r`   rQ   loggingr   pathlibr*  r   r   	threadingr   concurrent.futuresr   r   typingr   r   r   r   r	   r
   r   r   r   r   r   r   r   r   r   urllibr   r'  ZhttpxrX   Ztyping_extensionsr   Zurllib3.utilr   Z	langsmithr   Z
ls_schemas	getLoggerr   rh   	Exceptionr   r    r!   r"   r#   r$   r%   r&   r'   UserWarningr(   r)   r4   r9   rT   r]   rc   	lru_cacherj   rv   rx   rz   r~   r   r   r   r   r   r   r3   r   Filterr   r   r   RLockr   contextmanagerr   r   r   r   r   r   r   r   r  r  r  r  r$  r&  r.  r8  r<  r@  r   r   r   r   <module>   s   D




 

 *  	#G
