
    }
i2                    n   d dl mZ d dlZd dlZd dlmZmZ d dlmZ d dl	m
Z
mZmZmZ d dl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mZmZ d d	lmZ d d
lm Z  dZ!e"e         ez  Z#dZ$d*dZ%e%ddd+d            Z& edd           G d de                      Z' G d de          Z(d,d"Z)dd#d-d)Z*dS ).    )annotationsN)CallableSequence)partial)	AnnotatedAnyLiteralcast)
AnyMessageBaseMessageBaseMessageChunkMessageLikeRepresentationRemoveMessageconvert_to_messagesmessage_chunk_to_message)	TypedDict
deprecated)CONFCONFIG_KEY_SENDNS_SEP)
StateGraph)LangGraphDeprecatedSinceV10)add_messagesMessagesStateMessageGraphREMOVE_ALL_MESSAGES__remove_all__funcr   return(Callable[[Messages, Messages], Messages]c                     	 d	d
 fd} j         |_         t          t          t          t          gt          f         |          S )NleftMessages | Nonerightkwargsr   r   3Messages | Callable[[Messages, Messages], Messages]c                t    | |
 | |fi |S | |d| rdnd d}t          |          t          fi |S )NzMMust specify non-null arguments for both 'left' and 'right'. Only received: 'r"   r$   z'.)
