a
    bg?                     @   s|  d dl 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 d dlmZmZ d dlmZ d dlmZmZmZ d dlmZmZmZmZmZmZ d dlmZmZm Z  d dl!m"Z" d d	l#m$Z$ d d
l%m&Z& d dl'm(Z( d dl)m*Z*m+Z+m,Z,m-Z- dZ.ee/eee/ee/ef f  f Z0ee/ef ee/ef dddZ1e0eee/ef  dddZ2ee eee/ef  dddZ3G dd deZ4dS )    N)AnyAsyncIteratorCallableDictIteratorListMappingOptionalSequenceTypeUnion)AsyncCallbackManagerForLLMRunCallbackManagerForLLMRun)LanguageModelInput)BaseChatModelagenerate_from_streamgenerate_from_stream)	AIMessageAIMessageChunkBaseMessageHumanMessageSystemMessageToolMessage)ChatGenerationChatGenerationChunk
ChatResult)Runnable)BaseTool)get_from_dict_or_envconvert_to_openai_tool)	BaseModel
ConfigDictFieldmodel_validatorz
reka-flash)itemreturnc                 C   s6   | d dkr2| d }t |tr2d|v r2|d | d< | S )zProcess a single content item.type	image_urlurl)
isinstancedict)r%   r(    r,   r/var/www/html/cobodadashboardai.evdpl.com/venv/lib/python3.9/site-packages/langchain_community/chat_models/reka.pyprocess_content_item.   s
    r.   )contentr&   c                 C   s   t | trd| dgS t | trvg }| D ]H}t |trH|d|d q(t |trb|t| q(td| q(|S tddS )z\Process content to handle both text and media inputs,
    returning a list of content items.textr'   r0   zInvalid content item format: zInvalid content formatN)r*   strlistappendr+   r.   
ValueError)r/   resultr%   r,   r,   r-   process_content8   s    



r7   )messagesr&   c                 C   s  g }d}| D ]}t |trL|du rBt |jtr8|j}qJtdntdqt |trt|j}|r|rt |d tr|d 	ddkrd|d v r| d|d d  |d d< n|
dd|d d}|d	|d
 qt |trtddi}|jr
t|j}||d< d|jv rh|jd }g }|D ]6}|d |d d t|d d d}	||	 q(||d< || qt |trg }
|
|jtd|jid |d|
d
 qtdt| q|S )z2Convert LangChain messages to Reka message format.Nz'SystemMessage content must be a string.z+Multiple system messages are not supported.r   r'   r0   
r1   user)roler/   r;   Z	assistantr/   
tool_callsidfunctionname	arguments)r=   r?   
parametersstatus)tool_call_idoutputZtool_outputzUnsupported message type: )r*   r   r/   r2   	TypeErrorr5   r   r7   r+   getinsertr4   r   additional_kwargsjsonloadsr   rC   dumpsr'   )r8   reka_messagesZsystem_messagemessageZprocessed_contentZreka_messager<   Zformatted_tool_callsZ	tool_callZformatted_tool_callZcontent_listr,   r,   r-   convert_to_reka_messagesK   sr    










rN   c                       sP  e Zd ZU dZdZeed< dZeed< ee	dZ
eed< eddZeed< dZee ed	< d
Zeed< dZee ed< dZeed< dZee ed< eedZeeef ed< eddZdZeeeeeee f gef  ed< e dde!eeef eeef dddZ"e#e$eef dddZ%e#edddZ&d0ee eee  ee' ee(e) dd d!Z*d1ee eee  ee+ ee,e) dd"d#Z-d2ee eee  ee' ee.dd$d%Z/d3ee eee  ee+ ee.dd&d'Z0eeeee f ed(d)d*Z1d+dd,e2eeeef e3e4 ee5f  eee ee6e7ef d- fd.d/Z8  Z9S )4ChatRekaz Reka chat large language models.Nclientasync_client)defaultmodel   
max_tokenstemperatureF	streamingdefault_request_timeout   max_retriesreka_api_key)default_factorymodel_kwargsZforbid)extratoken_counterbefore)mode)valuesr&   c                 C   sr   | d}td|idd}||d< z0ddlm}m} ||d|d< ||d|d< W n tyl   tdY n0 |S )	zBValidate that API key and Python package exist in the environment.r[   ZREKA_API_KEYr   )	AsyncRekaReka)Zapi_keyrP   rQ   zTCould not import Reka Python package. Please install it with `pip install reka-api`.)rF   r   Zreka.clientrc   rd   ImportError)clsrb   r[   rc   rd   r,   r,   r-   validate_environment   s$    



zChatReka.validate_environment)r&   c                 C   s0   | j | jd}| jdur"| j|d< i || jS )z0Get the default parameters for calling Reka API.)rS   rU   NrV   )rS   rU   rV   r]   )selfparamsr,   r,   r-   _default_params   s    

