
    hh%                         d Z ddl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 ddlmZmZmZmZmZ ddl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Z& G d de          Z'dS )zMLX Chat Wrapper.    )
AnyCallableDictIteratorListLiteralOptionalSequenceTypeUnion)AsyncCallbackManagerForLLMRunCallbackManagerForLLMRun)LanguageModelInput)BaseChatModel)	AIMessageAIMessageChunkBaseMessageHumanMessageSystemMessage)ChatGenerationChatGenerationChunk
ChatResult	LLMResult)Runnable)BaseToolconvert_to_openai_tool)MLXPipelinez4You are a helpful, respectful, and honest assistant.c                   v    e Zd ZU dZeed<    ee          Zeed<   dZ	e
ed<   de
f fdZ	 	 dd	ee         d
eee                  dee         de
def
dZ	 	 dd	ee         d
eee                  dee         de
def
dZ	 	 dd	ee         dedee         defdZdedefdZededefd            Zedefd            Z	 	 dd	ee         d
eee                  dee         de
dee         f
dZ ddde!e"e#ee
f         e$e%e&f                  dee"eee'd         ef                  de
de(e)ef         f fdZ* xZ+S ) ChatMLXa  MLX chat models.

    Works with `MLXPipeline` LLM.

    To use, you should have the ``mlx-lm`` python package installed.

    Example:
        .. code-block:: python

            from langchain_community.chat_models import chatMLX
            from langchain_community.llms import MLXPipeline

            llm = MLXPipeline.from_model_id(
                model_id="mlx-community/quantized-gemma-2b-it",
            )
            chat = chatMLX(llm=llm)

    llmcontentsystem_messageN	tokenizerkwargsc                 \     t                      j        di | | j        j        | _        d S )N )super__init__r!   r%   )selfr&   	__class__s     `/var/www/FlaskApp/flask-venv/lib/python3.11/site-packages/langchain_community/chat_models/mlx.pyr*   zChatMLX.__init__D   s0    ""6"""+    messagesstoprun_managerreturnc                     |                      |          } | j        j        d|g||d|}|                     |          S N)promptsr0   r1   r(   )_to_chat_promptr!   	_generate_to_chat_resultr+   r/   r0   r1   r&   	llm_input
llm_results          r-   r7   zChatMLX._generateH   s^     ((22	'TX' 
Kd
 
GM
 

 ##J///r.   c                    K   |                      |          } | j        j        d|g||d| d {V }|                     |          S r4   )r6   r!   
_agenerater8   r9   s          r-   r=   zChatMLX._agenerateU   s       ((22	.48. 
Kd
 
GM
 
 
 
 
 
 
 

 ##J///r.   Ftokenizereturn_tensorsc                      |st          d          t          |d         t                    st          d           fd|D             } j                            ||d|          S )zHConvert a list of messages into a prompt format expected by wrapped LLM.z+At least one HumanMessage must be provided!z$Last message must be a HumanMessage!c                 :    g | ]}                     |          S r(   )_to_chatml_format).0mr+   s     r-   
<listcomp>z+ChatMLX._to_chat_prompt.<locals>.<listcomp>o   s'    FFF$0033FFFr.   T)r>   add_generation_promptr?   )
ValueError
isinstancer   r%   apply_chat_template)r+   r/   r>   r?   messages_dictss   `    r-   r6   zChatMLX._to_chat_promptb   s      	LJKKK(2,55 	ECDDDFFFFXFFF~11"&)	 2 
 
 	
r.   messagec                     t          |t                    rd}nOt          |t                    rd}n7t          |t                    rd}nt	          dt          |                     ||j        dS )z+Convert LangChain message to ChatML format.system	assistantuserzUnknown message type: )roler#   )rI   r   r   r   rH   typer#   )r+   rL   rQ   s      r-   rC   zChatMLX._to_chatml_formatw   s     g}-- 	GDD++ 	GDD.. 	GDDEd7mmEEFFF999r.   r;   c                     g }| j         d         D ]@}t          t          |j                  |j                  }|                    |           At          || j                  S )Nr   r"   )rL   generation_info)generations
llm_output)rU   r   r   textrT   appendr   rV   )r;   chat_generationsgchat_generations       r-   r8   zChatMLX._to_chat_result   s    '* 	5 	5A,!!&1111CT  O ##O4444(Z5J
 
 
 	
r.   c                     dS )Nzmlx-chat-wrapperr(   )r+   s    r-   	_llm_typezChatMLX._llm_type   s    !!r.   c              +     K   dd l m} ddlm} 	 dd l m} ddlm}m} ddlm} n# t          $ r t          d          w xY w|                    d| j	        j
                  }	|	                    dd          }