ValueErrorr   )r"   r$   r%   msgr   s       C:\Users\Dell Inspiron 16\Desktop\tws\AgrotaPowerBi\back-agrota-powerbi\mcp-client-agrota\venv\Lib\site-packages\langgraph/graph/message.py_add_messagesz,_add_messages_wrapper.<locals>._add_messages*   s~      14e..v...!2>(,9ff'> > >  S//!4**6***    )NN)r"   r#   r$   r#   r%   r   r   r&   )__doc__r
   r   Messages)r   r+   s   ` r*   _add_messages_wrapperr/   )   sT    ?C+ + + + + + + !LM(H-x78-HHHr,   )formatr"   r.   r$   r0   "Literal['langchain-openai'] | Nonec                 
 d}t          | t                    s| g} t          |t                    s|g}d t          |           D             } d t          |          D             }| D ].}|j        %t	          t          j                              |_        /t          |          D ]X\  }}|j        %t	          t          j                              |_        t          |t                    r|j        t          k    r|}Y|||dz   d         S | 
                                }d t          |          D             }t                      
|D ]}|                    |j                  x}Pt          |t                    r
                    |j                   N
                    |j                   |||<   nt          |t                    rt          d|j         d          t!          |          ||j        <   |                    |           Ȉ
fd|D             }|d	k    rt%          |          }n|rd
|d}	t          |	          	 |S )a  Merges two lists of messages, updating existing messages by ID.

    By default, this ensures the state is "append-only", unless the
    new message has the same ID as an existing message.

    Args:
        left: The base list of `Messages`.
        right: The list of `Messages` (or single `Message`) to merge
            into the base list.
        format: The format to return messages in. If `None` then `Messages` will be
            returned as is. If `langchain-openai` then `Messages` will be returned as
            `BaseMessage` objects with their contents formatted to match OpenAI message
            format, meaning contents can be string, `'text'` blocks, or `'image_url'` blocks
            and tool responses are returned as their own `ToolMessage` objects.

            !!! important "Requirement"

                Must have `langchain-core>=0.3.11` installed to use this feature.

    Returns:
        A new list of messages with the messages from `right` merged into `left`.
        If a message in `right` has the same ID as a message in `left`, the
            message from `right` will replace the message from `left`.

    Example: Basic usage
        ```python
        from langchain_core.messages import AIMessage, HumanMessage

        msgs1 = [HumanMessage(content="Hello", id="1")]
        msgs2 = [AIMessage(content="Hi there!", id="2")]
        add_messages(msgs1, msgs2)
        # [HumanMessage(content='Hello', id='1'), AIMessage(content='Hi there!', id='2')]
        ```

    Example: Overwrite existing message
        ```python
        msgs1 = [HumanMessage(content="Hello", id="1")]
        msgs2 = [HumanMessage(content="Hello again", id="1")]
        add_messages(msgs1, msgs2)
        # [HumanMessage(content='Hello again', id='1')]
        ```

    Example: Use in a StateGraph
        ```python
        from typing import Annotated
        from typing_extensions import TypedDict
        from langgraph.graph import StateGraph


        class State(TypedDict):
            messages: Annotated[list, add_messages]


        builder = StateGraph(State)
        builder.add_node("chatbot", lambda state: {"messages": [("assistant", "Hello")]})
        builder.set_entry_point("chatbot")
        builder.set_finish_point("chatbot")
        graph = builder.compile()
        graph.invoke({})
        # {'messages': [AIMessage(content='Hello', id=...)]}
        ```

    Example: Use OpenAI message format
        ```python
        from typing import Annotated
        from typing_extensions import TypedDict
        from langgraph.graph import StateGraph, add_messages


        class State(TypedDict):
            messages: Annotated[list, add_messages(format="langchain-openai")]


        def chatbot_node(state: State) -> list:
            return {
                "messages": [
                    {
                        "role": "user",
                        "content": [
                            {
                                "type": "text",
                                "text": "Here's an image:",
                                "cache_control": {"type": "ephemeral"},
                            },
                            {
                                "type": "image",
                                "source": {
                                    "type": "base64",
                                    "media_type": "image/jpeg",
                                    "data": "1234",
                                },
                            },
                        ],
                    },
                ]
            }


        builder = StateGraph(State)
        builder.add_node("chatbot", chatbot_node)
        builder.set_entry_point("chatbot")
        builder.set_finish_point("chatbot")
        graph = builder.compile()
        graph.invoke({"messages": []})
        # {
        #     'messages': [
        #         HumanMessage(
        #             content=[
        #                 {"type": "text", "text": "Here's an image:"},
        #                 {
        #                     "type": "image_url",
        #                     "image_url": {"url": "data:image/jpeg;base64,1234"},
        #                 },
        #             ],
        #         ),
        #     ]
        # }
        ```

    Nc                R    g | ]$}t          t          t          |                    %S  r   r
   r   .0ms     r*   
<listcomp>z add_messages.<locals>.<listcomp>   s;        	!&6!:!:;;  r,   c                R    g | ]$}t          t          t          |                    %S r4   r5   r6   s     r*   r9   z add_messages.<locals>.<listcomp>   s;        	!&6!:!:;;  r,      c                $    i | ]\  }}|j         |S r4   id)r7   ir8   s      r*   
<dictcomp>z add_messages.<locals>.<dictcomp>   s     :::1AD!:::r,   z?Attempting to delete a message with an ID that doesn't exist ('z')c                &    g | ]}|j         v|S r4   r=   )r7   r8   ids_to_removes     r*   r9   z add_messages.<locals>.<listcomp>   s%    ===A14}#<#<a#<#<#<r,   zlangchain-openaizUnrecognized format=z+. Expected one of 'langchain-openai', None.)
isinstancelistr   r>   struuiduuid4	enumerater   r   copysetgetadddiscardr(   lenappend_format_messages)r"   r$   r0   remove_all_idxr8   idxmergedmerged_by_idexisting_idxr)   rB   s             @r*   r   r   <   s   ~ NdD!! veT""  $T**  D $U++  E
  % %4<tz||$$ADE"" ! !Q4<tz||$$ADa'' 	!AD4G,G,G N!^a'))** YY[[F::	&(9(9:::LEEM  (,,QT222L?!]++ )!!!$''''%%ad+++'(|$$!]++  ^VWVZ^^^   "%VLMM!=======F###!&))	 RfRRRooMr,   z{MessageGraph is deprecated in langgraph 1.0.0, to be removed in 2.0.0. Please use StateGraph with a `messages` key instead.)categoryc                  $     e Zd ZdZd fdZ xZS )r   a  A StateGraph where every node receives a list of messages as input and returns one or more messages as output.

    MessageGraph is a subclass of StateGraph whose entire state is a single, append-only* list of messages.
    Each node in a MessageGraph takes a list of messages as input and returns zero or more
    messages as output. The `add_messages` function is used to merge the output messages from each node
    into the existing list of messages in the graph's state.

    Examples:
        ```pycon
        >>> from langgraph.graph.message import MessageGraph
        ...
        >>> builder = MessageGraph()
        >>> builder.add_node("chatbot", lambda state: [("assistant", "Hello!")])
        >>> builder.set_entry_point("chatbot")
        >>> builder.set_finish_point("chatbot")
        >>> builder.compile().invoke([("user", "Hi there.")])
        [HumanMessage(content="Hi there.", id='...'), AIMessage(content="Hello!", id='...')]
        ```

        ```pycon
        >>> from langchain_core.messages import AIMessage, HumanMessage, ToolMessage
        >>> from langgraph.graph.message import MessageGraph
        ...
        >>> builder = MessageGraph()
        >>> builder.add_node(
        ...     "chatbot",
        ...     lambda state: [
        ...         AIMessage(
        ...             content="Hello!",
        ...             tool_calls=[{"name": "search", "id": "123", "args": {"query": "X"}}],
        ...         )
        ...     ],
        ... )
        >>> builder.add_node(
        ...     "search", lambda state: [ToolMessage(content="Searching...", tool_call_id="123")]
        ... )
        >>> builder.set_entry_point("chatbot")
        >>> builder.add_edge("chatbot", "search")
        >>> builder.set_finish_point("search")
        >>> builder.compile().invoke([HumanMessage(content="Hi there. Can you search for X?")])
        {'messages': [HumanMessage(content="Hi there. Can you search for X?", id='b8b7d8f4-7f4d-4f4d-9c1d-f8b8d8f4d9c1'),
                     AIMessage(content="Hello!", id='f4d9c1d8-8d8f-4d9c-b8b7-d8f4f4d9c1d8'),
                     ToolMessage(content="Searching...", id='d8f4f4d9-c1d8-4f4d-b8b7-d8f4f4d9c1d8', tool_call_id="123")]}
        ```
    r   Nonec                    t          j        dt          d           t                                          t
          t          t                   t          f                    d S )Nz}MessageGraph is deprecated in LangGraph v1.0.0, to be removed in v2.0.0. Please use StateGraph with a `messages` key instead.   )rV   
stacklevel)	warningswarnr   super__init__r   rD   r   r   )self	__class__s    r*   r_   zMessageGraph.__init__*  sW     L0	
 	
 	
 	

 	4
#3\#ABCCCCCr,   )r   rX   )__name__
__module____qualname__r-   r_   __classcell__)ra   s   @r*   r   r      sR        
, ,\D D D D D D D D D Dr,   r   c                      e Zd ZU ded<   dS )r   z)Annotated[list[AnyMessage], add_messages]messagesN)rb   rc   rd   __annotations__r4   r,   r*   r   r   3  s         777777r,   r   rg   Sequence[BaseMessage]list[BaseMessage]c                    	 ddl m} t           ||                     S # t          $ r( d}t	          j        |           t          |           cY S w xY w)Nr   )convert_to_openai_messageszMust have langchain-core>=0.3.11 installed to use automatic message formatting (format='langchain-openai'). Please update your langchain-core version or remove the 'format' flag. Returning un-formatted messages.)langchain_core.messagesrl   r   ImportErrorr\   r]   rD   )rg   rl   r)   s      r*   rP   rP   7  s    IFFFFFF ##=#=h#G#GHHH     	 	cH~~s     /AA)	state_keymessage,MessageLikeRepresentation | BaseMessageChunkro   
str | Noner   c                 
 ddl m
m} ddlm} ddlm  |            }t          d t          | g          D                       } | j	        t          d          t          |d         |          r|d         }|j        }nDt          |d         t                    r)t          
fd	|d         D                       r|d         }t          fd
|D             d          x}rb|d         }t          t!          t"          |d                                       t&                              |f}	|                    |	| d           |r$ |t*                   t,                   || fg           | S )zWrite a message manually to the `messages` / `messages-tuple` stream mode.

    Will automatically write to the channel specified in the `state_key` unless `state_key` is `None`.
    r   )BaseCallbackHandlerBaseCallbackManager)
get_config)StreamMessagesHandlerc              3     K   | ]}|V  d S Nr4   )r7   xs     r*   	<genexpr>zpush_message.<locals>.<genexpr>Z  s"      ==1======r,   NzMessage ID is required	callbacksc              3  8   K   | ]}t          |          V  d S ry   rC   )r7   rz   rt   s     r*   r{   zpush_message.<locals>.<genexpr>b  s?       7 7/0
1)**7 7 7 7 7 7r,   c              3  <   K   | ]}t          |          |V  d S ry   r~   )r7   rz   rw   s     r*   r{   zpush_message.<locals>.<genexpr>h  s3      EEq
1.C D DEEEEEEEr,   metadatalanggraph_checkpoint_nsF)dedupe)langchain_core.callbacks.basert   ru   langgraph.configrv   langgraph.pregel._messagesrw   nextr   r>   r(   rC   handlersrD   alltupler
   rE   splitr   _emitr   r   )rp   ro   ru   rv   configmanagerr   stream_handlerr   message_metart   rw   s             @@r*   push_messager   G  s          
 ,+++++@@@@@@Z\\F==17)<<=====Gz1222&%':;; '%#	F;'	.	. '3 7 7 7 74:;4G7 7 7 4 4 ' +&EEEEHEEEt  ~ B *%$sH%>?@@FFvNNOO
 	\75AAA >%t_%	7';&<===Nr,   )r   r   r   r    )r"   r.   r$   r.   r0   r1   r   r.   )rg   ri   r   rj   )rp   rq   ro   rr   r   r   )+
__future__r   rF   r\   collections.abcr   r   	functoolsr   typingr   r   r	   r
   rm   r   r   r   r   r   r   r   typing_extensionsr   r   langgraph._internal._constantsr   r   r   langgraph.graph.stater   langgraph.warningsr   __all__rD   r.   r   r/   r   r   r   rP   r   r4   r,   r*   <module>r      s   " " " " " "   . . . . . . . .                                   4 3 3 3 3 3 3 3 H H H H H H H H H H , , , , , , : : : : : : )*-FF& I I I I& 
 26	w w w w w wt  B  5D 5D 5D 5D 5D: 5D 5D	 5Dp8 8 8 8 8I 8 8 8I I I I& '- - - - - - - -r,   