o
    ZhD                     @   sj  d dl Z 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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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)m*Z*m+Z+ d d
l,m-Z-m.Z.m/Z/ d dl0m1Z1m2Z2 d dl3m4Z4 d dl5m6Z6 d dl7m8Z8m9Z9m:Z: e;e<Z=G dd deZ>de$de?fddZ@de!de?fddZAdS )    N)AnyCallableDictIteratorListLiteralMappingOptionalSequenceTypeUnioncast)urlparse)CallbackManagerForLLMRun)BaseChatModel)LanguageModelInput)	AIMessageAIMessageChunkBaseMessageBaseMessageChunkChatMessageChatMessageChunkFunctionMessageHumanMessageHumanMessageChunkInvalidToolCallSystemMessageSystemMessageChunkToolCallToolMessageToolMessageChunk)tool_call_chunk)make_invalid_tool_callparse_tool_call)ChatGenerationChatGenerationChunk
ChatResult)RunnableRunnableConfig)BaseToolconvert_to_openai_tool)	BaseModelFieldPrivateAttrc                       s  e Zd ZU dZeed< 	 eed< 	 dZeed< 	 dZe	ed< 	 dZ
eee  ed	< 	 dZee	 ed
< 	 eedZeed< 	 e Zeed< def fddZedefddZd?ddZedeeef fddZ	d@dee d	eee  dedeeef fddZ		dAdee d	eee  dee dedef
ddZ	d@ddded ee  d	eee  dede!e" f
 fd!d"Z#		dAdee d	eee  dee dede!e$ f
d#d$Z%edeeef fd%d&Z&	d@d	eee  dedeeef f fd'd(Z'edefd)d*Z(e)d+e*eef defd,d-Z+e)d+e*eef d.ede"fd/d0Z,e)d?d1d2Z-e)d3edefd4d5Z.e)d6e*eef defd7d8Z/dd9d:e0e1eeef e2e3 e4e5f  d;ee1eee6d< e7f  dede8eef f fd=d>Z9  Z:S )B
ChatMlflowa  `MLflow` chat models API.

    To use, you should have the `mlflow[genai]` python package installed.
    For more information, see https://mlflow.org/docs/latest/llms/deployments.

    Example:
        .. code-block:: python

            from langchain_community.chat_models import ChatMlflow

            chat = ChatMlflow(
                target_uri="http://localhost:5000",
                endpoint="chat",
                temperature=0.1,
            )
    endpoint
target_urig        temperature   nNstop
max_tokens)default_factoryextra_params_clientkwargsc              
      sf   t  jdi | |   zddlm} || j| _W d S  ty2 } z
td| j d|d }~ww )Nr   )get_deploy_clientz;Failed to create the client. Please run `pip install mlflowz#` to install required dependencies. )	super__init___validate_uriZmlflow.deploymentsr;   r1   r9   ImportError_mlflow_extras)selfr:   r;   e	__class__r<   ]/var/www/html/lang_env/lib/python3.10/site-packages/langchain_community/chat_models/mlflow.pyr>   [   s   zChatMlflow.__init__returnc                 C      dS )Nz[genai]r<   rB   r<   r<   rF   rA   i   s   zChatMlflow._mlflow_extrasc                 C   sB   | j dkrd S g d}t| j j|vrtd| j  d| dd S )N
databricks)httphttpsrJ   zInvalid target URI: z. The scheme must be one of .)r1   r   scheme
ValueError)rB   allowedr<   r<   rF   r?   m   s   

zChatMlflow._validate_uric                 C   s&   | j | j| j| j| j| j| jd}|S )Nr1   r0   r2   r4   r5   r6   r8   rQ   )rB   paramsr<   r<   rF   _default_paramsw   s   	zChatMlflow._default_paramsmessagesc                 K   sV   dd |D }|| j | jd| j|}| jp| }r||d< | jd ur)| j|d< |S )Nc                 S   s   g | ]}t |qS r<   )r/   _convert_message_to_dict).0messager<   r<   rF   
<listcomp>   s    
z.ChatMlflow._prepare_inputs.<locals>.<listcomp>)rT   r2   r4   r5   r6   )r2   r4   r8   r5   r6   )rB   rT   r5   r:   Zmessage_dictsdatar<   r<   rF   _prepare_inputs   s    