zChatReka._default_paramsc                 C   s   dS )zReturn type of chat model.z	reka-chatr,   )rh   r,   r,   r-   	_llm_type   s    zChatReka._llm_type)r8   stoprun_managerkwargsr&   c                 k   s~   t |}i | j|}|r"||d< | jjjf d|i|}|D ]:}|jd jj}	tt	|	dd}
|rr|j
|	|
d |
V  q>d S Nrl   r8   r   r/   rM   )chunk)rN   rj   rP   chatcreate_stream	responsesrr   r/   r   r   on_llm_new_tokenrh   r8   rl   rm   rn   rL   ri   streamrr   r/   Z
chat_chunkr,   r,   r-   _stream   s    zChatReka._streamc                 K  s   t |}i | j|}|r"||d< | jjjf d|i|}|2 zH3 d H W }|jd jj}	tt	|	dd}
|r|j
|	|
dI d H  |
V  q>6 d S ro   )rN   rj   rQ   rs   rt   ru   rr   r/   r   r   rv   rw   r,   r,   r-   _astream   s    zChatReka._astreamc                 K   s   | j r"t| j|f||d|S t|}i | j|}|rD||d< | jjjf d|i|}|jd j	j
r|jd j	j
}tdddd |D id	}	n$|jd j	j}
t|
d ur|
ndd
}	tt|	dgdS )Nrl   rm   rl   r8   r    r<   c                 S   s*   g | ]"}|j d |jt|jddqS r>   )r?   r@   )r=   r'   r>   r=   r?   rI   rK   rA   .0Ztcr,   r,   r-   
<listcomp>  s   	
z&ChatReka._generate.<locals>.<listcomp>r/   rH   rp   rq   Zgenerations)rW   r   ry   rN   rj   rP   rs   createru   rM   r<   r   r/   r   r   rh   r8   rl   rm   rn   rL   ri   responser<   rM   r/   r,   r,   r-   	_generate   s*    	zChatReka._generatec                    s   | j r(t| j|f||d|I d H S t|}i | j|}|rJ||d< | jjjf d|i|I d H }|jd j	j
r|jd j	j
}tdddd |D id	}	n$|jd j	j}
t|
d ur|
ndd
}	tt|	dgdS )Nr{   rl   r8   r   r|   r<   c                 S   s*   g | ]"}|j d |jt|jddqS r}   r~   r   r,   r,   r-   r   9  s   	
z'ChatReka._agenerate.<locals>.<listcomp>r   rp   rq   r   )rW   r   rz   rN   rj   rQ   rs   r   ru   rM   r<   r   r/   r   r   r   r,   r,   r-   
_agenerate"  s*    
	zChatReka._agenerate)inputr&   c                 C   s   | j dur|  |S zddl}W n ty:   tdY n0 |d}t|tr^t||S t|tr|j	}t|tst
dt| t||S t|trd}|D ]8}|j	}t|tst
dt| |t||7 }q|S tdt| dS )aN  Calculate number of tokens.

        Args:
            input: Either a string, a single BaseMessage, or a list of BaseMessages.

        Returns:
            int: Number of tokens in the input.

        Raises:
            ImportError: If tiktoken is not installed.
            ValueError: If message content is not a string.
        Nr   zXCould not import tiktoken python package. Please install it with `pip install tiktoken`.Zcl100k_basez&Message content must be a string, got zUnsupported input type: )r_   tiktokenre   Zget_encodingr*   r2   lenencoder   r/   r5   r'   r3   rE   )rh   r   r   encodingr/   totalmsgr,   r,   r-   get_num_tokensM  s:    








zChatReka.get_num_tokensauto)tool_choicestrict)toolsr   r   rn   r&   c                   sV    fdd|D }|dvr*t d| d||d< dd |D }t jf d|i|S )	a  Bind tool-like objects to this chat model.

        The `tool_choice` parameter controls how the model uses the tools you pass.
        There are three available options:

        - `"auto"`: Lets the model decide whether or not to invoke a tool. This is the
          recommended way to do function calling with our models.
        - `"none"`: Disables tool calling. In this case, even if you pass tools to
          the model, the model will not invoke any tools.
        - `"tool"`: Forces the model to invoke one or more of the tools it has
          been passed.

        Args:
            tools: A list of tool definitions to bind to this chat model.
                Supports any tool definition handled by
                :meth:`langchain_core.utils.function_calling.convert_to_openai_tool`.
            tool_choice: Controls how the model uses the tools you pass.
                Options are "auto", "none", or "tool". Defaults to "auto".
            strict:
            If True, model output is guaranteed to exactly match the JSON Schema
                provided in the tool definition.
                If False, input schema will not be validated
                and model output will not be validated.
                If None, ``strict`` argument will not
                be passed to the model.
            kwargs: Any additional parameters are passed directly to the model.

        Returns:
            Runnable: An executable chain or component.
        c                    s   g | ]}t | d qS )r   r   r   toolr   r,   r-   r     s   z'ChatReka.bind_tools.<locals>.<listcomp>)r   noner   zInvalid tool_choice 'zB' provided. Tool choice must be one of: 'auto', 'none', or 'tool'.r   c                 S   s   g | ]}|d  qS )r>   r,   r   r,   r,   r-   r         r   )r5   superbind)rh   r   r   r   rn   Zformatted_tools	__class__r   r-   
bind_tools}  s    &

zChatReka.bind_tools)NN)NN)NN)NN):__name__
__module____qualname____doc__rP   r   __annotations__rQ   r#   DEFAULT_REKA_MODELrS   r2   rU   intrV   r	   floatrW   boolrX   rZ   r[   r+   r]   r   r"   Zmodel_configr_   r   r   r   r   r$   classmethodrg   propertyr   rj   rk   r   r   r   ry   r   r   rz   r   r   r   r   r
   r   r!   r   r   r   r   __classcell__r,   r,   r   r-   rO      s   

$
  
  
  
.  
+4
rO   )5rI   typingr   r   r   r   r   r   r   r	   r
   r   r   Zlangchain_core.callbacksr   r   Zlangchain_core.language_modelsr   Z*langchain_core.language_models.chat_modelsr   r   r   Zlangchain_core.messagesr   r   r   r   r   r   Zlangchain_core.outputsr   r   r   Zlangchain_core.runnablesr   Zlangchain_core.toolsr   Zlangchain_core.utilsr   Z%langchain_core.utils.function_callingr    Zpydanticr!   r"   r#   r$   r   r2   ZContentTyper.   r7   rN   rO   r,   r,   r,   r-   <module>   s"   4   
 E