
    dh%                         S r SSKJrJrJrJrJrJrJrJ	r	J
r
Jr  SSKJrJr  SSKJr  SSKJr  SSKJrJrJrJrJr  SSKJrJrJrJr  SSKJr  SS	K J!r!  SS
K"J#r#  SSK$J%r%  Sr& " S S\5      r'g)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                     ^  \ rS rSr% Sr\\S'   \" \S9r	\\S'   Sr
\\S'   S\4U 4S	 jjr  SS
\\   S\\\      S\\   S\S\4
S jjr  SS
\\   S\\\      S\\   S\S\4
S jjr  S S
\\   S\S\\   S\4S jjrS\S\4S jr\S\S\4S j5       r\S\4S j5       r  SS
\\   S\\\      S\\   S\S\\    4
S jjr!SS.S\"\#\$\\4   \%\&\'4      S\\#\\\(S   \4      S\S\)\*\4   4U 4S jjjr+Sr,U =r-$ )!ChatMLX,   a  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U ]  " S0 UD6  U R                  R                  U l        g )N )super__init__r!   r%   )selfr&   	__class__s     [/var/www/html/shao/venv/lib/python3.13/site-packages/langchain_community/chat_models/mlx.pyr*   ChatMLX.__init__D   s$    "6"++    messagesstoprun_managerreturnc                     U R                  U5      nU R                  R                  " SU/X#S.UD6nU R                  U5      $ N)promptsr1   r2   r(   )_to_chat_promptr!   	_generate_to_chat_resultr+   r0   r1   r2   r&   	llm_input
llm_results          r-   r8   ChatMLX._generateH   sO     ((2	XX'' 
Kd
GM

 ##J//r/   c                    #    U R                  U5      nU R                  R                  " SU/X#S.UD6I S h  vN nU R                  U5      $  N7fr5   )r7   r!   
_agenerater9   r:   s          r-   r?   ChatMLX._agenerateU   s\      ((2	88.. 
Kd
GM
 

 ##J//
s   5AAAtokenizereturn_tensorsc                     U(       d  [        S5      e[        US   [        5      (       d  [        S5      eU Vs/ sH  o@R                  U5      PM     nnU R                  R                  UUSUS9$ s  snf )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!T)rA   add_generation_promptrB   )
ValueError
isinstancer   _to_chatml_formatr%   apply_chat_template)r+   r0   rA   rB   mmessages_dictss         r-   r7   ChatMLX._to_chat_promptb   s{     JKK(2,55CDD=EFX003XF~~11"&)	 2 
 	
 Gs   A1messagec                     [        U[        5      (       a  SnOG[        U[        5      (       a  SnO/[        U[        5      (       a  SnO[	        S[        U5       35      eX!R                  S.$ )z+Convert LangChain message to ChatML format.system	assistantuserzUnknown message type: )roler#   )rG   r   r   r   rF   typer#   )r+   rM   rR   s      r-   rH   ChatMLX._to_chatml_formatw   s^     g}--D++D..D5d7m_EFF99r/   r<   c                     / nU R                   S    H9  n[        [        UR                  S9UR                  S9nUR                  U5        M;     [        XR                  S9$ )Nr   r"   )rM   generation_info)generations
llm_output)rW   r   r   textrV   appendr   rX   )r<   chat_generationsgchat_generations       r-   r9   ChatMLX._to_chat_result   sc    ''*A,!!&&11CTCTO ##O4	 + (5J5J
 	
r/   c                     g)Nzmlx-chat-wrapperr(   )r+   s    r-   	_llm_typeChatMLX._llm_type   s    !r/   c           	   +   2  #    SS K Jn  SSKJn   SS K Jn  SSKJnJn  SSKJn  UR                  SU R                  R                  5      n	U	R                  SS5      n
U	R                  SS	5      nU	R                  S
S 5      nU	R                  SS 5      nU	R                  SS5      nU	R                  SS5      nU	R                  SS5      nU R                  USSS9nUR                  US   5      nU R                  R                  nU" U
=(       d    SXU5      nU" S X5      n[        U" UU R                  R                   UUS9[#        U5      5       H  u  u  nnnS n[%        U[&        5      (       d*  U R                  R)                  UR+                  5       5      nOU R                  R)                  U5      nU(       a+  [-        [/        US9S9nU(       a  UR1                  UUS9  Uv   UU:X  d  Uc  M  UU;   d  M    g    g ! [         a    [        S5      ef = f7f)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)rA   rB   )samplerlogits_processorsr"   )rM   )chunk)mlx.corecoremlx_lm.utilsrc   mlx_lm.sample_utilsrd   re   ImportErrorgetr!   pipeline_kwargsr7   arrayr%   eos_token_idzipmodelrangerG   intdecodeitemr   r   on_llm_new_token)r+   r0   r1   r2   r&   mxrc   rd   re   rf   rg   max_new_tokensrj   rk   rl   rm   rn   r;   prompt_tokensr|   rq   rr   tokenprobnrY   rs   s                              r-   _streamChatMLX._stream   s     	.		!P2 zz.$((2J2JK"&&vs3*..|SA.:.>.> $/
 2>1A1A%t2
 $''5#''5"."2"23G"K((DQU(V	1.~~22t{sE:LM2$
 !$"3	 .!!
MUD1 #'DeS))~~,,UZZ\:~~,,U3 +N44PQ00U0C $)9ddl3!
=  	? 	s(   HG> G	H1H9H>HH)tool_choicetoolsr   autononec                  > U Vs/ sH  n[        U5      PM     nnUb  U(       a  [        U5      S:w  a  [        S[        U5       S35      e[        U[        5      (       a  US;  a  SSU0S.nOo[        U[
        5      (       a  US   nOT[        U[        5      (       a1  US   S   S   US   S   :w  a  [        S	U S
US   S   S    S35      eO[        SU 35      eX#S'   [        TU ]   " SSU0UD6$ s  snf )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.
ro   zKWhen specifying `tool_choice`, you must provide exactly one tool. Received z tools.r   functionname)rS   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(   )	r   lenrF   rG   strbooldictr)   bind)r+   r   r   r&   toolformatted_toolsr,   s         r-   
bind_toolsChatMLX.bind_tools   sS   0 EJJED1$7EJ"{?#q( &&)/&:%;7D  +s++&66 *%+[$9#K K..-a0K..#A&z26:":.v67 %&{m 4--<Q-?
-KF-S,TTUW 7 !!!,/  %0=!w|</<V<<= Ks   C5)r%   )NN)FN).__name__
__module____qualname____firstlineno____doc__r   __annotations__r   DEFAULT_SYSTEM_PROMPTr$   r%   r   r*   r   r   r	   r   r   r   r8   r   r?   r   r7   r   rH   staticmethodr   r9   propertyr`   r   r   r   r
   r   r   r   r   r   r   r   r   r   __static_attributes____classcell__)r,   s   @r-   r   r   ,   s7   & 
$1:O$PNMPIs, , %):>	0{#0 tCy!0 67	0
 0 
0  %)?C	0{#0 tCy!0 ;<	0
 0 
0  (,	
{#
 
 !	

 

*: : : 
I 
* 
 
 "3 " " %):>	F{#F tCy!F 67	F
 F 
%	&FX RV	6=d38ndHhFGH6= eD#w~/F$LMN	6=
 6= 
$k1	2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      sZ       > D   . ) H =R i=m i=r/   