zChatMlflow._prepare_inputsrun_managerc                 K   s0   | j ||fi |}| jj| j|d}t|S )Nr0   Zinputs)rZ   r9   Zpredictr0   r/   _create_chat_result)rB   rT   r5   r[   r:   rY   respr<   r<   rF   	_generate   s   
zChatMlflow._generate)r5   inputconfigc                +   sV    t | jdstt| j|f||d|V  d S t j||fd|i|E d H  d S )Npredict_stream)ra   r5   r5   )hasattrr9   r   r   Zinvoker=   stream)rB   r`   ra   r5   r:   rD   r<   rF   rd      s   

$zChatMlflow.streamc                 k   s    | j ||fi |}| jj| j|d}d }|D ]N}|d rf|d d }	|	d }
|d u r1|
d}t|
|}i }|	d }rD||d< |	d }rO||d< t||pTd d}|rb|j|j	||d	 |V  qqd S )
Nr\   choicesr   deltarolefinish_reasonlogprobsrW   generation_info)chunkri   )
rZ   r9   rb   r0   getr/   _convert_delta_to_message_chunkr%   Zon_llm_new_tokentext)rB   rT   r5   r[   r:   rY   Z
chunk_iterZfirst_chunk_rolerl   choiceZchunk_deltaZchunk_messagerk   rh   ri   r<   r<   rF   _stream   sB   
zChatMlflow._streamc                 C   s   | j S N)rS   rI   r<   r<   rF   _identifying_params   s   zChatMlflow._identifying_paramsc                    s    i | j t jdd|i|S )z>Get the parameters used to invoke the model FOR THE CALLBACKS.r5   Nr<   )rS   r=   _get_invocation_params)rB   r5   r:   rD   r<   rF   rt      s
   z!ChatMlflow._get_invocation_paramsc                 C   rH   )zReturn type of chat model.zmlflow-chatr<   rI   r<   r<   rF   	_llm_type   s   zChatMlflow._llm_type_dictc           	      C   s   | d }t t| d}|dkrt|dS |dkrf|pd}i }g }g }| d }rZ||d< |D ])}z|t|dd	 W q0 tyY } z|t|t| W Y d }~q0d }~ww t||| d
||dS |dkrot	|dS t
||dS )Nrg   contentuserrw   	assistant 
tool_callsT)Z	return_idid)rw   additional_kwargsr}   r|   invalid_tool_callssystemrw   rg   )r   strrm   r   appendr#   	Exceptionr"   r   r   r   )	rv   rg   rw   r~   r|   r   raw_tool_callsZraw_tool_callrC   r<   r<   rF   _convert_dict_to_message   s@   


z#ChatMlflow._convert_dict_to_messagedefault_rolec                 C   s   |  d|}|  dpd}|dkrt|dS |dkrGi }g }|  d }r<||d< z	dd	 |D }W n	 ty;   Y nw t|||  d
|dS |dkrPt|dS |dkr`t|| d |  d
dS t||dS )Nrg   rw   r{   rx   ry   rz   r|   c                 S   s:   g | ]}t |d  d|d  d|d|d dqS )functionname	argumentsr}   index)r   argsr}   r   )r!   rm   )rV   Zrtcr<   r<   rF   rX   .  s    z>ChatMlflow._convert_delta_to_message_chunk.<locals>.<listcomp>r}   )rw   r~   r}   tool_call_chunksr   tooltool_call_id)rw   r   r}   r   )rm   r   KeyErrorr   r   r    r   )rv   r   rg   rw   r~   r   r   r<   r<   rF   rn      s:   

	
z*ChatMlflow._convert_delta_to_message_chunkc                   C   s   t d)N~Function messages are not supported by Databricks. Please create a feature request at https://github.com/mlflow/mlflow/issues.)rO   r<   r<   r<   rF   _raise_functions_not_supportedH  s   z)ChatMlflow._raise_functions_not_supportedrW   c                    sx  d| j i}| jp| jd }d ur||d< t| tr!| j|d< nt| tr+d|d< nt| tryd|d< | j	s:| j
rMdd | j	D dd | j
D  |d	< nd	| jv rk| jd	 |d	< h d
fdd|d	 D |d	< n	 d	|v rx|d pud |d< n8t| trd|d< n.t| trd|d< | j|d< h d  fdd| D }nt| trtdtd|  d| jv rt  |S )Nrw   r   rg   rx   rz   c                 S      g | ]}t |qS r<   )!_lc_tool_call_to_openai_tool_callrV   Ztcr<   r<   rF   rX   [  s    z7ChatMlflow._convert_message_to_dict.<locals>.<listcomp>c                 S   r   r<   ))_lc_invalid_tool_call_to_openai_tool_callr   r<   r<   rF   rX   ]  s    r|   >   typer   r}   c                    s"   g | ]} fd d|  D qS )c                       i | ]\}}| v r||qS r<   r<   rV   kvtool_call_supported_propsr<   rF   
<dictcomp>e  s
    zBChatMlflow._convert_message_to_dict.<locals>.<listcomp>.<dictcomp>)items)rV   	tool_callr   r<   rF   rX   d  s    