|	                    dd	          }|	                    d
d           }|	                    dd           }|	                    dd          }|	                    dd          }|	                    dd          }|                     |dd          }|                    |d                   }| j        j        } ||
pd|||          } |d ||          }t           ||| j	        j        ||          t#          |                    D ]\  \  }}}d }t%          |t&                    s-| j                            |                                          }n| j                            |          }|r;t-          t/          |                    }|r|                    ||           |V  ||k    s|||v r d S d S )Nr   )generate_step)make_logits_processorsmake_samplerzTCould not import mlx_lm python package. Please install it with `pip install mlx_lm`.model_kwargstempg        
max_tokensd   repetition_penaltyrepetition_context_sizetop_pg      ?min_pmin_tokens_to_keep   Tnp)r>   r?   )samplerlogits_processorsr"   )rL   )chunk)mlx.corecoremlx_lm.utilsr_   mlx_lm.sample_utilsr`   ra   ImportErrorgetr!   pipeline_kwargsr6   arrayr%   eos_token_idzipmodelrangerI   intdecodeitemr   r   on_llm_new_token)r+   r/   r0   r1   r&   mxr_   r`   ra   rb   rc   max_new_tokensrf   rg   rh   ri   rj   r:   prompt_tokensrx   rm   rn   tokenprobnrW   ro   s                              r-   _streamzChatMLX._stream   s      	......		!!!!!!PPPPPPPP2222222 	 	 	?  	
 zz.$(2JKK"&&vs33*..|SAA.:.>.> $/
 /
 2>1A1A%t2
 2
 $''55#''55"."2"23G"K"K((DQU(VV	1..~2,t{sE5:LMM22$&=
 
 !$M"3	   .!!!
 !
 	 	MUD1 #'DeS)) 4~,,UZZ\\::~,,U33  +N44P4P4PQQQ D00U0CCC $$)9ddll3	 	s   % ?)tool_choicetoolsr   autononec                0   d |D             }||rt          |          dk    r t          dt          |           d          t          |t                    r|dvrdd|id	}nt          |t                    r	|d
         }ntt          |t
                    rM|d
         d         d         |d         d         k    r(t          d| d|d
         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.
                Supports any tool definition handled by
                :meth:`langchain_core.utils.function_calling.convert_to_openai_tool`.
            tool_choice: Which tool to require the model to call.
                Must be the name of the single provided function or
                "auto" to automatically determine which function to call
                (if any), 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                 ,    g | ]}t          |          S r(   r   )rD   tools     r-   rF   z&ChatMLX.bind_tools.<locals>.<listcomp>   s!    JJJD1$77JJJr.   Nrk   zKWhen specifying `tool_choice`, you must provide exactly one tool. Received z tools.r   functionname)rR   r   r   zTool choice z/ was specified, but the only provided tool was .zEUnrecognized tool_choice type. Expected str, bool or dict. Received: r   r   r(   )lenrH   rI   strbooldictr)   bind)r+   r   r   r&   formatted_toolsr,   s        r-   
bind_toolszChatMLX.bind_tools   s   0 KJEJJJ"{"?##q(( D&)/&:&:D D D   +s++ &666 *%+[$9# #K K.. -a0K.. #A&z26:":.v67 7 %W{ W W-<Q-?
-KF-SW W W  7 !/!,/ /   %0F=!uww|<</<V<<<r.   )NN)FN),__name__
__module____qualname____doc__r   __annotations__r   DEFAULT_SYSTEM_PROMPTr$   r%   r   r*   r   r   r	   r   r   r   r7   r   r=   r   r6   r   rC   staticmethodr   r8   propertyr]   r   r   r   r
   r   r   r   r   r   r   r   r   r   __classcell__)r,   s   @r-   r    r    ,   s&         & 
$1M:O$P$P$PNMPPPIs, , , , , , , %):>	0 0{#0 tCy!0 67	0
 0 
0 0 0 0  %)?C	0 0{#0 tCy!0 ;<	0
 0 
0 0 0 0  (,	
 
{#
 
 !	

 

 
 
 
*: : : : : : 
I 
* 
 
 
 \
 "3 " " " X" %):>	F F{#F tCy!F 67	F
 F 
%	&F F F FX RV	6= 6= 6=d38ndHhFGH6= eD#w~/F$LMN	6=
 6= 
$k1	26= 6= 6= 6= 6= 6= 6= 6= 6= 6=r.   r    N)(r   typingr   r   r   r   r   r   r	   r
   r   r    langchain_core.callbacks.managerr   r   langchain_core.language_modelsr   *langchain_core.language_models.chat_modelsr   langchain_core.messagesr   r   r   r   r   langchain_core.outputsr   r   r   r   langchain_core.runnablesr   langchain_core.toolsr   %langchain_core.utils.function_callingr   %langchain_community.llms.mlx_pipeliner   r   r    r(   r.   r-   <module>r      s                                   > = = = = = D D D D D D                         . - - - - - ) ) ) ) ) ) H H H H H H = = = = = =R i= i= i= i= i=m i= i= i= i= i=r.   