r   r   r   >   r   rg   rw   c                    r   r<   r<   r   )supported_propsr<   rF   r   w  s    z7ChatMlflow._convert_message_to_dict.<locals>.<dictcomp>r   zGot unknown message type: Zfunction_call)rw   r   r~   rm   
isinstancer   rg   r   r   r|   r   r   r   r   r   r   rO   r/   r   )rW   Zmessage_dictr   r<   )r   r   rF   rU   O  sX   







	






z#ChatMlflow._convert_message_to_dictresponsec                 C   sZ   g }| d D ]}t |d }|di }t||d}|| q| di }t||dS )Nre   rW   usagerj   )generationsZ
llm_output)r/   r   rm   r$   r   r&   )r   r   rp   rW   r   genr<   r<   rF   r]     s   zChatMlflow._create_chat_resulttool_choicetoolsr   )autononerequiredanyc                   s   dd |D } rHt  tr dvrdd id n*t  tr=dd |D }t fdd	|D s<td
  d| dntd   |d< t jdd|i|S )a  Bind tool-like objects to this chat model.

        Assumes model is compatible with OpenAI tool-calling API.

        Args:
            tools: A list of tool definitions to bind to this chat model.
                Can be  a dictionary, pydantic model, callable, or BaseTool. Pydantic
                models, callables, and BaseTools will be automatically converted to
                their schema dictionary representation.
            tool_choice: Which tool to require the model to call.
                Options are:
                name of the tool (str): calls corresponding tool;
                "auto": automatically selects a tool (including no tool);
                "none": model does not generate any tool calls and instead must
                    generate a standard assistant message;
                "required": the model picks the most relevant tool in tools and
                    must generate a tool call;

                or a dict of the form:
                {"type": "function", "function": {"name": <<tool_name>>}}.
            **kwargs: Any additional parameters to pass to the
                :class:`~langchain.runnable.Runnable` constructor.
        c                 S   r   r<   r*   )rV   r   r<   r<   rF   rX     s    z)ChatMlflow.bind_tools.<locals>.<listcomp>)r   r   r   r   r   )r   r   c                 S   s   g | ]}|d  d qS )r   r   r<   )rV   Zformatted_toolr<   r<   rF   rX     s    
c                 3   s     | ]}| d  d kV  qdS )r   r   Nr<   )rV   Z	tool_namer   r<   rF   	<genexpr>  s
    
z(ChatMlflow.bind_tools.<locals>.<genexpr>zTool choice z1 was specified, but the only provided tools were rM   zEUnrecognized tool_choice type. Expected str, bool or dict. Received: r   r   Nr<   )r   r   dictr   rO   r=   bind)rB   r   r   r:   Zformatted_toolsZ
tool_namesrD   r   rF   
bind_tools  s8    

	zChatMlflow.bind_tools)rG   Nrr   )NN);__name__
__module____qualname____doc__r   __annotations__r2   floatr4   intr5   r	   r   r6   r-   r   r8   r.   r9   r   r>   propertyrA   r?   r   rS   r   rZ   r   r&   r_   r   r(   r   r   rd   r%   rq   rs   rt   ru   staticmethodr   r   rn   r   rU   r]   r
   r   r   r,   r   r)   r   boolr'   r   __classcell__r<   r<   rD   rF   r/   9   s   
 









/

	!
'6
r/   r   rG   c                 C   s$   d| d | d t | d ddS Nr   r}   r   r   )r   r   )r   r}   r   )jsondumps)r   r<   r<   rF   r     s   r   invalid_tool_callc                 C   s   d| d | d | d ddS r   r<   )r   r<   r<   rF   r     s   r   )Br   loggingtypingr   r   r   r   r   r   r   r	   r
   r   r   r   urllib.parser   Zlangchain_core.callbacksr   Zlangchain_core.language_modelsr   Z#langchain_core.language_models.baser   Zlangchain_core.messagesr   r   r   r   r   r   r   r   r   r   r   r   r   r   r    Zlangchain_core.messages.toolr!   Z*langchain_core.output_parsers.openai_toolsr"   r#   Zlangchain_core.outputsr$   r%   r&   Zlangchain_core.runnablesr'   r(   Zlangchain_core.toolsr)   Z%langchain_core.utils.function_callingr+   Zpydanticr,   r-   r.   	getLoggerr   loggerr/   r   r   r   r<   r<   r<   rF   <module>   s4    8D
   