
    %Gg                      U d Z ddlmZ ddlZddlZ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 ddlZddlZddlm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#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3 ddl4m5Z5m6Z6m7Z7  ejp                  e9      Z:dZ;d3d4d	Z<	 	 	 	 	 	 d5d
Z=d6dZ>dddd	 	 	 	 	 	 	 d7dZ? G d d      Z@ G d d      ZAd8dZBd9dZC G d d      ZD G d d      ZE G d d      ZF G d d      ZG G d d      ZHdddd	 	 	 	 	 	 	 d:dZI G d  d      ZJ G d! d"      ZKd8d#ZLd9d$ZM G d% d&      ZN G d' d(      ZO G d) d*      ZP G d+ d,      ZQ G d- d.      ZRd;d/ZSg ZTd0eUd1<   d<d2ZVy)=a>  The LangGraph client implementations connect to the LangGraph API.

This module provides both asynchronous (LangGraphClient) and synchronous (SyncLanggraphClient)
clients to interacting with the LangGraph API's core resources such as
Assistants, Threads, Runs, and Cron jobs, as well as its persistent
document Store.
    )annotationsN)
AnyAsyncIteratorDictIteratorListLiteralOptionalSequenceUnionoverload)QueryParamTypes)All	AssistantAssistantVersionCancelAction
CheckpointCommandConfigCronDisconnectModeGraphSchemaIfNotExistsItemJsonListNamespaceResponseMultitaskStrategyOnCompletionBehaviorOnConflictBehaviorRun	RunCreate	RunStatusSearchItemsResponse
StreamMode
StreamPart	SubgraphsThreadThreadStateThreadStatusThreadUpdateStateResponse)
SSEDecoderaiter_lines_rawiter_lines_raw)	x-api-keyc                    | r| S dD ]L  }t        j                  | d      x}s|j                         j                  d      j                  d      c S  y)zGet the API key from the environment.
    Precedence:
        1. explicit argument
        2. LANGGRAPH_API_KEY
        3. LANGSMITH_API_KEY
        4. LANGCHAIN_API_KEY
    )	LANGGRAPH	LANGSMITH	LANGCHAIN_API_KEY"'N)osgetenvstrip)api_keyprefixenvs      q/home/kushmeetdev/apache_webroot/langgraph_flaskproject/venv/lib/python3.12/site-packages/langgraph_sdk/client.py_get_api_keyr=   G   s]     9 5))vhh/003099;$$S)//445     c                    |xs i }t         D ]  }||v st        d| d       ddt        j                   i|}t	        |       } | r| |d<   |S )z1Combine api_key and custom user-provided headers.zCannot set reserved header 'r5   z
User-Agentzlanggraph-sdk-py/r.   )RESERVED_HEADERS
ValueErrorlanggraph_sdk__version__r=   )r9   custom_headersheaderheaderss       r<   get_headersrG   W   s     $)rN" G^#;F81EFFG
 	)-*C*C)DE
G 7#G&Nr>   c                8   t        | d      r%t        | j                        r| j                         S t        | d      r%t        | j                        r| j                         S t	        | t
        t        f      rt        |       S t        dt        |        d      )N
model_dumpdictzObject of type z is not JSON serializable)
hasattrcallablerI   rJ   
isinstanceset	frozensetlist	TypeErrortype)objs    r<   orjson_defaultrT   k   sw    sL!hs~~&>~~	f	(388"4xxz	C#y)	*Cy/$s)4MNOOr>   )urlr9   rF   LangGraphClientc           
        d}| qt         j                  j                  d      dk(  r/t        j                  dd      }t
        j                  |       d} n 	 ddlm} d} t        j                  |d	      }|t        j                  d      }t        j                  | |t        j                  dddd      t        ||            }t        |      S # t        $ r d
} Y jw xY w)a5  Get a LangGraphClient instance.

    Args:
        url: The URL of the LangGraph API.
        api_key: The API key. If not provided, it will be read from the environment.
            Precedence:
                1. explicit argument
                2. LANGGRAPH_API_KEY
                3. LANGSMITH_API_KEY
                4. LANGCHAIN_API_KEY
        headers: Optional custom headers

    Returns:
        LangGraphClient: The top-level client for accessing AssistantsClient,
        ThreadsClient, RunsClient, and CronClient.

    Example:

        from langgraph_sdk import get_client

        # get top-level LangGraphClient
        client = get_client(url="http://localhost:8123")

        # example usage: client.<model>.<method_name>()
        assistants = await client.assistants.get(assistant_id="some_uuid")
    N$__LANGGRAPH_DEFER_LOOPBACK_TRANSPORTtruez/noauth)app	root_pathz
http://apir   )rZ   )r[   http://localhost:8123   retries,  connectreadwritepoolbase_url	transporttimeoutrF   )r6   environgethttpxASGITransport_registered_transportsappendlanggraph_api.serverrZ   	ExceptionAsyncHTTPTransportAsyncClientTimeoutrG   rV   )rU   r9   rF   rh   rZ   clients         r<   
get_clientrv   v   s    B 59I
{::>>@AVK++	JI")))4C.4"!//yI	 ,,Q7	ac1EGW-	F 6""  .-.s   C C! C!c                      e Zd ZdZddZy)rV   a  Top-level client for LangGraph API.

    Attributes:
        assistants: Manages versioned configuration for your graphs.
        threads: Handles (potentially) multi-turn interactions, such as conversational threads.
        runs: Controls individual invocations of the graph.
        crons: Manages scheduled operations.
        store: Interfaces with persistent, shared data storage.
    c                (   t        |      | _        t        | j                        | _        t	        | j                        | _        t        | j                        | _        t        | j                        | _	        t        | j                        | _        y N)
HttpClienthttpAssistantsClient
assistantsThreadsClientthreads
RunsClientruns
CronClientcronsStoreClientstoreselfru   s     r<   __init__zLangGraphClient.__init__   s^    v&	*4995$TYY/tyy)			*
 +
r>   Nru   zhttpx.AsyncClientreturnNone__name__
__module____qualname____doc__r    r>   r<   rV   rV      s    ,r>   c                      e Zd ZdZddZddd	 	 	 	 	 	 	 ddZdd	 	 	 	 	 	 	 ddZdd	 	 	 	 	 	 	 ddZdd	 	 	 	 	 	 	 dd	Zddd
	 	 	 	 	 	 	 ddZ	dddd	 	 	 	 	 	 	 	 	 	 	 ddZ
y)rz   zHandle async requests to the LangGraph API.

    Adds additional error messaging & content handling above the
    provided httpx client.

    Attributes:
        client (httpx.AsyncClient): Underlying HTTPX async client.
    c                    || _         y ry   ru   r   s     r<   r   zHttpClient.__init__   	    r>   NparamsrF   c                 K   | j                   j                  |||       d{   }	 |j                          t        |       d{   S 7 (# t        j                  $ rn}|j                          d{  7  j                         }t        j                  dk\  r|j                  |       |t        j                  d| |       |d}~ww xY w7 w)Send a GET request.r   N      Error from langgraph-api: exc_info)ru   rk   raise_for_statusrl   HTTPStatusErrorareaddecodesysversion_infoadd_noteloggererroradecode_jsonr   pathr   rF   rebodys          r<   rk   zHttpClient.get   s      ++//$vw/GG	  "!_$$ H $$ 	'')OO++-D7*

4  G 9$@1MG	 %sJ   "CACA CC	CC"C5A86ACCCrF   c                 K   |t        |       d{   \  }}ni d}}|r|j                  |       | j                  j                  |||       d{   }	 |j	                          t        |       d{   S 7 i7 *# t
        j                  $ rn}|j                          d{  7  j                         }t        j                  dk\  r|j                  |       |t        j                  d| |       |d}~ww xY w7 wzSend a POST request.Nr>   rF   contentr   r   r   )aencode_jsonupdateru   postr   rl   r   r   r   r   r   r   r   r   r   	r   r   jsonrF   request_headersr   r   r   r   s	            r<   r   zHttpClient.post   s      -9$-?'?$OW')3WO""7+++""4'"RR	  "!_$$! (@ S $$ 	'')OO++-D7*

4  G 9$@1MG	 %s_   DA=A DA?DB *D8D9D?DDC='B*(AC==DDc                 K   t        |       d{   \  }}|r|j                  |       | j                  j                  |||       d{   }	 |j	                          t        |       d{   S 7 d7 *# t
        j                  $ rn}|j                          d{  7  j                         }t        j                  dk\  r|j                  |       |t        j                  d| |       |d}~ww xY w7 w)Send a PUT request.Nr   r   r   r   )r   r   ru   putr   rl   r   r   r   r   r   r   r   r   r   r   s	            r<   r   zHttpClient.put  s      *6d);#; ""7+++//$/QQ	  "!_$$ $< R $$ 	'')OO++-D7*

4  G 9$@1MG	 %^   D A6;D A8D A: #D 1C>2D 8D :C;C6 B#!AC66C;;D c                 K   t        |       d{   \  }}|r|j                  |       | j                  j                  |||       d{   }	 |j	                          t        |       d{   S 7 d7 *# t
        j                  $ rn}|j                          d{  7  j                         }t        j                  dk\  r|j                  |       |t        j                  d| |       |d}~ww xY w7 w)Send a PATCH request.Nr   r   r   r   )r   r   ru   patchr   rl   r   r   r   r   r   r   r   r   r   r   s	            r<   r   zHttpClient.patch  s      *6d);#; ""7+++##D/7#SS	  "!_$$ $< T $$ 	'')OO++-D7*

4  G 9$@1MG	 %r   r   rF   c                 K   | j                   j                  d|||       d{   }	 |j                          y7 # t        j                  $ rn}|j                          d{  7  j                         }t        j                  dk\  r|j                  |       |t        j                  d| |       |d}~ww xY ww)Send a DELETE request.DELETEr   Nr   r   r   )ru   requestr   rl   r   r   r   r   r   r   r   r   r   r   r   rF   r   r   r   s          r<   deletezHttpClient.delete(  s      ++%%h4%QQ	  R $$ 	'')OO++-D7*

4  G 9$@1MG	s;   #C<C> CB?B:$A'%AB::B??Cr   r   rF   c              l  K   t        |       d{   \  }}d|d<   d|d<   |r|j                  |       | j                  j                  |||||      4 d{   }	 |j	                          |j                  j                  d
d      j!                  d      d   }d|vrt        j"                  d|      t%               }t'        |      2 3 d{   }|j                  |j)                  d            }|-| 37 7 # t
        j                  $ rn}	|j                          d{  7  j                         }
t        j                  dk\  r|	j                  |
       |	t        j                  d|
 |		       |	d}	~	ww xY w7 6 ddd      d{  7   y# 1 d{  7  sw Y   yxY ww)zStream results using SSE.Ntext/event-streamAcceptno-storeCache-ControlrF   r   r   r   r   r   content-type ;r   JExpected response header Content-Type to contain 'text/event-stream', got    
)line)r   r   ru   streamr   rl   r   r   r   r   r   r   r   r   rF   rk   	partitionTransportErrorr+   r,   rstripr   r   methodr   r   rF   r   r   resr   r   content_typedecoderr   sses                  r<   r   zHttpClient.stream;  s     *6d);#; $7!+5(""7+;;%%D/76 & 
 	 	$$& ;;??>2>HHMaPL",6**'*, 
 !lG-c2  dnn$++e*<n=?IA $<	 (( !iik))113##w.JJt$  LL#=dV!DqLQ 2-	 	 	 	 	s   F4DAF4DF4F D0AFFF
F$F<FF4F4FF,D/-AFFF
FFF4FF4F1%F(&F1-F4r   r   strr   Optional[QueryParamTypes]rF   Optional[dict[str, str]]r   r   r   r   r   Optional[dict]rF   r   r   r   r   r   r   rJ   rF   r   r   r   r   r   r   zOptional[Any]rF   r   r   r   )r   r   r   r   r   r   r   r   rF   r   r   AsyncIterator[StreamPart])r   r   r   r   r   rk   r   r   r   r   r   r   r>   r<   rz   rz      sD    -1,0%% *	%
 *% 
%2 -1%% 	%
 *% 
%8 MQ%%"&%1I%	%( MQ%%"&%1I%	%. #,0 	
 * 
0  $,0,0** *
 * ** ** 
#*r>   rz   c                  K   | i d fS t        j                         j                  d t        j                  | t
        t        j                  t        j                  z         d {   }t        t        |            }d}||d}||fS 7 #wNzapplication/json)zContent-LengthzContent-Type)
asyncioget_running_looprun_in_executororjsondumpsrT   OPT_SERIALIZE_NUMPYOPT_NON_STR_KEYSr   lenr   r   content_lengthr   rF   s        r<   r   r   h  s     |4x))+;;""V%<%<< D T^N%L!/NGD=s   A"B
$B%$B
c                   K   | j                          d {   }|r;t        j                         j                  d t        j
                  |       d {   S d S 7 C7 wry   )r   r   r   r   r   loadsr   r   s     r<   r   r   x  sT     ?D  &&(88v||TRR  Rs!   AA<AAAAc                     e Zd ZdZddZdd	 	 	 	 	 ddZddd	 	 	 	 	 	 	 ddZdd	 	 	 	 	 dd	Z	 	 ddd	 	 	 	 	 	 	 	 	 dd
Z	 dddddddd	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 ddZ	ddddddd	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 ddZ
dd	 	 	 	 	 ddZdddddd	 	 	 	 	 	 	 	 	 	 	 d dZ	 	 	 d!dd	 	 	 	 	 	 	 	 	 	 	 d"dZdd	 	 	 	 	 	 	 d#dZy)$r|   a  Client for managing assistants in LangGraph.

    This class provides methods to interact with assistants,
    which are versioned configurations of your graph.

    Example:

        client = get_client()
        assistant = await client.assistants.get("assistant_id_123")
    c                    || _         y ry   r{   r   r{   s     r<   r   zAssistantsClient.__init__  	    	r>   Nr   c               ^   K   | j                   j                  d| |       d{   S 7 w)ak  Get an assistant by ID.

        Args:
            assistant_id: The ID of the assistant to get.
            headers: Optional custom headers to include with the request.

        Returns:
            Assistant: Assistant Object.

        Example Usage:

            assistant = await client.assistants.get(
                assistant_id="my_assistant_id"
            )
            print(assistant)

            ----------------------------------------------------

            {
                'assistant_id': 'my_assistant_id',
                'graph_id': 'agent',
                'created_at': '2024-06-25T17:10:33.109781+00:00',
                'updated_at': '2024-06-25T17:10:33.109781+00:00',
                'config': {},
                'metadata': {'created_by': 'system'},
                'version': 1,
                'name': 'my_assistant'
            }

        /assistants/r   Nr{   rk   r   assistant_idrF   s      r<   rk   zAssistantsClient.get  s-     B YY]]\,#@']RRRR   $-+-FxrayrF   c               f   K   | j                   j                  d| dd|i|       d{   S 7 w)ag  Get the graph of an assistant by ID.

        Args:
            assistant_id: The ID of the assistant to get the graph of.
            xray: Include graph representation of subgraphs. If an integer value is provided, only subgraphs with a depth less than or equal to the value will be included.
            headers: Optional custom headers to include with the request.

        Returns:
            Graph: The graph information for the assistant in JSON format.

        Example Usage:

            graph_info = await client.assistants.get_graph(
                assistant_id="my_assistant_id"
            )
            print(graph_info)

            --------------------------------------------------------------------------------------------------------------------------

            {
                'nodes':
                    [
                        {'id': '__start__', 'type': 'schema', 'data': '__start__'},
                        {'id': '__end__', 'type': 'schema', 'data': '__end__'},
                        {'id': 'agent','type': 'runnable','data': {'id': ['langgraph', 'utils', 'RunnableCallable'],'name': 'agent'}},
                    ],
                'edges':
                    [
                        {'source': '__start__', 'target': 'agent'},
                        {'source': 'agent','target': '__end__'}
                    ]
            }


        r   /graphr  r   Nr   r   r   r  rF   s       r<   	get_graphzAssistantsClient.get_graph  sB     T YY]]<./PW # 
 
 	
 
   (1/1c               `   K   | j                   j                  d| d|       d{   S 7 w)a  Get the schemas of an assistant by ID.

        Args:
            assistant_id: The ID of the assistant to get the schema of.
            headers: Optional custom headers to include with the request.

        Returns:
            GraphSchema: The graph schema for the assistant.

        Example Usage:

            schema = await client.assistants.get_schemas(
                assistant_id="my_assistant_id"
            )
            print(schema)

            ----------------------------------------------------------------------------------------------------------------------------

            {
                'graph_id': 'agent',
                'state_schema':
                    {
                        'title': 'LangGraphInput',
                        '$ref': '#/definitions/AgentState',
                        'definitions':
                            {
                                'BaseMessage':
                                    {
                                        'title': 'BaseMessage',
                                        'description': 'Base abstract Message class. Messages are the inputs and outputs of ChatModels.',
                                        'type': 'object',
                                        'properties':
                                            {
                                             'content':
                                                {
                                                    'title': 'Content',
                                                    'anyOf': [
                                                        {'type': 'string'},
                                                        {'type': 'array','items': {'anyOf': [{'type': 'string'}, {'type': 'object'}]}}
                                                    ]
                                                },
                                            'additional_kwargs':
                                                {
                                                    'title': 'Additional Kwargs',
                                                    'type': 'object'
                                                },
                                            'response_metadata':
                                                {
                                                    'title': 'Response Metadata',
                                                    'type': 'object'
                                                },
                                            'type':
                                                {
                                                    'title': 'Type',
                                                    'type': 'string'
                                                },
                                            'name':
                                                {
                                                    'title': 'Name',
                                                    'type': 'string'
                                                },
                                            'id':
                                                {
                                                    'title': 'Id',
                                                    'type': 'string'
                                                }
                                            },
                                        'required': ['content', 'type']
                                    },
                                'AgentState':
                                    {
                                        'title': 'AgentState',
                                        'type': 'object',
                                        'properties':
                                            {
                                                'messages':
                                                    {
                                                        'title': 'Messages',
                                                        'type': 'array',
                                                        'items': {'$ref': '#/definitions/BaseMessage'}
                                                    }
                                            },
                                        'required': ['messages']
                                    }
                            }
                    },
                'config_schema':
                    {
                        'title': 'Configurable',
                        'type': 'object',
                        'properties':
                            {
                                'model_name':
                                    {
                                        'title': 'Model Name',
                                        'enum': ['anthropic', 'openai'],
                                        'type': 'string'
                                    }
                            }
                    }
            }

        r   /schemasr   Nr   r   s      r<   get_schemaszAssistantsClient.get_schemas  s;     T YY]]<.17 # 
 
 	
 
s   %.,.c                  K   |.| j                   j                  d| d| d|i|       d{   S | j                   j                  d| dd|i|       d{   S 7 07 w)a  Get the schemas of an assistant by ID.

        Args:
            assistant_id: The ID of the assistant to get the schema of.
            namespace: Optional namespace to filter by.
            recurse: Whether to recursively get subgraphs.
            headers: Optional custom headers to include with the request.

        Returns:
            Subgraphs: The graph schema for the assistant.

        Nr   /subgraphs/recurser   
/subgraphsr   r   r   	namespacer  rF   s        r<   get_subgraphszAssistantsClient.get_subgraphsO  s     (  |nK	{C!7+ '    |nJ7!7+ '   s!   ,A#A+A#A!A#!A#metadatar   	if_existsnamerF   descriptionc                  K   d|i}	|r||	d<   |r||	d<   |r||	d<   |r||	d<   |r||	d<   |r||	d<   | j                   j                  d|	|	       d
{   S 7 w)a  Create a new assistant.

        Useful when graph is configurable and you want to create different assistants based on different configurations.

        Args:
            graph_id: The ID of the graph the assistant should use. The graph ID is normally set in your langgraph.json configuration.
            config: Configuration to use for the graph.
            metadata: Metadata to add to assistant.
            assistant_id: Assistant ID to use, will default to a random UUID if not provided.
            if_exists: How to handle duplicate creation. Defaults to 'raise' under the hood.
                Must be either 'raise' (raise error if duplicate), or 'do_nothing' (return existing assistant).
            name: The name of the assistant. Defaults to 'Untitled' under the hood.
            headers: Optional custom headers to include with the request.
            description: Optional description of the assistant.
                The description field is available for langgraph-api server version>=0.0.45

        Returns:
            Assistant: The created assistant.

        Example Usage:

            assistant = await client.assistants.create(
                graph_id="agent",
                config={"configurable": {"model_name": "openai"}},
                metadata={"number":1},
                assistant_id="my-assistant-id",
                if_exists="do_nothing",
                name="my_name"
            )
        graph_idconfigr  r   r  r  r  /assistantsr   Nr{   r   
r   r  r  r  r   r  r  rF   r  payloads
             r<   createzAssistantsClient.createp  s     V #
  &GH"*GJ&2GN##,GK "GFO%0GM"YY^^M^QQQQs   AAAAr  r  r  r  rF   r  c                  K   i }|r||d<   |r||d<   |r||d<   |r||d<   |r||d<   | j                   j                  d| ||       d{   S 7 w)	a  Update an assistant.

        Use this to point to a different graph, update the configuration, or change the metadata of an assistant.

        Args:
            assistant_id: Assistant to update.
            graph_id: The ID of the graph the assistant should use.
                The graph ID is normally set in your langgraph.json configuration. If None, assistant will keep pointing to same graph.
            config: Configuration to use for the graph.
            metadata: Metadata to merge with existing assistant metadata.
            name: The new name for the assistant.
            headers: Optional custom headers to include with the request.
            description: Optional description of the assistant.
                The description field is available for langgraph-api server version>=0.0.45

        Returns:
            Assistant: The updated assistant.

        Example Usage:

            assistant = await client.assistants.update(
                assistant_id='e280dad7-8618-443f-87f1-8e41841c180f',
                graph_id="other-graph",
                config={"configurable": {"model_name": "anthropic"}},
                metadata={"number":2}
            )

        r  r  r  r  r  r   r   Nr{   r   	r   r   r  r  r  r  rF   r  r  s	            r<   r   zAssistantsClient.update  s     N #%"*GJ &GH"*GJ"GFO%0GM"YY__<.) % 
 
 	
 
s   A
AAAc               `   K   | j                   j                  d| |       d{    y7 w)aR  Delete an assistant.

        Args:
            assistant_id: The assistant ID to delete.
            headers: Optional custom headers to include with the request.

        Returns:
            None

        Example Usage:

            await client.assistants.delete(
                assistant_id="my_assistant_id"
            )

        r   r   Nr{   r   r   s      r<   r   zAssistantsClient.delete  s,     , iil^<gNNN   $.,.
   r   r  r  limitoffsetrF   c                  K   ||d}|r||d<   |r||d<   | j                   j                  d||       d{   S 7 w)a  Search for assistants.

        Args:
            metadata: Metadata to filter by. Exact match filter for each KV pair.
            graph_id: The ID of the graph to filter by.
                The graph ID is normally set in your langgraph.json configuration.
            limit: The maximum number of results to return.
            offset: The number of results to skip.
            headers: Optional custom headers to include with the request.

        Returns:
            list[Assistant]: A list of assistants.

        Example Usage:

            assistants = await client.assistants.search(
                metadata = {"name":"my_name"},
                graph_id="my_graph_id",
                limit=5,
                offset=5
            )
        r)  r*  r  r  /assistants/searchr   Nr  r   r  r  r)  r*  rF   r  s          r<   searchzAssistantsClient.search  s_     @ #
 "*GJ"*GJYY^^  $ 
 
 	
 
s   5><>c               z   K   ||d}|r||d<   | j                   j                  d| d||       d{   S 7 w)a  List all versions of an assistant.

        Args:
            assistant_id: The assistant ID to get versions for.
            metadata: Metadata to filter versions by. Exact match filter for each KV pair.
            limit: The maximum number of versions to return.
            offset: The number of versions to skip.
            headers: Optional custom headers to include with the request.

        Returns:
            list[AssistantVersion]: A list of assistant versions.

        Example Usage:

            assistant_versions = await client.assistants.get_versions(
                assistant_id="my_assistant_id"
            )

        r,  r  r   	/versionsr   Nr  r   r   r  r)  r*  rF   r  s          r<   get_versionszAssistantsClient.get_versions(  sX     < #
 "*GJYY^^<.	2' $ 
 
 	
 
   2;9;c               j   K   d|i}| j                   j                  d| d||       d{   S 7 w)  Change the version of an assistant.

        Args:
            assistant_id: The assistant ID to delete.
            version: The version to change to.
            headers: Optional custom headers to include with the request.

        Returns:
            Assistant: Assistant Object.

        Example Usage:

            new_version_assistant = await client.assistants.set_latest(
                assistant_id="my_assistant_id",
                version=3
            )

        versionr   /latestr   Nr  r   r   r7  rF   r  s        r<   
set_latestzAssistantsClient.set_latestO  sF     4 $-g"6YY^^<.0w $ 
 
 	
 
s   *313r{   rz   r   r   r   r   rF   r   r   r   r   r   r  zUnion[int, bool]rF   r   r   zdict[str, list[dict[str, Any]]]r   r   rF   r   r   r   NF
r   r   r  Optional[str]r  boolrF   r   r   r&   ry   r  rA  r  Optional[Config]r  r   r   rA  r  Optional[OnConflictBehavior]r  rA  rF   r   r  rA  r   r   r   r   r  rA  r  rD  r  r   r  rA  rF   r   r  rA  r   r   r   r   rF   r   r   r   r  r   r  rA  r)  intr*  rI  rF   r   r   zlist[Assistant]Nr'  r   r   r   r  r   r)  rI  r*  rI  rF   r   r   zlist[AssistantVersion]r   r   r7  rI  rF   r   r   r   r   r   r   r   r   rk   r  r  r  r  r   r   r/  r3  r:  r   r>   r<   r|   r|     s   	 IM!S!S-E!S	!SN "',0,
,
 	,

 *,
 
),
^ IMl
l
-El
	l
b $(	 -1 ! 	 * 
H $(9R
 &*26",0%)9R9R !9R
 9R $9R 09R 9R *9R #9R 
9R~ #'#'",0%)6
6
  	6

 !6
 6
 6
 *6
 #6
 
6
x -1	OO *	O
 
O6 "&,0+
 +
  	+

 +
 +
 *+
 
+
` %
 -1%
%
 %
 	%

 %
 *%
 
 %
X -1

 

 *
 

r>   r|   c                  j   e Zd ZdZddZdd	 	 	 	 	 ddZddddddd	 	 	 	 	 	 	 	 	 	 	 	 	 ddZdd	 	 	 	 	 	 	 ddZdd	 	 	 	 	 dd	Zdddd
ddd	 	 	 	 	 	 	 	 	 	 	 	 	 ddZ	dd	 	 	 	 	 ddZ
	 	 dddd	 	 	 	 	 	 	 	 	 	 	 ddZddddd	 	 	 	 	 	 	 	 	 	 	 	 	 ddZd
ddddd	 	 	 	 	 	 	 	 	 	 	 	 	 ddZy) r~   a  Client for managing threads in LangGraph.

    A thread maintains the state of a graph across multiple interactions/invocations (aka runs).
    It accumulates and persists the graph's state, allowing for continuity between separate
    invocations of the graph.

    Example:

        client = get_client()
        new_thread = await client.threads.create(metadata={"user_id": "123"})
    c                    || _         y ry   r   r   s     r<   r   zThreadsClient.__init__}  r   r>   Nr   c               ^   K   | j                   j                  d| |       d{   S 7 w)a  Get a thread by ID.

        Args:
            thread_id: The ID of the thread to get.
            headers: Optional custom headers to include with the request.

        Returns:
            Thread: Thread object.

        Example Usage:

            thread = await client.threads.get(
                thread_id="my_thread_id"
            )
            print(thread)

            -----------------------------------------------------

            {
                'thread_id': 'my_thread_id',
                'created_at': '2024-07-18T18:35:15.540834+00:00',
                'updated_at': '2024-07-18T18:35:15.540834+00:00',
                'metadata': {'graph_id': 'agent'}
            }

        	/threads/r   Nr   r   	thread_idrF   s      r<   rk   zThreadsClient.get  s,     < YY]]Yyk#:G]LLLLr  r  rS  r  
superstepsr  rF   c               D  K   i }|r||d<   |s|ri |xs i |rd|ini |d<   |r||d<   |rA|D 	cg c]0  }d|d   D 	cg c]  }	|	d   |	j                  d      |	d   d	 c}	i2 c}	}|d
<   | j                  j                  d||       d{   S c c}	w c c}	}w 7 w)a  Create a new thread.

        Args:
            metadata: Metadata to add to thread.
            thread_id: ID of thread.
                If None, ID will be a randomly generated UUID.
            if_exists: How to handle duplicate creation. Defaults to 'raise' under the hood.
                Must be either 'raise' (raise error if duplicate), or 'do_nothing' (return existing thread).
            supersteps: Apply a list of supersteps when creating a thread, each containing a sequence of updates.
                Each update has `values` or `command` and `as_node`. Used for copying a thread between deployments.
            graph_id: Optional graph ID to associate with the thread.
            headers: Optional custom headers to include with the request.

        Returns:
            Thread: The created thread.

        Example Usage:

            thread = await client.threads.create(
                metadata={"number":1},
                thread_id="my-thread-id",
                if_exists="raise"
            )
        rS  r  r  r  updatesvaluescommandas_noderX  rY  rZ  rU  /threadsr   Nrk   r{   r   
r   r  rS  r  rU  r  rF   r  sus
             r<   r  zThreadsClient.create  s     D #%#,GK x#>r#-5J)2#GJ #,GK  $%   "#9  	 '(k'(uuY'7'(| 	%GL! YY^^JWg^NNN % Os3   /B B"B B&(B BB BB c               d   K   | j                   j                  d| d|i|       d{   S 7 w)a  Update a thread.

        Args:
            thread_id: ID of thread to update.
            metadata: Metadata to merge with existing thread metadata.
            headers: Optional custom headers to include with the request.

        Returns:
            Thread: The created thread.

        Example Usage:

            thread = await client.threads.update(
                thread_id="my-thread-id",
                metadata={"number":1},
            )
        rQ  r  r   Nr"  r   rS  r  rF   s       r<   r   zThreadsClient.update  s?     0 YY__	{#:x*@' % 
 
 	
 
   '0.0c               `   K   | j                   j                  d| |       d{    y7 w)aF  Delete a thread.

        Args:
            thread_id: The ID of the thread to delete.
            headers: Optional custom headers to include with the request.

        Returns:
            None

        Example Usage:

            await client.threads.delete(
                thread_id="my_thread_id"
            )

        rQ  r   Nr%  rR  s      r<   r   zThreadsClient.delete  s,     & ii9+6HHHr&  r'  r   r  rX  statusr)  r*  rF   c                  K   ||d}|r||d<   |r||d<   |r||d<   | j                   j                  d||       d{   S 7 w)a  Search for threads.

        Args:
            metadata: Thread metadata to filter on.
            values: State values to filter on.
            status: Thread status to filter on.
                Must be one of 'idle', 'busy', 'interrupted' or 'error'.
            limit: Limit on number of threads to return.
            offset: Offset in threads table to start search from.
            headers: Optional custom headers to include with the request.

        Returns:
            list[Thread]: List of the threads matching the search parameters.

        Example Usage:

            threads = await client.threads.search(
                metadata={"number":1},
                status="interrupted",
                limit=15,
                offset=5
            )

        r,  r  rX  rf  /threads/searchr   Nr  r   r  rX  rf  r)  r*  rF   r  s           r<   r/  zThreadsClient.search  sl     F #
 "*GJ &GH &GHYY^^ $ 
 
 	
 
s   <AAAc               b   K   | j                   j                  d| dd|       d{   S 7 w)a@  Copy a thread.

        Args:
            thread_id: The ID of the thread to copy.
            headers: Optional custom headers to include with the request.

        Returns:
            None

        Example Usage:

            await client.threads.copy(
                thread_id="my_thread_id"
            )

        rQ  /copyNr   r  rR  s      r<   copyzThreadsClient.copy@  s<     & YY^^	{%(tW $ 
 
 	
 
s   &/-/F	subgraphsrF   c               ,  K   |r-| j                   j                  d| d||d|       d{   S |r.| j                   j                  d| d| d|i|       d{   S | j                   j                  d| d	d|i|       d{   S 7 `7 27 w)
a)  Get the state of a thread.

        Args:
            thread_id: The ID of the thread to get the state of.
            checkpoint: The checkpoint to get the state of.
            checkpoint_id: (deprecated) The checkpoint ID to get the state of.
            subgraphs: Include subgraphs states.
            headers: Optional custom headers to include with the request.

        Returns:
            ThreadState: the thread of the state.

        Example Usage:

            thread_state = await client.threads.get_state(
                thread_id="my_thread_id",
                checkpoint_id="my_checkpoint_id"
            )
            print(thread_state)

            ----------------------------------------------------------------------------------------------------------------------------------------------------------------------

            {
                'values': {
                    'messages': [
                        {
                            'content': 'how are you?',
                            'additional_kwargs': {},
                            'response_metadata': {},
                            'type': 'human',
                            'name': None,
                            'id': 'fe0a5778-cfe9-42ee-b807-0adaa1873c10',
                            'example': False
                        },
                        {
                            'content': "I'm doing well, thanks for asking! I'm an AI assistant created by Anthropic to be helpful, honest, and harmless.",
                            'additional_kwargs': {},
                            'response_metadata': {},
                            'type': 'ai',
                            'name': None,
                            'id': 'run-159b782c-b679-4830-83c6-cef87798fe8b',
                            'example': False,
                            'tool_calls': [],
                            'invalid_tool_calls': [],
                            'usage_metadata': None
                        }
                    ]
                },
                'next': [],
                'checkpoint':
                    {
                        'thread_id': 'e2496803-ecd5-4e0c-a779-3226296181c2',
                        'checkpoint_ns': '',
                        'checkpoint_id': '1ef4a9b8-e6fb-67b1-8001-abd5184439d1'
                    }
                'metadata':
                    {
                        'step': 1,
                        'run_id': '1ef4a9b8-d7da-679a-a45a-872054341df2',
                        'source': 'loop',
                        'writes':
                            {
                                'agent':
                                    {
                                        'messages': [
                                            {
                                                'id': 'run-159b782c-b679-4830-83c6-cef87798fe8b',
                                                'name': None,
                                                'type': 'ai',
                                                'content': "I'm doing well, thanks for asking! I'm an AI assistant created by Anthropic to be helpful, honest, and harmless.",
                                                'example': False,
                                                'tool_calls': [],
                                                'usage_metadata': None,
                                                'additional_kwargs': {},
                                                'response_metadata': {},
                                                'invalid_tool_calls': []
                                            }
                                        ]
                                    }
                            },
                'user_id': None,
                'graph_id': 'agent',
                'thread_id': 'e2496803-ecd5-4e0c-a779-3226296181c2',
                'created_by': 'system',
                'assistant_id': 'fe096781-5601-53d2-b2f6-0d3403f7e9ca'},
                'created_at': '2024-07-25T15:35:44.184703+00:00',
                'parent_config':
                    {
                        'thread_id': 'e2496803-ecd5-4e0c-a779-3226296181c2',
                        'checkpoint_ns': '',
                        'checkpoint_id': '1ef4a9b8-d80d-6fa7-8000-9300467fad0f'
                    }
            }

        rQ  /state/checkpoint
checkpointrn  r   N/state/rn  r   /stater{   r   rk   r   rS  rr  checkpoint_idrn  rF   s         r<   	get_statezThreadsClient.get_stateW  s     P I;&78$.YG (   
 I;gm_=#Y/ '    I;f-#Y/ '   s3   +BB/BB+B	B
BBBrZ  rr  rw  rF   c                  K   d|i}|r||d<   |r||d<   |r||d<   | j                   j                  d| d||       d{   S 7 w)	a/  Update the state of a thread.

        Args:
            thread_id: The ID of the thread to update.
            values: The values to update the state with.
            as_node: Update the state as if this node had just executed.
            checkpoint: The checkpoint to update the state of.
            checkpoint_id: (deprecated) The checkpoint ID to update the state of.
            headers: Optional custom headers to include with the request.

        Returns:
            ThreadUpdateStateResponse: Response after updating a thread's state.

        Example Usage:

            response = await client.threads.update_state(
                thread_id="my_thread_id",
                values={"messages":[{"role": "user", "content": "hello!"}]},
                as_node="my_node",
            )
            print(response)

            ----------------------------------------------------------------------------------------------------------------------------------------------------------------------

            {
                'checkpoint': {
                    'thread_id': 'e2496803-ecd5-4e0c-a779-3226296181c2',
                    'checkpoint_ns': '',
                    'checkpoint_id': '1ef4a9b8-e6fb-67b1-8001-abd5184439d1',
                    'checkpoint_map': {}
                }
            }

        rX  rw  rr  rZ  rQ  rt  r   Nr  r   rS  rX  rZ  rr  rw  rF   r  s           r<   update_statezThreadsClient.update_state  sr     Z f#
 '4GO$$.GL!!(GIYY^^	{&) $ 
 
 	
 
   ?AAAr)  beforer  rr  rF   c                  K   d|i}|r||d<   |r||d<   |r||d<   | j                   j                  d| d||       d{   S 7 w)	a  Get the state history of a thread.

        Args:
            thread_id: The ID of the thread to get the state history for.
            checkpoint: Return states for this subgraph. If empty defaults to root.
            limit: The maximum number of states to return.
            before: Return states before this checkpoint.
            metadata: Filter states by metadata key-value pairs.
            headers: Optional custom headers to include with the request.

        Returns:
            list[ThreadState]: the state history of the thread.

        Example Usage:

            thread_state = await client.threads.get_history(
                thread_id="my_thread_id",
                limit=5,
            )

        r)  r  r  rr  rQ  /historyr   Nr  r   rS  r)  r  r  rr  rF   r  s           r<   get_historyzThreadsClient.get_history  sr     @ U#
  &GH"*GJ$.GL!YY^^	{(+'7 $ 
 
 	
 
r}  r;  rS  r   rF   r   r   r'   r  r   rS  rA  r  rE  rU  z7Optional[Sequence[dict[str, Sequence[dict[str, Any]]]]]r  rA  rF   r   r   r'   rS  r   r  dict[str, Any]rF   r   r   r'   rS  r   rF   r   r   r   r  r   rX  r   rf  zOptional[ThreadStatus]r)  rI  r*  rI  rF   r   r   zlist[Thread]NNrS  r   rr  Optional[Checkpoint]rw  rA  rn  rB  rF   r   r   r(   rS  r   rX  z%Optional[Union[dict, Sequence[dict]]]rZ  rA  rr  r  rw  rA  rF   r   r   r*   rS  r   r)  rI  r  zOptional[str | Checkpoint]r  r   rr  r  rF   r   r   zlist[ThreadState]r   r   r   r   r   rk   r  r   r   r/  rl  rx  r|  r  r   r>   r<   r~   r~   p  s   
 FJMM*BM	MF #'26NR"&,0;O ;O !	;O
 0;O L;O  ;O *;O 
;OD -1

 !	

 *
 

: FJII*BI	I0 )-,00
 0
 	0

 '0
 0
 0
 *0
 
0
f FJ

*B
	
4 ,0'+	y  ,0yy )y %	y y *y 
y@ "&+/'+,07
7
 67

 7
 )7
 %7
 *7
 
#7
z -1#'+/,0*
*
 	*

 +*
 !*
 )*
 **
 
*
r>   r~   c                  ,   e Zd ZdZd'dZedddddddddddddddddd	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d(d       Zedddddddddddddddd	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d)d	       Zddddddddddddddddddd
	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d*dZedddddddddddddd	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d+d       Zedddddddddddddddd	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d,d       Zddddddddddddddddd	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d-dZd.dZedddddddddddddddd	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d/d       Z	edddddddddddddd	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d0d       Z	ddddddddddddddddd	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d1dZ	ddddd	 	 	 	 	 	 	 	 	 	 	 d2dZ
dd	 	 	 	 	 	 	 d3dZdd dd!	 	 	 	 	 	 	 	 	 	 	 d4d"Zdd	 	 	 	 	 	 	 d5d#Zdddd$	 	 	 	 	 	 	 	 	 	 	 d6d%Zdd	 	 	 	 	 	 	 d7d&Zy)8r   ap  Client for managing runs in LangGraph.

    A run is a single assistant invocation with optional input, config, and metadata.
    This client manages runs, which can be stateful (on threads) or stateless.

    Example:

        client = get_client()
        run = await client.runs.create(assistant_id="asst_123", thread_id="thread_456", input={"query": "Hello"})
    c                    || _         y ry   r   r   s     r<   r   zRunsClient.__init__D  r   r>   NrX  FinputrY  stream_modestream_subgraphsr  r  rr  rw  interrupt_beforeinterrupt_afterfeedback_keyson_disconnectwebhookmultitask_strategyif_not_existsafter_secondsrF   c                    y ry   r   r   rS  r   r  rY  r  r  r  r  rr  rw  r  r  r  r  r  r  r  r  rF   s                       r<   r   zRunsClient.streamG  s    . %(r>   r  rY  r  r  r  r  r  r  r  r  on_completionr  r  r  rF   c                    y ry   r   r   rS  r   r  rY  r  r  r  r  r  r  r  r  r  r  r  r  rF   s                     r<   r   zRunsClient.stream`  s    * %(r>   r  rY  r  r  r  r  rr  rw  r  r  r  r  r  r  r  r  r  rF   c          
     z   i d|d|r'|j                         D ci c]  \  }}|	|| c}}ndd|d|d|d|d|d	|d
|d|d|d|	d|
d|d|d|d|d|i}|d| dnd}| j                  j                  |d|j                         D ci c]  \  }}|	|| c}}|      S c c}}w c c}}w )aE  Create a run and stream the results.

        Args:
            thread_id: the thread ID to assign to the thread.
                If None will create a stateless run.
            assistant_id: The assistant ID or graph name to stream from.
                If using graph name, will default to first assistant created from that graph.
            input: The input to the graph.
            command: A command to execute. Cannot be combined with input.
            stream_mode: The stream mode(s) to use.
            stream_subgraphs: Whether to stream output from subgraphs.
            metadata: Metadata to assign to the run.
            config: The configuration for the assistant.
            checkpoint: The checkpoint to resume from.
            interrupt_before: Nodes to interrupt immediately before they get executed.
            interrupt_after: Nodes to Nodes to interrupt immediately after they get executed.
            feedback_keys: Feedback keys to assign to run.
            on_disconnect: The disconnect mode to use.
                Must be one of 'cancel' or 'continue'.
            on_completion: Whether to delete or keep the thread created for a stateless run.
                Must be one of 'delete' or 'keep'.
            webhook: Webhook to call after LangGraph API call is done.
            multitask_strategy: Multitask strategy to use.
                Must be one of 'reject', 'interrupt', 'rollback', or 'enqueue'.
            if_not_exists: How to handle missing thread. Defaults to 'reject'.
                Must be either 'reject' (raise error if missing), or 'create' (create new thread).
            after_seconds: The number of seconds to wait before starting the run.
                Use to schedule future runs.

        Returns:
            AsyncIterator[StreamPart]: Asynchronous iterator of stream results.

        Example Usage:

            async for chunk in client.runs.stream(
                thread_id=None,
                assistant_id="agent",
                input={"messages": [{"role": "user", "content": "how are you?"}]},
                stream_mode=["values","debug"],
                metadata={"name":"my_run"},
                config={"configurable": {"model_name": "anthropic"}},
                interrupt_before=["node_to_stop_before_1","node_to_stop_before_2"],
                interrupt_after=["node_to_stop_after_1","node_to_stop_after_2"],
                feedback_keys=["my_feedback_key_1","my_feedback_key_2"],
                webhook="https://my.fake.webhook.com",
                multitask_strategy="interrupt"
            ):
                print(chunk)

            ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

            StreamPart(event='metadata', data={'run_id': '1ef4a9b8-d7da-679a-a45a-872054341df2'})
            StreamPart(event='values', data={'messages': [{'content': 'how are you?', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': 'fe0a5778-cfe9-42ee-b807-0adaa1873c10', 'example': False}]})
            StreamPart(event='values', data={'messages': [{'content': 'how are you?', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': 'fe0a5778-cfe9-42ee-b807-0adaa1873c10', 'example': False}, {'content': "I'm doing well, thanks for asking! I'm an AI assistant created by Anthropic to be helpful, honest, and harmless.", 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-159b782c-b679-4830-83c6-cef87798fe8b', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}]})
            StreamPart(event='end', data=None)

        r  rY  Nr  r  r  r  r   r  r  r  r  rr  rw  r  r  r  r  r  rQ  /runs/streamPOSTr   itemsr{   r   r   rS  r   r  rY  r  r  r  r  rr  rw  r  r  r  r  r  r  r  r  r  rF   kvr  endpoints                            r<   r   zRunsClient.streamw  su   b
U
GN'--/C$!QQ]ACTX

 f
 
 ;
  0
 L
  0
 
 ]
 w
 *
 ]
  !"4!
" ]#
$ ]%
& ]'
( ])
0 $ 	{,/ 	
 yy#*==?D41aam!Q$D	   
 	
1 D6 E   
B1
B1

B7"B7r  rY  r  r  r  r  r  r  r  r  r  r  rF   c                  K   y wry   r   r   rS  r   r  rY  r  r  r  r  r  r  r  r  r  r  rF   s                   r<   r  zRunsClient.create  s     &    r  rY  r  r  r  r  rr  rw  r  r  r  r  r  r  rF   c                  K   y wry   r   r   rS  r   r  rY  r  r  r  r  rr  rw  r  r  r  r  r  r  rF   s                     r<   r  zRunsClient.create  s     * r  )r  rY  r  r  r  r  rr  rw  r  r  r  r  r  r  r  rF   c                 K   i d|d|r'|j                         D ci c]  \  }}|	|| c}}ndd|d|d|d|d|d	|d
|d|d|	d|
d|d|d|d|}|j                         D ci c]  \  }}|	|| }}}|r)| j                  j                  d| d|       d{   S | j                  j                  d|       d{   S c c}}w c c}}w 7 57 w)a  Create a background run.

        Args:
            thread_id: the thread ID to assign to the thread.
                If None will create a stateless run.
            assistant_id: The assistant ID or graph name to stream from.
                If using graph name, will default to first assistant created from that graph.
            input: The input to the graph.
            command: A command to execute. Cannot be combined with input.
            stream_mode: The stream mode(s) to use.
            stream_subgraphs: Whether to stream output from subgraphs.
            metadata: Metadata to assign to the run.
            config: The configuration for the assistant.
            checkpoint: The checkpoint to resume from.
            interrupt_before: Nodes to interrupt immediately before they get executed.
            interrupt_after: Nodes to Nodes to interrupt immediately after they get executed.
            webhook: Webhook to call after LangGraph API call is done.
            multitask_strategy: Multitask strategy to use.
                Must be one of 'reject', 'interrupt', 'rollback', or 'enqueue'.
            on_completion: Whether to delete or keep the thread created for a stateless run.
                Must be one of 'delete' or 'keep'.
            if_not_exists: How to handle missing thread. Defaults to 'reject'.
                Must be either 'reject' (raise error if missing), or 'create' (create new thread).
            after_seconds: The number of seconds to wait before starting the run.
                Use to schedule future runs.
            headers: Optional custom headers to include with the request.

        Returns:
            Run: The created background run.

        Example Usage:

            background_run = await client.runs.create(
                thread_id="my_thread_id",
                assistant_id="my_assistant_id",
                input={"messages": [{"role": "user", "content": "hello!"}]},
                metadata={"name":"my_run"},
                config={"configurable": {"model_name": "openai"}},
                interrupt_before=["node_to_stop_before_1","node_to_stop_before_2"],
                interrupt_after=["node_to_stop_after_1","node_to_stop_after_2"],
                webhook="https://my.fake.webhook.com",
                multitask_strategy="interrupt"
            )
            print(background_run)

            --------------------------------------------------------------------------------

            {
                'run_id': 'my_run_id',
                'thread_id': 'my_thread_id',
                'assistant_id': 'my_assistant_id',
                'created_at': '2024-07-25T15:35:42.598503+00:00',
                'updated_at': '2024-07-25T15:35:42.598503+00:00',
                'metadata': {},
                'status': 'pending',
                'kwargs':
                    {
                        'input':
                            {
                                'messages': [
                                    {
                                        'role': 'user',
                                        'content': 'how are you?'
                                    }
                                ]
                            },
                        'config':
                            {
                                'metadata':
                                    {
                                        'created_by': 'system'
                                    },
                                'configurable':
                                    {
                                        'run_id': 'my_run_id',
                                        'user_id': None,
                                        'graph_id': 'agent',
                                        'thread_id': 'my_thread_id',
                                        'checkpoint_id': None,
                                        'model_name': "openai",
                                        'assistant_id': 'my_assistant_id'
                                    }
                            },
                        'webhook': "https://my.fake.webhook.com",
                        'temporary': False,
                        'stream_mode': ['values'],
                        'feedback_keys': None,
                        'interrupt_after': ["node_to_stop_after_1","node_to_stop_after_2"],
                        'interrupt_before': ["node_to_stop_before_1","node_to_stop_before_2"]
                    },
                'multitask_strategy': 'interrupt'
            }

        r  rY  Nr  r  r  r  r   r  r  r  rr  rw  r  r  r  r  rQ  /runsr   r  r{   r   )r   rS  r   r  rY  r  r  r  r  rr  rw  r  r  r  r  r  r  r  rF   r  r  r  s                         r<   r  zRunsClient.create  sj    h
U
GN'--/C$!QQ]ACTX

 ;
  0
 f
 
 L
  0
 
 w
 *
 ]
 !"4
  ]!
" ]#
$ ]%
( %,MMOEDAqq}1a4EE)I;e(D7SSSg>>>+ D" FS>sE   C$
C
C
AC$1
C<C)C$*C +$C$C"C$"C$c                   K   dd}|D cg c]
  } ||       }}| j                   j                  d|       d{   S c c}w 7 	w),Create a batch of stateless background runs.c                \    | j                         D ci c]  \  }}|	|| c}}S c c}}w ry   r  r  r  r  s      r<   filter_payloadz/RunsClient.create_batch.<locals>.filter_payload  (    %,]]_FTQAqDFFF   
((/runs/batchr  Nr  r!   r  )r   payloadsr  r  s       r<   create_batchzRunsClient.create_batch  sJ     	G <DDN7+DDYY^^M^AAA EAs   	AA"AA
AT)r  rY  r  r  rr  rw  r  r  r  r  r  r  r  raise_errorrF   c                  K   y wry   r   )r   rS  r   r  rY  r  r  rr  rw  r  r  r  r  r  r  r  r  rF   s                     r<   waitzRunsClient.wait  s     * -0r  )r  rY  r  r  r  r  r  r  r  r  r  r  rF   c                  K   y wry   r   )r   rS  r   r  rY  r  r  r  r  r  r  r  r  r  r  rF   s                   r<   r  zRunsClient.wait  s     & -0r  )r  rY  r  r  rr  rw  r  r  r  r  r  r  r  r  r  rF   c                 K   ||r'|j                         D ci c]  \  }}|	|| c}}nd||||	|
||||||||d}|d| dnd}| j                  j                  ||j                         D ci c]  \  }}|	|| c}}|       d{   }|r[t        |t              rKd|v rGt        |d   t              r4t        |d   j                  d       d|d   j                  d	             |S c c}}w c c}}w 7 ow)
aL  Create a run, wait until it finishes and return the final state.

        Args:
            thread_id: the thread ID to create the run on.
                If None will create a stateless run.
            assistant_id: The assistant ID or graph name to run.
                If using graph name, will default to first assistant created from that graph.
            input: The input to the graph.
            command: A command to execute. Cannot be combined with input.
            metadata: Metadata to assign to the run.
            config: The configuration for the assistant.
            checkpoint: The checkpoint to resume from.
            interrupt_before: Nodes to interrupt immediately before they get executed.
            interrupt_after: Nodes to Nodes to interrupt immediately after they get executed.
            webhook: Webhook to call after LangGraph API call is done.
            on_disconnect: The disconnect mode to use.
                Must be one of 'cancel' or 'continue'.
            on_completion: Whether to delete or keep the thread created for a stateless run.
                Must be one of 'delete' or 'keep'.
            multitask_strategy: Multitask strategy to use.
                Must be one of 'reject', 'interrupt', 'rollback', or 'enqueue'.
            if_not_exists: How to handle missing thread. Defaults to 'reject'.
                Must be either 'reject' (raise error if missing), or 'create' (create new thread).
            after_seconds: The number of seconds to wait before starting the run.
                Use to schedule future runs.
            headers: Optional custom headers to include with the request.

        Returns:
            Union[list[dict], dict[str, Any]]: The output of the run.

        Example Usage:

            final_state_of_run = await client.runs.wait(
                thread_id=None,
                assistant_id="agent",
                input={"messages": [{"role": "user", "content": "how are you?"}]},
                metadata={"name":"my_run"},
                config={"configurable": {"model_name": "anthropic"}},
                interrupt_before=["node_to_stop_before_1","node_to_stop_before_2"],
                interrupt_after=["node_to_stop_after_1","node_to_stop_after_2"],
                webhook="https://my.fake.webhook.com",
                multitask_strategy="interrupt"
            )
            print(final_state_of_run)

            -------------------------------------------------------------------------------------------------------------------------------------------

            {
                'messages': [
                    {
                        'content': 'how are you?',
                        'additional_kwargs': {},
                        'response_metadata': {},
                        'type': 'human',
                        'name': None,
                        'id': 'f51a862c-62fe-4866-863b-b0863e8ad78a',
                        'example': False
                    },
                    {
                        'content': "I'm doing well, thanks for asking! I'm an AI assistant created by Anthropic to be helpful, honest, and harmless.",
                        'additional_kwargs': {},
                        'response_metadata': {},
                        'type': 'ai',
                        'name': None,
                        'id': 'run-bf1cd3c6-768f-4c16-b62d-ba6f17ad8b36',
                        'example': False,
                        'tool_calls': [],
                        'invalid_tool_calls': [],
                        'usage_metadata': None
                    }
                ]
            }

        Nr  rY  r  r  r   r  r  r  rr  rw  r  r  r  r  r  rQ  
/runs/waitr   	__error__r   z: message)r  r{   r   rM   rJ   rq   rk   )r   rS  r   r  rY  r  r  rr  rw  r  r  r  r  r  r  r  r  r  rF   r  r  r  r  responses                           r<   r  zRunsClient.wait  s:    B GN'--/C$!QQ]ACTX ( 0.$*"4****#
( 2;1Fi	{*-L 	 #*==?D41aam!Q$D ( 
 
 8T*x'8K0$7K(,,W56b+9N9R9RS\9]8^_  C D* E
s4   D 
C2C2AD 1
C8<C8D C>A0D r'  r   )r)  r*  rf  rF   c               z   K   ||d}|||d<   | j                   j                  d| d||       d{   S 7 w)a2  List runs.

        Args:
            thread_id: The thread ID to list runs for.
            limit: The maximum number of results to return.
            offset: The number of results to skip.
            status: The status of the run to filter by.
            headers: Optional custom headers to include with the request.

        Returns:
            List[Run]: The runs for the thread.

        Example Usage:

            await client.runs.list(
                thread_id="thread_id",
                limit=5,
                offset=5,
            )

        r,  Nrf  rQ  r  r   r   )r   rS  r)  r*  rf  rF   r   s          r<   rP   zRunsClient.list_  s[     > 
 %F8YY]]	{%( # 
 
 	
 
r4  r   c               d   K   | j                   j                  d| d| |       d{   S 7 w)a  Get a run.

        Args:
            thread_id: The thread ID to get.
            run_id: The run ID to get.
            headers: Optional custom headers to include with the request.

        Returns:
            Run: Run object.

        Example Usage:

            run = await client.runs.get(
                thread_id="thread_id_to_delete",
                run_id="run_id_to_delete",
            )

        rQ  /runs/r   Nr   r   rS  run_idrF   s       r<   rk   zRunsClient.get  s>     , YY]]	{&17 # 
 
 	
 
rc  	interruptr  actionrF   c          
     z   K   | j                   j                  d| d| d|rdnd d| d|       d{   S 7 w)	a  Get a run.

        Args:
            thread_id: The thread ID to cancel.
            run_id: The run ID to cancel.
            wait: Whether to wait until run has completed.
            action: Action to take when cancelling the run. Possible values
                are `interrupt` or `rollback`. Default is `interrupt`.
            headers: Optional custom headers to include with the request.

        Returns:
            None

        Example Usage:

            await client.runs.cancel(
                thread_id="thread_id_to_cancel",
                run_id="run_id_to_cancel",
                wait=True,
                action="interrupt"
            )

        rQ  r  /cancel?wait=   r   &action=Nr   r  r   rS  r  r  r  rF   s         r<   cancelzRunsClient.cancel  sV     @ YY^^	{&4aQ=OxX^W_` $ 
 
 	
 
r4  c               f   K   | j                   j                  d| d| d|       d{   S 7 w)a  Block until a run is done. Returns the final state of the thread.

        Args:
            thread_id: The thread ID to join.
            run_id: The run ID to join.
            headers: Optional custom headers to include with the request.

        Returns:
            None

        Example Usage:

            result =await client.runs.join(
                thread_id="thread_id_to_join",
                run_id="run_id_to_join"
            )

        rQ  r  /joinr   Nr   r  s       r<   joinzRunsClient.join  s@     * YY]]	{&6 # 
 
 	
 
r  )cancel_on_disconnectr  rF   c               T    | j                   j                  d| d| dd||d|      S )a  Stream output from a run in real-time, until the run is done.
        Output is not buffered, so any output produced before this call will
        not be received here.

        Args:
            thread_id: The thread ID to join.
            run_id: The run ID to join.
            cancel_on_disconnect: Whether to cancel the run when the stream is disconnected.
            stream_mode: The stream mode(s) to use. Must be a subset of the stream modes passed
                when creating the run. Background runs default to having the union of all
                stream modes.
            headers: Optional custom headers to include with the request.

        Returns:
            None

        Example Usage:

            await client.runs.join_stream(
                thread_id="thread_id_to_join",
                run_id="run_id_to_join",
                stream_mode=["values", "debug"]
            )

        rQ  r  /streamGET)r  r  r   r{   r   )r   rS  r  r  r  rF   s         r<   join_streamzRunsClient.join_stream  sF    D yy	{&8(<*    
 	
r>   c               f   K   | j                   j                  d| d| |       d{    y7 w)a  Delete a run.

        Args:
            thread_id: The thread ID to delete.
            run_id: The run ID to delete.
            headers: Optional custom headers to include with the request.

        Returns:
            None

        Example Usage:

            await client.runs.delete(
                thread_id="thread_id_to_delete",
                run_id="run_id_to_delete"
            )

        rQ  r  r   Nr%  r  s       r<   r   zRunsClient.delete  s2     * ii9+VF8DgVVVs   '1/1r;  )(rS  r   r   r   r  r   rY  Optional[Command]r  'Union[StreamMode, Sequence[StreamMode]]r  rB  r  r   r  rD  rr  r  rw  rA  r  #Optional[Union[All, Sequence[str]]]r  r  r  Optional[Sequence[str]]r  Optional[DisconnectMode]r  rA  r  Optional[MultitaskStrategy]r  Optional[IfNotExists]r  Optional[int]rF   r   r   r   )$rS  r   r   r   r  r   rY  r  r  r  r  rB  r  r   r  rD  r  r  r  r  r  r  r  r  r  Optional[OnCompletionBehavior]r  r  r  rA  r  r  rF   r   r   r   )*rS  rA  r   r   r  r   rY  r  r  r  r  rB  r  r   r  rD  rr  r  rw  rA  r  r  r  r  r  r  r  r  r  r  r  rA  r  r  r  r  r  r  rF   r   r   r    rS  r   r   r   r  r   rY  r  r  r  r  rB  r  r   r  rD  r  r  r  r  r  rA  r  r  r  r  r  r  rF   r   r   r    $rS  r   r   r   r  r   rY  r  r  r  r  rB  r  r   r  rD  rr  r  rw  rA  r  r  r  r  r  rA  r  r  r  r  r  r  rF   r   r   r    )&rS  rA  r   r   r  r   rY  r  r  r  r  rB  r  r   r  rD  rr  r  rw  rA  r  r  r  r  r  rA  r  r  r  r  r  r  r  r  rF   r   r   r    )r  list[RunCreate]r   	list[Run])$rS  r   r   r   r  r   rY  r  r  r   r  rD  rr  r  rw  rA  r  r  r  r  r  rA  r  r  r  r  r  r  r  r  r  rB  rF   r   r   !Union[list[dict], dict[str, Any]]) rS  r   r   r   r  r   rY  r  r  r   r  rD  r  r  r  r  r  rA  r  r  r  r  r  r  r  r  r  rB  rF   r   r   r  )&rS  rA  r   r   r  r   rY  r  r  r   r  rD  rr  r  rw  rA  r  r  r  r  r  rA  r  r  r  r  r  r  r  r  r  r  r  rB  rF   r   r   r  )rS  r   r)  rI  r*  rI  rf  zOptional[RunStatus]rF   r   r   	List[Run]rS  r   r  r   rF   r   r   r    rS  r   r  r   r  rB  r  r   rF   r   r   r   rS  r   r  r   rF   r   r   rJ   )rS  r   r  r   r  rB  r  1Optional[Union[StreamMode, Sequence[StreamMode]]]rF   r   r   r   rS  r   r  r   rF   r   r   r   r   r   r   r   r   r   r   r  r  r  rP   rk   r  r  r  r   r   r>   r<   r   r   8  sX
   	  !%%)?G!&#'#'+/'+@D?C1526!%:>/3'+,0+(( (
 ( #( =( ( !( !( )( %( >( =( /(  0!(" #($ 8%(& -'(( %)(* *+(, 
#-( (0  !%%)?G!&#'#'@D?C15268</3!%'+,0'(( (
 ( #( =( ( !( !( >( =( /( 0( 6(  -!(" #($ %%(& *'(( 
#)( (6 !%%)?G!&#'#'+/'+@D?C15268<!%:>/3'+,0-q
 q
 q

 q
 #q
 =q
 q
 !q
 !q
 )q
 %q
 >q
 =q
 /q
  0!q
" 6#q
$ %q
& 8'q
( -)q
* %+q
, *-q
. 
#/q
f  !%%)?G!&#'#'@D?C!%8</3'+,0# 
  # =  ! ! > =  6 -  %!" *#$ 
% (  !%%)?G!&#'#'+/'+@D?C!%:>/3'+,0' 
  # =  ! ! ) % > =   8!" -#$ %%& *'( 
) 6 !%%)?G!&#'#'+/'+@D?C!%:>/38<'+,0)L? L? L?
 L? #L? =L? L? !L? !L? )L? %L? >L? =L? L?  8!L?" -#L?$ 6%L?& %'L?( *)L?* 
+L?\B  !%%)#'#'+/'+@D?C!%26:>/3'+ ,0'00 0
 0 #0 !0 !0 )0 %0 >0 =0 0 00 80  -!0" %#0$ %0& *'0( 
+)0 0,  !%%)#'#'@D?C!%268</3'+ ,0#00 0
 0 #0 !0 !0 >0 =0 0 00 60 -0 %0  !0" *#0$ 
+%0 02 !%%)#'#'+/'+@D?C!%268<:>/3'+ ,0)D D D
 D #D !D !D )D %D >D =D D 0D 6D  8!D" -#D$ %%D& 'D( *)D* 
++DT &*,0&
&
 	&

 &
 $&
 *&
 
&
R SW

&)
7O
	
> *,0$
$
 $

 $
 $
 *$
 
$
N SW

&)
7O
	
< &+IM,0*
*
 *

 #*
 G*
 **
 
#*
Z SWWW&)W7OW	Wr>   r   c            	          e Zd ZdZddZddddddddd	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 ddZddddddddd	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 ddZ	 d	 	 	 	 	 ddZdddd	dd
	 	 	 	 	 	 	 	 	 	 	 ddZy)r   a  Client for managing recurrent runs (cron jobs) in LangGraph.

    A run is a single invocation of an assistant with optional input and config.
    This client allows scheduling recurring runs to occur automatically.

    Example:

        client = get_client()
        cron_job = await client.crons.create_for_thread(
            thread_id="thread_123",
            assistant_id="asst_456",
            schedule="0 9 * * *",
            input={"message": "Daily update"}
        )
    c                    || _         y ry   r   r   http_clients     r<   r   zCronClient.__init__5  	    	r>   Nr  r  r  r  r  r  r  rF   c       	   	        K   ||||||||	d}|
r|
|d<   |j                         D ci c]  \  }}|	|| }}}| j                  j                  d| d||       d{   S c c}}w 7 
w)a  Create a cron job for a thread.

        Args:
            thread_id: the thread ID to run the cron job on.
            assistant_id: The assistant ID or graph name to use for the cron job.
                If using graph name, will default to first assistant created from that graph.
            schedule: The cron schedule to execute this job on.
            input: The input to the graph.
            metadata: Metadata to assign to the cron job runs.
            config: The configuration for the assistant.
            interrupt_before: Nodes to interrupt immediately before they get executed.

            interrupt_after: Nodes to Nodes to interrupt immediately after they get executed.

            webhook: Webhook to call after LangGraph API call is done.
            multitask_strategy: Multitask strategy to use.
                Must be one of 'reject', 'interrupt', 'rollback', or 'enqueue'.
            headers: Optional custom headers to include with the request.

        Returns:
            Run: The cron run.

        Example Usage:

            cron_run = await client.crons.create_for_thread(
                thread_id="my-thread-id",
                assistant_id="agent",
                schedule="27 15 * * *",
                input={"messages": [{"role": "user", "content": "hello!"}]},
                metadata={"name":"my_run"},
                config={"configurable": {"model_name": "openai"}},
                interrupt_before=["node_to_stop_before_1","node_to_stop_before_2"],
                interrupt_after=["node_to_stop_after_1","node_to_stop_after_2"],
                webhook="https://my.fake.webhook.com",
                multitask_strategy="interrupt"
            )

        scheduler  r  r  r   r  r  r  r  NrQ  /runs/cronsr   r  r   rS  r   r  r  r  r  r  r  r  r  rF   r  r  r  s                  r<   create_for_threadzCronClient.create_for_thread8  s     l ! ( 0.	
 ,>G()$+MMOEDAqq}1a4EEYY^^	{+.Wg $ 
 
 	
 F
s    &A-
A%A%(A- A+!A-c       	   	        K   ||||||||d}|	r|	|d<   |j                         D ci c]  \  }}|	|| }}}| j                  j                  d||
       d{   S c c}}w 7 
w)(  Create a cron run.

        Args:
            assistant_id: The assistant ID or graph name to use for the cron job.
                If using graph name, will default to first assistant created from that graph.
            schedule: The cron schedule to execute this job on.
            input: The input to the graph.
            metadata: Metadata to assign to the cron job runs.
            config: The configuration for the assistant.
            interrupt_before: Nodes to interrupt immediately before they get executed.
            interrupt_after: Nodes to Nodes to interrupt immediately after they get executed.
            webhook: Webhook to call after LangGraph API call is done.
            multitask_strategy: Multitask strategy to use.
                Must be one of 'reject', 'interrupt', 'rollback', or 'enqueue'.
            headers: Optional custom headers to include with the request.

        Returns:
            Run: The cron run.

        Example Usage:

            cron_run = client.crons.create(
                assistant_id="agent",
                schedule="27 15 * * *",
                input={"messages": [{"role": "user", "content": "hello!"}]},
                metadata={"name":"my_run"},
                config={"configurable": {"model_name": "openai"}},
                interrupt_before=["node_to_stop_before_1","node_to_stop_before_2"],
                interrupt_after=["node_to_stop_after_1","node_to_stop_after_2"],
                webhook="https://my.fake.webhook.com",
                multitask_strategy="interrupt"
            )

        r  r  Nr  r   r  r   r   r  r  r  r  r  r  r  r  rF   r  r  r  s                 r<   r  zCronClient.create~  s     b ! ( 0.	
 ,>G()$+MMOEDAqq}1a4EEYY^^M^QQQ FQs    &A)
A!A!$A)A'A)c                `   K   | j                   j                  d| |       d{    y7 w)a7  Delete a cron.

        Args:
            cron_id: The cron ID to delete.
            headers: Optional custom headers to include with the request.

        Returns:
            None

        Example Usage:

            await client.crons.delete(
                cron_id="cron_to_delete"
            )

        /runs/crons/r   Nr%  r   cron_idrF   s      r<   r   zCronClient.delete  s,     * iigY7IIIr&  r'  r   r   rS  r)  r*  rF   c                  K   ||||d}|j                         D ci c]  \  }}|	|| }}}| j                  j                  d||       d{   S c c}}w 7 
w)a?  Get a list of cron jobs.

        Args:
            assistant_id: The assistant ID or graph name to search for.
            thread_id: the thread ID to search for.
            limit: The maximum number of results to return.
            offset: The number of results to skip.
            headers: Optional custom headers to include with the request.

        Returns:
            list[Cron]: The list of cron jobs returned by the search,

        Example Usage:

            cron_jobs = await client.crons.search(
                assistant_id="my_assistant_id",
                thread_id="my_thread_id",
                limit=5,
                offset=5,
            )
            print(cron_jobs)

            ----------------------------------------------------------

            [
                {
                    'cron_id': '1ef3cefa-4c09-6926-96d0-3dc97fd5e39b',
                    'assistant_id': 'my_assistant_id',
                    'thread_id': 'my_thread_id',
                    'user_id': None,
                    'payload':
                        {
                            'input': {'start_time': ''},
                            'schedule': '4 * * * *',
                            'assistant_id': 'my_assistant_id'
                        },
                    'schedule': '4 * * * *',
                    'next_run_date': '2024-07-25T17:04:00+00:00',
                    'end_time': None,
                    'created_at': '2024-07-08T06:02:23.073257+00:00',
                    'updated_at': '2024-07-08T06:02:23.073257+00:00'
                }
            ]

        r   rS  r)  r*  N/runs/crons/searchr   r  	r   r   rS  r)  r*  rF   r  r  r  s	            r<   r/  zCronClient.search  sj     n )"	
 %,MMOEDAqq}1a4EEYY^^$8wPW^XXX FXs    A
AA$AAA)r   rz   r   r   rS  r   r   r   r  r   r  r   r  r   r  rD  r  Optional[Union[All, list[str]]]r  r  r  rA  r  rA  rF   r   r   r    r   r   r  r   r  r   r  r   r  rD  r  r  r  r  r  rA  r  rA  rF   r   r   r    ry   r  r   rF   r   r   r   r   rA  rS  rA  r)  rI  r*  rI  rF   r   r   z
list[Cron]	r   r   r   r   r   r  r  r   r/  r   r>   r<   r   r   $  s      !%#'#'<@;?!%,0,0D
D
 D

 D
 D
 !D
 !D
 :D
 9D
 D
 *D
 *D
 
D
V !%#'#'<@;?!%,0,0=R=R 	=R
 =R !=R !=R :=R 9=R =R *=R *=R 
=RD -1JJ *J 
	J4 '+#',0=Y $=Y !	=Y
 =Y =Y *=Y 
=Yr>   r   c                      e Zd ZdZd
dZ	 	 	 d	 	 	 	 	 	 	 	 	 	 	 	 	 ddZddd	 	 	 	 	 	 	 	 	 ddZ	 d	 	 	 	 	 	 	 ddZ	 	 	 	 	 	 d	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 ddZ	 	 	 	 	 	 d	 	 	 	 	 	 	 	 	 	 	 	 	 dd	Z	y)r   a{  Client for interacting with the graph's shared storage.

    The Store provides a key-value storage system for persisting data across graph executions,
    allowing for stateful operations and data sharing across threads.

    Example:

        client = get_client()
        await client.store.put_item(["users", "user123"], "mem-123451342", {"name": "Alice", "score": 100})
    c                    || _         y ry   r   r   s     r<   r   zStoreClient.__init__ 	  r   r>   Nc                  K   |D ]  }d|v st        d| d       |||||d}| j                  j                  dt        |      |       d{    y7 w)a  Store or update an item.

        Args:
            namespace: A list of strings representing the namespace path.
            key: The unique identifier for the item within the namespace.
            value: A dictionary containing the item's data.
            index: Controls search indexing - None (use defaults), False (disable), or list of field paths to index.
            ttl: Optional time-to-live in minutes for the item, or None for no expiration.
            headers: Optional custom headers to include with the request.

        Returns:
            None

        Example Usage:

            await client.store.put_item(
                ["documents", "user123"],
                key="item456",
                value={"title": "My Document", "content": "Hello World"}
            )
        .Invalid namespace label '1'. Namespace labels cannot contain periods ('.').r  keyvalueindexttl/store/itemsr   NrA   r{   r   _provided_vals	r   r  r"  r#  r$  r%  rF   labelr  s	            r<   put_itemzStoreClient.put_item#	  s}     >  	Ee| /w6gh 	 #
 iimm!8'  
 	
 	
s   
AAAAArefresh_ttlrF   c                 K   |D ]  }d|v st        d| d       dj                  |      |d}|||d<   | j                  j                  d||       d{   S 7 w)	a  Retrieve a single item.

        Args:
            key: The unique identifier for the item.
            namespace: Optional list of strings representing the namespace path.
            refresh_ttl: Whether to refresh the TTL on this read operation. If None, uses the store's default behavior.

        Returns:
            Item: The retrieved item.
            headers: Optional custom headers to include with the request.

        Example Usage:

            item = await client.store.get_item(
                ["documents", "user123"],
                key="item456",
            )
            print(item)

            ----------------------------------------------------------------

            {
                'namespace': ['documents', 'user123'],
                'key': 'item456',
                'value': {'title': 'My Document', 'content': 'Hello World'},
                'created_at': '2024-07-30T12:00:00Z',
                'updated_at': '2024-07-30T12:00:00Z'
            }
        r  r  r   r  r"  Nr-  r&  r   rA   r  r{   rk   r   r  r"  r-  rF   r*  r   s          r<   get_itemzStoreClient.get_itemR	  s}     L  	Ee| /w6gh 	
  #xx	23?"$/F=!YY]]>&']RRRRs   
A AA AA c               b   K   | j                   j                  d||d|       d{    y7 w)a  Delete an item.

        Args:
            key: The unique identifier for the item.
            namespace: Optional list of strings representing the namespace path.
            headers: Optional custom headers to include with the request.

        Returns:
            None

        Example Usage:

            await client.store.delete_item(
                ["documents", "user123"],
                key="item456",
            )
        r&  r/  r   Nr%  r   r  r"  rF   s       r<   delete_itemzStoreClient.delete_item	  s7     0 ii(5  
 	
 	
s   %/-/c               ~   K   ||||||d}| j                   j                  dt        |      |       d{   S 7 w)aU  Search for items within a namespace prefix.

        Args:
            namespace_prefix: List of strings representing the namespace prefix.
            filter: Optional dictionary of key-value pairs to filter results.
            limit: Maximum number of items to return (default is 10).
            offset: Number of items to skip before returning results (default is 0).
            query: Optional query for natural language search.
            refresh_ttl: Whether to refresh the TTL on items returned by this search. If None, uses the store's default behavior.
            headers: Optional custom headers to include with the request.

        Returns:
            List[Item]: A list of items matching the search criteria.

        Example Usage:

            items = await client.store.search_items(
                ["documents"],
                filter={"author": "John Doe"},
                limit=5,
                offset=0
            )
            print(items)

            ----------------------------------------------------------------

            {
                "items": [
                    {
                        "namespace": ["documents", "user123"],
                        "key": "item789",
                        "value": {
                            "title": "Another Document",
                            "author": "John Doe"
                        },
                        "created_at": "2024-07-30T12:00:00Z",
                        "updated_at": "2024-07-30T12:00:00Z"
                    },
                    # ... additional items ...
                ]
            }
        namespace_prefixfilterr)  r*  queryr-  /store/items/searchr   Nr{   r   r(  	r   r8  r9  r)  r*  r:  r-  rF   r  s	            r<   search_itemszStoreClient.search_items	  sV     l !1&
 YY^^!( $ 
 
 	
 
s   4=;=c                |   K   |||||d}| j                   j                  dt        |      |       d{   S 7 w)a  List namespaces with optional match conditions.

        Args:
            prefix: Optional list of strings representing the prefix to filter namespaces.
            suffix: Optional list of strings representing the suffix to filter namespaces.
            max_depth: Optional integer specifying the maximum depth of namespaces to return.
            limit: Maximum number of namespaces to return (default is 100).
            offset: Number of namespaces to skip before returning results (default is 0).
            headers: Optional custom headers to include with the request.

        Returns:
            List[List[str]]: A list of namespaces matching the criteria.

        Example Usage:

            namespaces = await client.store.list_namespaces(
                prefix=["documents"],
                max_depth=3,
                limit=10,
                offset=0
            )
            print(namespaces)

            ----------------------------------------------------------------

            [
                ["documents", "user123", "reports"],
                ["documents", "user456", "invoices"],
                ...
            ]
        r:   suffix	max_depthr)  r*  /store/namespacesr   Nr<  r   r:   rA  rB  r)  r*  rF   r  s           r<   list_namespaceszStoreClient.list_namespaces	  sS     R "
 YY^^( $ 
 
 	
 
s   3<:<r;  NNNr"  r   r#  r  r$  z*Optional[Union[Literal[False], list[str]]]r%  r  rF   r   r  Sequence[str]r   r   
r"  r   r  rH  r-  Optional[bool]rF   r   r   r   ry   r"  r   rF   r   r  rH  r   r   Nr'  r   NNNr9  zOptional[dict[str, Any]]r)  rI  r*  rI  r:  rA  r-  rJ  rF   r   r8  rH  r   r#   NNNd   r   Nr:   Optional[List[str]]rA  rQ  rB  r  r)  rI  r*  rI  rF   r   r   r   
r   r   r   r   r   r+  r2  r5  r>  rE  r   r>   r<   r   r   	  s   	 =A!,0-
 	-

 -
 :-
 -
 *-
 -
 
-
j '+,0.S 	.S .S $.S *.S 
.Sj -1
 	

 *
 
 

D ,0#&*,0B
 )	B

 B
 B
 B
 $B
 *B
'B
 
B
L '+&*#',03
#3
 $3
 !	3

 3
 3
 *3
 
3
r>   r   SyncLangGraphClientc           
         | d} t        j                  d      }t        j                  | |t        j                  dddd      t	        ||            }t        |      S )a_  Get a synchronous LangGraphClient instance.

    Args:
        url: The URL of the LangGraph API.
        api_key: The API key. If not provided, it will be read from the environment.
            Precedence:
                1. explicit argument
                2. LANGGRAPH_API_KEY
                3. LANGSMITH_API_KEY
                4. LANGCHAIN_API_KEY
        headers: Optional custom headers
    Returns:
        SyncLangGraphClient: The top-level synchronous client for accessing AssistantsClient,
        ThreadsClient, RunsClient, and CronClient.

    Example:

        from langgraph_sdk import get_sync_client

        # get top-level synchronous LangGraphClient
        client = get_sync_client(url="http://localhost:8123")

        # example usage: client.<model>.<method_name>()
        assistant = client.assistants.get(assistant_id="some_uuid")
    r\   r]   r^   r`   ra   rf   )rl   HTTPTransportClientrt   rG   rS  )rU   r9   rF   rh   ru   s        r<   get_sync_clientrW  
  s\    @ {%##A.I\\ac1EGW-	F v&&r>   c                      e Zd ZdZddZy)rS  a7  Synchronous client for interacting with the LangGraph API.

    This class provides synchronous access to LangGraph API endpoints for managing
    assistants, threads, runs, cron jobs, and data storage.

    Example:

        client = get_sync_client()
        assistant = client.assistants.get("asst_123")
    c                (   t        |      | _        t        | j                        | _        t	        | j                        | _        t        | j                        | _        t        | j                        | _	        t        | j                        | _        y ry   )SyncHttpClientr{   SyncAssistantsClientr}   SyncThreadsClientr   SyncRunsClientr   SyncCronClientr   SyncStoreClientr   r   s     r<   r   zSyncLangGraphClient.__init__S
  s^    "6*	.tyy9(3"499-	#DII.
$TYY/
r>   Nru   zhttpx.Clientr   r   r   r   r>   r<   rS  rS  G
  s    	0r>   c                      e Zd ZddZddd	 	 	 	 	 	 	 ddZdd	 	 	 	 	 	 	 ddZdd	 	 	 	 	 	 	 ddZdd	 	 	 	 	 	 	 ddZddd		 	 	 	 	 	 	 dd
Zdddd	 	 	 	 	 	 	 	 	 	 	 ddZ	y)rZ  c                    || _         y ry   r   r   s     r<   r   zSyncHttpClient.__init__]
  r   r>   Nr   c               l   | j                   j                  |||      }	 |j                          t        |      S # t        j                  $ re}|j                         j                         }t        j                  dk\  r|j                  |       |t        j                  d| |       |d}~ww xY w)r   r   r   r   r   N)ru   rk   r   rl   r   rc   r   r   r   r   r   r   decode_jsonr   s          r<   rk   zSyncHttpClient.get`
  s     KKOODOA	  1~ $$ 	668??$D7*

4  G 9$@1MG	s   ; B3A B..B3r   c                  |t        |      \  }}ni d}}|r|j                  |       | j                  j                  |||      }	 |j	                          t        |      S # t
        j                  $ re}|j                         j                         }t        j                  dk\  r|j                  |       |t        j                  d| |       |d}~ww xY wr   )encode_jsonr   ru   r   r   rl   r   rc   r   r   r   r   r   r   rd  r   s	            r<   r   zSyncHttpClient.postt
  s     '24'8$OW')3WO""7+KKT?GL	  1~ $$ 	668??$D7*

4  G 9$@1MG	s   A# #C6A CCc                  t        |      \  }}|r|j                  |       | j                  j                  |||      }	 |j	                          t        |      S # t
        j                  $ re}|j                         j                         }t        j                  dk\  r|j                  |       |t        j                  d| |       |d}~ww xY w)r   r   r   r   r   N)rf  r   ru   r   r   rl   r   rc   r   r   r   r   r   r   rd  r   s	            r<   r   zSyncHttpClient.put
  s     $/t#4 ""7+KKOOD/7OK	  1~ $$ 	668??$D7*

4  G 9$@1MG	   A C/A CCc                  t        |      \  }}|r|j                  |       | j                  j                  |||      }	 |j	                          t        |      S # t
        j                  $ re}|j                         j                         }t        j                  dk\  r|j                  |       |t        j                  d| |       |d}~ww xY w)r   r   r   r   r   N)rf  r   ru   r   r   rl   r   rc   r   r   r   r   r   r   rd  r   s	            r<   r   zSyncHttpClient.patch
  s     $/t#4 ""7+KKdOWM	  1~ $$ 	668??$D7*

4  G 9$@1MG	rh  r   c               Z   | j                   j                  d|||      }	 |j                          y# t        j                  $ re}|j                         j                         }t        j                  dk\  r|j                  |       |t        j                  d| |       |d}~ww xY w)r   r   r   r   r   r   N)ru   r   r   rl   r   rc   r   r   r   r   r   r   r   s          r<   r   zSyncHttpClient.delete
  s     KK$T7K	 $$ 	668??$D7*

4  G 9$@1MG	s   2 B*A B%%B*r   c             #    K   t        |      \  }}d|d<   d|d<   |r|j                  |       | j                  j                  |||||      5 }	 |j	                          |j                  j                  d
d      j!                  d      d   }d|vrt        j"                  d|      t%               }t'        |      D ])  }|j                  |j)                  d            }|&| + 	 d	d	d	       y	# t
        j                  $ re}	|j                         j                         }
t        j                  dk\  r|	j                  |
       |	t        j                  d|
 |	       |	d	}	~	ww xY w# 1 sw Y   y	xY ww)z*Stream the results of a request using SSE.r   r   r   r   r   r   r   r   Nr   r   r   r   r   r   )rf  r   ru   r   r   rl   r   rc   r   r   r   r   r   r   rF   rk   r   r   r+   r-   r   r   s                  r<   r   zSyncHttpClient.stream
  s     $/t#4 $7!+5(""7+[[D/76   
 	$$& ;;??>2>HHMaPL",6**'*, 
 !lG&s+ nnT[[%78?I-	 	 (( 
**,##w.JJt$  LL#=dV!DqLQ	 	sJ   AE<E0C5 BE0%E0,	E<5E-A E((E--E00E95E<r`  r   r   r   r   )r   r   r   r   r   r   r   r   rF   r   r   Iterator[StreamPart])
r   r   r   r   rk   r   r   r   r   r   r   r>   r<   rZ  rZ  \
  s?    -1,0 *	
 * 
2 -1 	
 * 
6 MQ"&1I	* MQ"&1I	. #,0 	
 * 
0  $,0,0(( (
 ( *( *( 
(r>   rZ  c                    t        j                  | t        t         j                  t         j                  z        }t        t        |            }d}||d}||fS r   )r   r   rT   r   r   r   r   r   s        r<   rf  rf  
  sR    <<""V%<%<<D
 T^N%L!/NGD=r>   c                T    | j                         }|rt        j                  |      S d S ry   )rc   r   r   r   s     r<   rd  rd  
  s#    668D!%6<</4/r>   c                     e Zd ZdZddZdd	 	 	 	 	 ddZddd	 	 	 	 	 	 	 ddZdd	 	 	 	 	 dd	Z	 	 ddd	 	 	 	 	 	 	 	 	 dd
Z	 dddddddd	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 ddZ	ddddddd	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 ddZ
dd	 	 	 	 	 ddZdddddd	 	 	 	 	 	 	 	 	 	 	 d dZ	 	 	 d!dd	 	 	 	 	 	 	 	 	 	 	 d"dZdd	 	 	 	 	 	 	 d#dZy)$r[  a  Client for managing assistants in LangGraph synchronously.

    This class provides methods to interact with assistants, which are versioned configurations of your graph.

    Example:

        client = get_client()
        assistant = client.assistants.get("assistant_id_123")
    c                    || _         y ry   r   r   s     r<   r   zSyncAssistantsClient.__init__  r   r>   Nr   c               B    | j                   j                  d| |      S )a  Get an assistant by ID.

        Args:
            assistant_id: The ID of the assistant to get.
            headers: Optional custom headers to include with the request.

        Returns:
            Assistant: Assistant Object.

        Example Usage:

            assistant = client.assistants.get(
                assistant_id="my_assistant_id"
            )
            print(assistant)

            ----------------------------------------------------

            {
                'assistant_id': 'my_assistant_id',
                'graph_id': 'agent',
                'created_at': '2024-06-25T17:10:33.109781+00:00',
                'updated_at': '2024-06-25T17:10:33.109781+00:00',
                'config': {},
                'metadata': {'created_by': 'system'}
            }

        r   r   r   r   s      r<   rk   zSyncAssistantsClient.get  s#    D yy}}|L>:G}LLr>   Fr  c               J    | j                   j                  d| dd|i|      S )aa  Get the graph of an assistant by ID.

        Args:
            assistant_id: The ID of the assistant to get the graph of.
            xray: Include graph representation of subgraphs. If an integer value is provided, only subgraphs with a depth less than or equal to the value will be included.
            headers: Optional custom headers to include with the request.

        Returns:
            Graph: The graph information for the assistant in JSON format.

        Example Usage:

            graph_info = client.assistants.get_graph(
                assistant_id="my_assistant_id"
            )
            print(graph_info)

            --------------------------------------------------------------------------------------------------------------------------

            {
                'nodes':
                    [
                        {'id': '__start__', 'type': 'schema', 'data': '__start__'},
                        {'id': '__end__', 'type': 'schema', 'data': '__end__'},
                        {'id': 'agent','type': 'runnable','data': {'id': ['langgraph', 'utils', 'RunnableCallable'],'name': 'agent'}},
                    ],
                'edges':
                    [
                        {'source': '__start__', 'target': 'agent'},
                        {'source': 'agent','target': '__end__'}
                    ]
            }


        r   r  r  r   r   r  s       r<   r  zSyncAssistantsClient.get_graph6  s4    T yy}}<./PW  
 	
r>   c               D    | j                   j                  d| d|      S )a  Get the schemas of an assistant by ID.

        Args:
            assistant_id: The ID of the assistant to get the schema of.
            headers: Optional custom headers to include with the request.

        Returns:
            GraphSchema: The graph schema for the assistant.

        Example Usage:

            schema = client.assistants.get_schemas(
                assistant_id="my_assistant_id"
            )
            print(schema)

            ----------------------------------------------------------------------------------------------------------------------------

            {
                'graph_id': 'agent',
                'state_schema':
                    {
                        'title': 'LangGraphInput',
                        '$ref': '#/definitions/AgentState',
                        'definitions':
                            {
                                'BaseMessage':
                                    {
                                        'title': 'BaseMessage',
                                        'description': 'Base abstract Message class. Messages are the inputs and outputs of ChatModels.',
                                        'type': 'object',
                                        'properties':
                                            {
                                             'content':
                                                {
                                                    'title': 'Content',
                                                    'anyOf': [
                                                        {'type': 'string'},
                                                        {'type': 'array','items': {'anyOf': [{'type': 'string'}, {'type': 'object'}]}}
                                                    ]
                                                },
                                            'additional_kwargs':
                                                {
                                                    'title': 'Additional Kwargs',
                                                    'type': 'object'
                                                },
                                            'response_metadata':
                                                {
                                                    'title': 'Response Metadata',
                                                    'type': 'object'
                                                },
                                            'type':
                                                {
                                                    'title': 'Type',
                                                    'type': 'string'
                                                },
                                            'name':
                                                {
                                                    'title': 'Name',
                                                    'type': 'string'
                                                },
                                            'id':
                                                {
                                                    'title': 'Id',
                                                    'type': 'string'
                                                }
                                            },
                                        'required': ['content', 'type']
                                    },
                                'AgentState':
                                    {
                                        'title': 'AgentState',
                                        'type': 'object',
                                        'properties':
                                            {
                                                'messages':
                                                    {
                                                        'title': 'Messages',
                                                        'type': 'array',
                                                        'items': {'$ref': '#/definitions/BaseMessage'}
                                                    }
                                            },
                                        'required': ['messages']
                                    }
                            }
                    },
                'config_schema':
                    {
                        'title': 'Configurable',
                        'type': 'object',
                        'properties':
                            {
                                'model_name':
                                    {
                                        'title': 'Model Name',
                                        'enum': ['anthropic', 'openai'],
                                        'type': 'string'
                                    }
                            }
                    }
            }

        r   r
  r   r   r   s      r<   r  z SyncAssistantsClient.get_schemasd  s%    Z yy}}|L>BG}TTr>   c                   |&| j                   j                  d| d| d|i|      S | j                   j                  d| dd|i|      S )a  Get the schemas of an assistant by ID.

        Args:
            assistant_id: The ID of the assistant to get the schema of.
            headers: Optional custom headers to include with the request.

        Returns:
            Subgraphs: The graph schema for the assistant.

        r   r  r  r   r  r   r  s        r<   r  z"SyncAssistantsClient.get_subgraphs  sr    $  99==|nK	{C!7+ !   99==|nJ7!7+ !  r>   r  c                   d|i}	|r||	d<   |r||	d<   |r||	d<   |r||	d<   |r||	d<   |r||	d<   | j                   j                  d|	|	      S )
a  Create a new assistant.

        Useful when graph is configurable and you want to create different assistants based on different configurations.

        Args:
            graph_id: The ID of the graph the assistant should use. The graph ID is normally set in your langgraph.json configuration.
            config: Configuration to use for the graph.
            metadata: Metadata to add to assistant.
            assistant_id: Assistant ID to use, will default to a random UUID if not provided.
            if_exists: How to handle duplicate creation. Defaults to 'raise' under the hood.
                Must be either 'raise' (raise error if duplicate), or 'do_nothing' (return existing assistant).
            name: The name of the assistant. Defaults to 'Untitled' under the hood.
            headers: Optional custom headers to include with the request.
            description: Optional description of the assistant.
                The description field is available for langgraph-api server version>=0.0.45

        Returns:
            Assistant: The created assistant.

        Example Usage:

            assistant = client.assistants.create(
                graph_id="agent",
                config={"configurable": {"model_name": "openai"}},
                metadata={"number":1},
                assistant_id="my-assistant-id",
                if_exists="do_nothing",
                name="my_name"
            )
        r  r  r  r   r  r  r  r  r   r  r  s
             r<   r  zSyncAssistantsClient.create  sy    V #
  &GH"*GJ&2GN##,GK "GFO%0GM"yy~~m'7~KKr>   r   c                   i }|r||d<   |r||d<   |r||d<   |r||d<   |r||d<   | j                   j                  d| ||      S )a  Update an assistant.

        Use this to point to a different graph, update the configuration, or change the metadata of an assistant.

        Args:
            assistant_id: Assistant to update.
            graph_id: The ID of the graph the assistant should use.
                The graph ID is normally set in your langgraph.json configuration. If None, assistant will keep pointing to same graph.
            config: Configuration to use for the graph.
            metadata: Metadata to merge with existing assistant metadata.
            name: The new name for the assistant.
            headers: Optional custom headers to include with the request.
            description: Optional description of the assistant.
                The description field is available for langgraph-api server version>=0.0.45

        Returns:
            Assistant: The updated assistant.

        Example Usage:

            assistant = client.assistants.update(
                assistant_id='e280dad7-8618-443f-87f1-8e41841c180f',
                graph_id="other-graph",
                config={"configurable": {"model_name": "anthropic"}},
                metadata={"number":2}
            )

        r  r  r  r  r  r   r   r"  r#  s	            r<   r   zSyncAssistantsClient.update-  st    N #%"*GJ &GH"*GJ"GFO%0GM"yy<.)  
 	
r>   c               D    | j                   j                  d| |       y)aL  Delete an assistant.

        Args:
            assistant_id: The assistant ID to delete.
            headers: Optional custom headers to include with the request.

        Returns:
            None

        Example Usage:

            client.assistants.delete(
                assistant_id="my_assistant_id"
            )

        r   r   Nr%  r   s      r<   r   zSyncAssistantsClient.deletee  s"    , 			<~6Hr>   r'  r   r(  c               d    ||d}|r||d<   |r||d<   | j                   j                  d||      S )a  Search for assistants.

        Args:
            metadata: Metadata to filter by. Exact match filter for each KV pair.
            graph_id: The ID of the graph to filter by.
                The graph ID is normally set in your langgraph.json configuration.
            limit: The maximum number of results to return.
            offset: The number of results to skip.
            headers: Optional custom headers to include with the request.

        Returns:
            list[Assistant]: A list of assistants.

        Example Usage:

            assistants = client.assistants.search(
                metadata = {"name":"my_name"},
                graph_id="my_graph_id",
                limit=5,
                offset=5
            )
        r,  r  r  r-  r   r  r.  s          r<   r/  zSyncAssistantsClient.search}  sQ    @ #
 "*GJ"*GJyy~~   
 	
r>   c               ^    ||d}|r||d<   | j                   j                  d| d||      S )as  List all versions of an assistant.

        Args:
            assistant_id: The assistant ID to get versions for.
            metadata: Metadata to filter versions by. Exact match filter for each KV pair.
            limit: The maximum number of versions to return.
            offset: The number of versions to skip.
            headers: Optional custom headers to include with the request.

        Returns:
            list[Assistant]: A list of assistants.

        Example Usage:

            assistant_versions = await client.assistants.get_versions(
                assistant_id="my_assistant_id"
            )

        r,  r  r   r1  r   r  r2  s          r<   r3  z!SyncAssistantsClient.get_versions  sJ    < #
 "*GJyy~~<.	2'  
 	
r>   c               N    d|i}| j                   j                  d| d||      S )r6  r7  r   r8  r   r  r9  s        r<   r:  zSyncAssistantsClient.set_latest  s8    4 $-g"6yy~~<.0w  
 	
r>   r{   rZ  r   r   r<  r=  r>  r?  r@  ry   rC  rF  rG  rH  rJ  rK  rL  rM  r   r>   r<   r[  r[    s    -1	"M"M *	"M
 
"MP "',0,
,
 	,

 *,
 
),
d -1	mUmU *	mU
 
mUd $(	 -1 ! 	 * 
D $(9L
 &*26",0%)9L9L !9L
 9L $9L 09L 9L *9L #9L 
9L~ #'#'",0%)6
6
  	6

 !6
 6
 6
 *6
 #6
 
6
x -1	II *	I
 
I6 "&,0+
 +
  	+

 +
 +
 *+
 
+
` %
 -1%
%
 %
 	%

 %
 *%
 
 %
X -1

 

 *
 

r>   r[  c                  j   e Zd ZdZddZdd	 	 	 	 	 ddZddddddd	 	 	 	 	 	 	 	 	 	 	 	 	 ddZdd	 	 	 	 	 	 	 ddZdd	 	 	 	 	 dd	Zdddd
ddd	 	 	 	 	 	 	 	 	 	 	 	 	 ddZ	dd	 	 	 	 	 ddZ
	 	 dddd	 	 	 	 	 	 	 	 	 	 	 ddZddddd	 	 	 	 	 	 	 	 	 	 	 	 	 ddZd
ddddd	 	 	 	 	 	 	 	 	 	 	 	 	 ddZy) r\  a6  Synchronous client for managing threads in LangGraph.

    This class provides methods to create, retrieve, and manage threads,
    which represent conversations or stateful interactions.

    Example:

        client = get_sync_client()
        thread = client.threads.create(metadata={"user_id": "123"})
    c                    || _         y ry   r   r   s     r<   r   zSyncThreadsClient.__init__  r   r>   Nr   c               B    | j                   j                  d| |      S )a  Get a thread by ID.

        Args:
            thread_id: The ID of the thread to get.
            headers: Optional custom headers to include with the request.

        Returns:
            Thread: Thread object.

        Example Usage:

            thread = client.threads.get(
                thread_id="my_thread_id"
            )
            print(thread)

            -----------------------------------------------------

            {
                'thread_id': 'my_thread_id',
                'created_at': '2024-07-18T18:35:15.540834+00:00',
                'updated_at': '2024-07-18T18:35:15.540834+00:00',
                'metadata': {'graph_id': 'agent'}
            }

        rQ  r   r   rR  s      r<   rk   zSyncThreadsClient.get  s#    B yy}}y4g}FFr>   rT  c               (   i }|r||d<   |s|ri |xs i |rd|ini |d<   |r||d<   |rA|D 	cg c]0  }d|d   D 	cg c]  }	|	d   |	j                  d      |	d   d	 c}	i2 c}	}|d
<   | j                  j                  d||      S c c}	w c c}	}w )a  Create a new thread.

        Args:
            metadata: Metadata to add to thread.
            thread_id: ID of thread.
                If None, ID will be a randomly generated UUID.
            if_exists: How to handle duplicate creation. Defaults to 'raise' under the hood.
                Must be either 'raise' (raise error if duplicate), or 'do_nothing' (return existing thread).
            supersteps: Apply a list of supersteps when creating a thread, each containing a sequence of updates.
                Each update has `values` or `command` and `as_node`. Used for copying a thread between deployments.
            graph_id: Optional graph ID to associate with the thread.
            headers: Optional custom headers to include with the request.

        Returns:
            Thread: The created thread.

        Example Usage:

            thread = client.threads.create(
                metadata={"number":1},
                thread_id="my-thread-id",
                if_exists="raise"
            )
        rS  r  r  r  rW  rX  rY  rZ  r[  rU  r\  r   r]  r^  s
             r<   r  zSyncThreadsClient.create$  s    D #%#,GK x#>r#-5J)2#GJ #,GK  $%   "#9  	 '(k'(uuY'7'(| 	%GL! yy~~jw~HH %s   B"B	B	Bc               H    | j                   j                  d| d|i|      S )a  Update a thread.

        Args:
            thread_id: ID of thread to update.
            metadata: Metadata to merge with existing thread metadata.
            headers: Optional custom headers to include with the request.

        Returns:
            Thread: The created thread.

        Example Usage:

            thread = client.threads.update(
                thread_id="my-thread-id",
                metadata={"number":1},
            )
        rQ  r  r   r"  rb  s       r<   r   zSyncThreadsClient.updatea  s1    0 yy	{#:x*@'  
 	
r>   c               D    | j                   j                  d| |       y)a@  Delete a thread.

        Args:
            thread_id: The ID of the thread to delete.
            headers: Optional custom headers to include with the request.

        Returns:
            None

        Example Usage:

            client.threads.delete(
                thread_id="my_thread_id"
            )

        rQ  r   Nr%  rR  s      r<   r   zSyncThreadsClient.delete}  s"    , 			9YK0'Br>   r'  r   re  c               r    ||d}|r||d<   |r||d<   |r||d<   | j                   j                  d||      S )a  Search for threads.

        Args:
            metadata: Thread metadata to filter on.
            values: State values to filter on.
            status: Thread status to filter on.
                Must be one of 'idle', 'busy', 'interrupted' or 'error'.
            limit: Limit on number of threads to return.
            offset: Offset in threads table to start search from.
            headers: Optional custom headers to include with the request.

        Returns:
            list[Thread]: List of the threads matching the search parameters.

        Example Usage:

            threads = client.threads.search(
                metadata={"number":1},
                status="interrupted",
                limit=15,
                offset=5
            )

        r,  r  rX  rf  rh  r   r  ri  s           r<   r/  zSyncThreadsClient.search  sU    F #
 "*GJ &GH &GHyy~~/gw~OOr>   c               F    | j                   j                  d| dd|      S )a:  Copy a thread.

        Args:
            thread_id: The ID of the thread to copy.
            headers: Optional custom headers to include with the request.

        Returns:
            None

        Example Usage:

            client.threads.copy(
                thread_id="my_thread_id"
            )

        rQ  rk  Nr   r  rR  s      r<   rl  zSyncThreadsClient.copy  s&    , yy~~	)E:w~WWr>   Frm  c                   |r%| j                   j                  d| d||d|      S |r&| j                   j                  d| d| d|i|      S | j                   j                  d| dd|i|      S )	a  Get the state of a thread.

        Args:
            thread_id: The ID of the thread to get the state of.
            checkpoint: The checkpoint to get the state of.
            subgraphs: Include subgraphs states.
            headers: Optional custom headers to include with the request.

        Returns:
            ThreadState: the thread of the state.

        Example Usage:

            thread_state = client.threads.get_state(
                thread_id="my_thread_id",
                checkpoint_id="my_checkpoint_id"
            )
            print(thread_state)

            ----------------------------------------------------------------------------------------------------------------------------------------------------------------------

            {
                'values': {
                    'messages': [
                        {
                            'content': 'how are you?',
                            'additional_kwargs': {},
                            'response_metadata': {},
                            'type': 'human',
                            'name': None,
                            'id': 'fe0a5778-cfe9-42ee-b807-0adaa1873c10',
                            'example': False
                        },
                        {
                            'content': "I'm doing well, thanks for asking! I'm an AI assistant created by Anthropic to be helpful, honest, and harmless.",
                            'additional_kwargs': {},
                            'response_metadata': {},
                            'type': 'ai',
                            'name': None,
                            'id': 'run-159b782c-b679-4830-83c6-cef87798fe8b',
                            'example': False,
                            'tool_calls': [],
                            'invalid_tool_calls': [],
                            'usage_metadata': None
                        }
                    ]
                },
                'next': [],
                'checkpoint':
                    {
                        'thread_id': 'e2496803-ecd5-4e0c-a779-3226296181c2',
                        'checkpoint_ns': '',
                        'checkpoint_id': '1ef4a9b8-e6fb-67b1-8001-abd5184439d1'
                    }
                'metadata':
                    {
                        'step': 1,
                        'run_id': '1ef4a9b8-d7da-679a-a45a-872054341df2',
                        'source': 'loop',
                        'writes':
                            {
                                'agent':
                                    {
                                        'messages': [
                                            {
                                                'id': 'run-159b782c-b679-4830-83c6-cef87798fe8b',
                                                'name': None,
                                                'type': 'ai',
                                                'content': "I'm doing well, thanks for asking! I'm an AI assistant created by Anthropic to be helpful, honest, and harmless.",
                                                'example': False,
                                                'tool_calls': [],
                                                'usage_metadata': None,
                                                'additional_kwargs': {},
                                                'response_metadata': {},
                                                'invalid_tool_calls': []
                                            }
                                        ]
                                    }
                            },
                'user_id': None,
                'graph_id': 'agent',
                'thread_id': 'e2496803-ecd5-4e0c-a779-3226296181c2',
                'created_by': 'system',
                'assistant_id': 'fe096781-5601-53d2-b2f6-0d3403f7e9ca'},
                'created_at': '2024-07-25T15:35:44.184703+00:00',
                'parent_config':
                    {
                        'thread_id': 'e2496803-ecd5-4e0c-a779-3226296181c2',
                        'checkpoint_ns': '',
                        'checkpoint_id': '1ef4a9b8-d80d-6fa7-8000-9300467fad0f'
                    }
            }

        rQ  rp  rq  r   rs  rn  r   rt  ru  rv  s         r<   rx  zSyncThreadsClient.get_state  s    N 99>>I;&78$.YG "  
 99==I;gm_=#Y/ !   99==I;f-#Y/ !  r>   ry  c               x    d|i}|r||d<   |r||d<   |r||d<   | j                   j                  d| d||      S )a  Update the state of a thread.

        Args:
            thread_id: The ID of the thread to update.
            values: The values to update the state with.
            as_node: Update the state as if this node had just executed.
            checkpoint: The checkpoint to update the state of.
            headers: Optional custom headers to include with the request.

        Returns:
            ThreadUpdateStateResponse: Response after updating a thread's state.

        Example Usage:

            response = await client.threads.update_state(
                thread_id="my_thread_id",
                values={"messages":[{"role": "user", "content": "hello!"}]},
                as_node="my_node",
            )
            print(response)

            ----------------------------------------------------------------------------------------------------------------------------------------------------------------------

            {
                'checkpoint': {
                    'thread_id': 'e2496803-ecd5-4e0c-a779-3226296181c2',
                    'checkpoint_ns': '',
                    'checkpoint_id': '1ef4a9b8-e6fb-67b1-8001-abd5184439d1',
                    'checkpoint_map': {}
                }
            }

        rX  rw  rr  rZ  rQ  rt  r   r  r{  s           r<   r|  zSyncThreadsClient.update_stateU  sd    X f#
 '4GO$$.GL!!(GIyy~~	{&)  
 	
r>   r~  c               x    d|i}|r||d<   |r||d<   |r||d<   | j                   j                  d| d||      S )a  Get the state history of a thread.

        Args:
            thread_id: The ID of the thread to get the state history for.
            checkpoint: Return states for this subgraph. If empty defaults to root.
            limit: The maximum number of states to return.
            before: Return states before this checkpoint.
            metadata: Filter states by metadata key-value pairs.
            headers: Optional custom headers to include with the request.

        Returns:
            list[ThreadState]: the state history of the thread.

        Example Usage:

            thread_state = client.threads.get_history(
                thread_id="my_thread_id",
                limit=5,
                before="my_timestamp",
                metadata={"name":"my_name"}
            )

        r)  r  r  rr  rQ  r  r   r  r  s           r<   r  zSyncThreadsClient.get_history  sd    D U#
  &GH"*GJ$.GL!yy~~	{(+'7  
 	
r>   r{  r  r  r  r  r  r  r  r  r  r  r   r>   r<   r\  r\    s   	 -1	!G!G *	!G
 
!GL #'26NR"&,0;I ;I !	;I
 0;I L;I  ;I *;I 
;ID -1

 !	

 *
 

@ -1	CC *	C
 
C6 )-,0,P ,P 	,P
 ',P ,P ,P *,P 
,Pd -1	XX *	X
 
X6 ,0'+	x  ,0xx )x %	x x *x 
x~ "&+/'+,06
6
 66

 6
 )6
 %6
 *6
 
#6
x -1#'+/,0,
,
 	,

 +,
 !,
 ),
 *,
 
,
r>   r\  c                  $   e Zd ZdZd&dZedddddddddddddddddd	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d'd       Zedddddddddddddddd	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d(d	       Zddddddddddddddddddd
	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d)dZedddddddddddddd	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d*d       Zedddddddddddddddd	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d+d       Zddddddddddddddddd	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d,dZdd	 	 	 	 	 d-dZeddddddddddddddd	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d.d       Z	eddddddddddddd	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d/d       Z	dddddddddddddddd	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d0dZ	dddd	 	 	 	 	 	 	 	 	 d1dZ
dd	 	 	 	 	 	 	 d2dZdddd 	 	 	 	 	 	 	 	 	 	 	 d3d!Zdd	 	 	 	 	 	 	 d4d"Zdddd#	 	 	 	 	 	 	 	 	 	 	 d5d$Zdd	 	 	 	 	 	 	 d6d%Zy)7r]  a7  Synchronous client for managing runs in LangGraph.

    This class provides methods to create, retrieve, and manage runs, which represent
    individual executions of graphs.

    Example:

        client = get_sync_client()
        run = client.runs.create(thread_id="thread_123", assistant_id="asst_456")
    c                    || _         y ry   r   r   s     r<   r   zSyncRunsClient.__init__  r   r>   NrX  Fr  c                    y ry   r   r  s                       r<   r   zSyncRunsClient.stream  s    .  #r>   r  c                    y ry   r   r  s                     r<   r   zSyncRunsClient.stream  s    *  #r>   r  c          
     z   i d|d|r'|j                         D ci c]  \  }}|	|| c}}ndd|d|d|d|d|d	|d
|d|d|d|	d|
d|d|d|d|d|i}|d| dnd}| j                  j                  |d|j                         D ci c]  \  }}|	|| c}}|      S c c}}w c c}}w )a`  Create a run and stream the results.

        Args:
            thread_id: the thread ID to assign to the thread.
                If None will create a stateless run.
            assistant_id: The assistant ID or graph name to stream from.
                If using graph name, will default to first assistant created from that graph.
            input: The input to the graph.
            command: The command to execute.
            stream_mode: The stream mode(s) to use.
            stream_subgraphs: Whether to stream output from subgraphs.
            metadata: Metadata to assign to the run.
            config: The configuration for the assistant.
            checkpoint: The checkpoint to resume from.
            interrupt_before: Nodes to interrupt immediately before they get executed.
            interrupt_after: Nodes to Nodes to interrupt immediately after they get executed.
            feedback_keys: Feedback keys to assign to run.
            on_disconnect: The disconnect mode to use.
                Must be one of 'cancel' or 'continue'.
            on_completion: Whether to delete or keep the thread created for a stateless run.
                Must be one of 'delete' or 'keep'.
            webhook: Webhook to call after LangGraph API call is done.
            multitask_strategy: Multitask strategy to use.
                Must be one of 'reject', 'interrupt', 'rollback', or 'enqueue'.
            if_not_exists: How to handle missing thread. Defaults to 'reject'.
                Must be either 'reject' (raise error if missing), or 'create' (create new thread).
            after_seconds: The number of seconds to wait before starting the run.
                Use to schedule future runs.
            headers: Optional custom headers to include with the request.

        Returns:
            Iterator[StreamPart]: Iterator of stream results.

        Example Usage:

            async for chunk in client.runs.stream(
                thread_id=None,
                assistant_id="agent",
                input={"messages": [{"role": "user", "content": "how are you?"}]},
                stream_mode=["values","debug"],
                metadata={"name":"my_run"},
                config={"configurable": {"model_name": "anthropic"}},
                interrupt_before=["node_to_stop_before_1","node_to_stop_before_2"],
                interrupt_after=["node_to_stop_after_1","node_to_stop_after_2"],
                feedback_keys=["my_feedback_key_1","my_feedback_key_2"],
                webhook="https://my.fake.webhook.com",
                multitask_strategy="interrupt"
            ):
                print(chunk)

            ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

            StreamPart(event='metadata', data={'run_id': '1ef4a9b8-d7da-679a-a45a-872054341df2'})
            StreamPart(event='values', data={'messages': [{'content': 'how are you?', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': 'fe0a5778-cfe9-42ee-b807-0adaa1873c10', 'example': False}]})
            StreamPart(event='values', data={'messages': [{'content': 'how are you?', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': 'fe0a5778-cfe9-42ee-b807-0adaa1873c10', 'example': False}, {'content': "I'm doing well, thanks for asking! I'm an AI assistant created by Anthropic to be helpful, honest, and harmless.", 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-159b782c-b679-4830-83c6-cef87798fe8b', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}]})
            StreamPart(event='end', data=None)

        r  rY  Nr  r  r  r  r   r  r  r  r  rr  rw  r  r  r  r  r  rQ  r  r  r   r  r  s                            r<   r   zSyncRunsClient.stream  su   d
U
GN'--/C$!QQ]ACTX

 f
 
 ;
  0
 L
  0
 
 ]
 w
 *
 ]
  !"4!
" ]#
$ ]%
& ]'
( ])
0 $ 	{,/ 	
 yy#*==?D41aam!Q$D	   
 	
1 D6 Er  r  c                    y ry   r   r  s                   r<   r  zSyncRunsClient.createo  s    & r>   r  c                    y ry   r   r  s                     r<   r  zSyncRunsClient.create  s    * r>   )r  rY  r  r  r  r  rr  rw  r  r  r  r  r  r  r  rF   c                  i d|d|r'|j                         D ci c]  \  }}|	|| c}}ndd|d|d|d|d|d	|d
|d|d|	d|
d|d|d|d|}|j                         D ci c]  \  }}|	|| }}}|r"| j                  j                  d| d||      S | j                  j                  d||      S c c}}w c c}}w )a  Create a background run.

        Args:
            thread_id: the thread ID to assign to the thread.
                If None will create a stateless run.
            assistant_id: The assistant ID or graph name to stream from.
                If using graph name, will default to first assistant created from that graph.
            input: The input to the graph.
            command: The command to execute.
            stream_mode: The stream mode(s) to use.
            stream_subgraphs: Whether to stream output from subgraphs.
            metadata: Metadata to assign to the run.
            config: The configuration for the assistant.
            checkpoint: The checkpoint to resume from.
            interrupt_before: Nodes to interrupt immediately before they get executed.
            interrupt_after: Nodes to Nodes to interrupt immediately after they get executed.
            webhook: Webhook to call after LangGraph API call is done.
            multitask_strategy: Multitask strategy to use.
                Must be one of 'reject', 'interrupt', 'rollback', or 'enqueue'.
            on_completion: Whether to delete or keep the thread created for a stateless run.
                Must be one of 'delete' or 'keep'.
            if_not_exists: How to handle missing thread. Defaults to 'reject'.
                Must be either 'reject' (raise error if missing), or 'create' (create new thread).
            after_seconds: The number of seconds to wait before starting the run.
                Use to schedule future runs.
            headers: Optional custom headers to include with the request.

        Returns:
            Run: The created background run.

        Example Usage:

            background_run = client.runs.create(
                thread_id="my_thread_id",
                assistant_id="my_assistant_id",
                input={"messages": [{"role": "user", "content": "hello!"}]},
                metadata={"name":"my_run"},
                config={"configurable": {"model_name": "openai"}},
                interrupt_before=["node_to_stop_before_1","node_to_stop_before_2"],
                interrupt_after=["node_to_stop_after_1","node_to_stop_after_2"],
                webhook="https://my.fake.webhook.com",
                multitask_strategy="interrupt"
            )
            print(background_run)

            --------------------------------------------------------------------------------

            {
                'run_id': 'my_run_id',
                'thread_id': 'my_thread_id',
                'assistant_id': 'my_assistant_id',
                'created_at': '2024-07-25T15:35:42.598503+00:00',
                'updated_at': '2024-07-25T15:35:42.598503+00:00',
                'metadata': {},
                'status': 'pending',
                'kwargs':
                    {
                        'input':
                            {
                                'messages': [
                                    {
                                        'role': 'user',
                                        'content': 'how are you?'
                                    }
                                ]
                            },
                        'config':
                            {
                                'metadata':
                                    {
                                        'created_by': 'system'
                                    },
                                'configurable':
                                    {
                                        'run_id': 'my_run_id',
                                        'user_id': None,
                                        'graph_id': 'agent',
                                        'thread_id': 'my_thread_id',
                                        'checkpoint_id': None,
                                        'model_name': "openai",
                                        'assistant_id': 'my_assistant_id'
                                    }
                            },
                        'webhook': "https://my.fake.webhook.com",
                        'temporary': False,
                        'stream_mode': ['values'],
                        'feedback_keys': None,
                        'interrupt_after': ["node_to_stop_after_1","node_to_stop_after_2"],
                        'interrupt_before': ["node_to_stop_before_1","node_to_stop_before_2"]
                    },
                'multitask_strategy': 'interrupt'
            }

        r  rY  Nr  r  r  r  r   r  r  r  rr  rw  r  r  r  r  rQ  r  r   r  )r   rS  r   r  rY  r  r  r  r  rr  rw  r  r  r  r  r  r  r  rF   r  r  r  s                         r<   r  zSyncRunsClient.create  sg   h
U
GN'--/C$!QQ]ACTX

 ;
  0
 f
 
 L
  0
 
 w
 *
 ]
 !"4
  ]!
" ]#
$ ]%
( %,MMOEDAqq}1a4EE99>>I;e,7G "   99>>'>II/ D" Fs   
C
C
/
C
:C
r   c               z    dd}|D cg c]
  } ||       }}| j                   j                  d||      S c c}w )r  c                \    | j                         D ci c]  \  }}|	|| c}}S c c}}w ry   r  r  s      r<   r  z3SyncRunsClient.create_batch.<locals>.filter_payload0  r  r  r  r   r  r  )r   r  rF   r  r  s        r<   r  zSyncRunsClient.create_batch+  sB    
	G <DDN7+DDyy~~m(G~LL Es   8)r  rY  r  r  rr  rw  r  r  r  r  r  r  r  rF   c                    y ry   r   )r   rS  r   r  rY  r  r  rr  rw  r  r  r  r  r  r  r  rF   s                    r<   r  zSyncRunsClient.wait6  s    ( -0r>   )r  rY  r  r  r  r  r  r  r  r  r  rF   c                    y ry   r   )r   rS  r   r  rY  r  r  r  r  r  r  r  r  r  rF   s                  r<   r  zSyncRunsClient.waitL  s    $ -0r>   )r  rY  r  r  rr  rw  r  r  r  r  r  r  r  r  rF   c               (   ||r'|j                         D ci c]  \  }}|	|| c}}nd||||	|
||||||||d}|d| dnd}| j                  j                  ||j                         D ci c]  \  }}|	|| c}}      S c c}}w c c}}w )a)  Create a run, wait until it finishes and return the final state.

        Args:
            thread_id: the thread ID to create the run on.
                If None will create a stateless run.
            assistant_id: The assistant ID or graph name to run.
                If using graph name, will default to first assistant created from that graph.
            input: The input to the graph.
            command: The command to execute.
            metadata: Metadata to assign to the run.
            config: The configuration for the assistant.
            checkpoint: The checkpoint to resume from.
            interrupt_before: Nodes to interrupt immediately before they get executed.
            interrupt_after: Nodes to Nodes to interrupt immediately after they get executed.
            webhook: Webhook to call after LangGraph API call is done.
            on_disconnect: The disconnect mode to use.
                Must be one of 'cancel' or 'continue'.
            on_completion: Whether to delete or keep the thread created for a stateless run.
                Must be one of 'delete' or 'keep'.
            multitask_strategy: Multitask strategy to use.
                Must be one of 'reject', 'interrupt', 'rollback', or 'enqueue'.
            if_not_exists: How to handle missing thread. Defaults to 'reject'.
                Must be either 'reject' (raise error if missing), or 'create' (create new thread).
            after_seconds: The number of seconds to wait before starting the run.
                Use to schedule future runs.
            headers: Optional custom headers to include with the request.

        Returns:
            Union[list[dict], dict[str, Any]]: The output of the run.

        Example Usage:

            final_state_of_run = client.runs.wait(
                thread_id=None,
                assistant_id="agent",
                input={"messages": [{"role": "user", "content": "how are you?"}]},
                metadata={"name":"my_run"},
                config={"configurable": {"model_name": "anthropic"}},
                interrupt_before=["node_to_stop_before_1","node_to_stop_before_2"],
                interrupt_after=["node_to_stop_after_1","node_to_stop_after_2"],
                webhook="https://my.fake.webhook.com",
                multitask_strategy="interrupt"
            )
            print(final_state_of_run)

            -------------------------------------------------------------------------------------------------------------------------------------------

            {
                'messages': [
                    {
                        'content': 'how are you?',
                        'additional_kwargs': {},
                        'response_metadata': {},
                        'type': 'human',
                        'name': None,
                        'id': 'f51a862c-62fe-4866-863b-b0863e8ad78a',
                        'example': False
                    },
                    {
                        'content': "I'm doing well, thanks for asking! I'm an AI assistant created by Anthropic to be helpful, honest, and harmless.",
                        'additional_kwargs': {},
                        'response_metadata': {},
                        'type': 'ai',
                        'name': None,
                        'id': 'run-bf1cd3c6-768f-4c16-b62d-ba6f17ad8b36',
                        'example': False,
                        'tool_calls': [],
                        'invalid_tool_calls': [],
                        'usage_metadata': None
                    }
                ]
            }

        Nr  rQ  r  r  r  )r   rS  r   r  rY  r  r  rr  rw  r  r  r  r  r  r  r  r  rF   r  r  r  r  s                         r<   r  zSyncRunsClient.wait`  s    @ GN'--/C$!QQ]ACTX ( 0.$*"4****#
( 2;1Fi	{*-L 	 yy~~W]]_NTQAqDN  
 	
' D( Os   
BB/
B:Br'  r   )r)  r*  rF   c               N    | j                   j                  d| d| d| |      S )a  List runs.

        Args:
            thread_id: The thread ID to list runs for.
            limit: The maximum number of results to return.
            offset: The number of results to skip.
            headers: Optional custom headers to include with the request.

        Returns:
            List[Run]: The runs for the thread.

        Example Usage:

            client.runs.list(
                thread_id="thread_id",
                limit=5,
                offset=5,
            )

        rQ  z/runs?limit=z&offset=r   r   )r   rS  r)  r*  rF   s        r<   rP   zSyncRunsClient.list  s7    8 yy}}	{,ugXfXFPW  
 	
r>   c               H    | j                   j                  d| d| |      S )a  Get a run.

        Args:
            thread_id: The thread ID to get.
            run_id: The run ID to get.
            headers: Optional custom headers to include with the request.

        Returns:
            Run: Run object.

        Example Usage:

            run = client.runs.get(
                thread_id="thread_id_to_delete",
                run_id="run_id_to_delete",
            )

        rQ  r  r   r   r  s       r<   rk   zSyncRunsClient.get  s(    4 yy}}y6&BG}TTr>   r  r  c          
     ^    | j                   j                  d| d| d|rdnd d| d|      S )	a  Get a run.

        Args:
            thread_id: The thread ID to cancel.
            run_id: The run ID to cancel.
            wait: Whether to wait until run has completed.
            action: Action to take when cancelling the run. Possible values
                are `interrupt` or `rollback`. Default is `interrupt`.
            headers: Optional custom headers to include with the request.

        Returns:
            None

        Example Usage:

            client.runs.cancel(
                thread_id="thread_id_to_cancel",
                run_id="run_id_to_cancel",
                wait=True,
                action="interrupt"
            )

        rQ  r  r  r  r   r  Nr   r  r  s         r<   r  zSyncRunsClient.cancel  sH    @ yy~~	{&4aQ=OxX^W_`  
 	
r>   c               J    | j                   j                  d| d| d|      S )a  Block until a run is done. Returns the final state of the thread.

        Args:
            thread_id: The thread ID to join.
            run_id: The run ID to join.
            headers: Optional custom headers to include with the request.

        Returns:
            None

        Example Usage:

            client.runs.join(
                thread_id="thread_id_to_join",
                run_id="run_id_to_join"
            )

        rQ  r  r  r   r   r  s       r<   r  zSyncRunsClient.join;  s2    2 yy}}	{&6  
 	
r>   )r  r  rF   c               T    | j                   j                  d| d| dd||d|      S )a  Stream output from a run in real-time, until the run is done.
        Output is not buffered, so any output produced before this call will
        not be received here.

        Args:
            thread_id: The thread ID to join.
            run_id: The run ID to join.
            stream_mode: The stream mode(s) to use. Must be a subset of the stream modes passed
                when creating the run. Background runs default to having the union of all
                stream modes.
            cancel_on_disconnect: Whether to cancel the run when the stream is disconnected.
            headers: Optional custom headers to include with the request.

        Returns:
            None

        Example Usage:

            client.runs.join_stream(
                thread_id="thread_id_to_join",
                run_id="run_id_to_join",
                stream_mode=["values", "debug"]
            )

        rQ  r  r  r  )r  r  r   r  )r   rS  r  r  r  rF   s         r<   r  zSyncRunsClient.join_streamX  sF    D yy	{&8*(<    
 	
r>   c               J    | j                   j                  d| d| |       y)a  Delete a run.

        Args:
            thread_id: The thread ID to delete.
            run_id: The run ID to delete.
            headers: Optional custom headers to include with the request.

        Returns:
            None

        Example Usage:

            client.runs.delete(
                thread_id="thread_id_to_delete",
                run_id="run_id_to_delete"
            )

        rQ  r  r   Nr%  r  s       r<   r   zSyncRunsClient.delete  s(    2 			9YKvfX>Pr>   r{  )(rS  r   r   r   r  r   rY  r  r  r  r  rB  r  r   r  rD  rr  r  rw  rA  r  r  r  r  r  r  r  r  r  rA  r  r  r  r  r  r  rF   r   r   rl  )$rS  r   r   r   r  r   rY  r  r  r  r  rB  r  r   r  rD  r  r  r  r  r  r  r  r  r  r  r  r  r  rA  r  r  rF   r   r   rl  )*rS  rA  r   r   r  r   rY  r  r  r  r  rB  r  r   r  rD  rr  r  rw  rA  r  r  r  r  r  r  r  r  r  r  r  rA  r  r  r  r  r  r  rF   r   r   rl  r  r  )&rS  rA  r   r   r  r   rY  r  r  r  r  rB  r  r   r  rD  rr  r  rw  rA  r  r  r  r  r  rA  r  r  r  r  r  r  r  r  rF   r   r   r    )r  r  rF   r   r   r  )"rS  r   r   r   r  r   rY  r  r  r   r  rD  rr  r  rw  rA  r  r  r  r  r  rA  r  r  r  r  r  r  r  r  rF   r   r   r  )rS  r   r   r   r  r   rY  r  r  r   r  rD  r  r  r  r  r  rA  r  r  r  r  r  r  r  r  rF   r   r   r  )$rS  rA  r   r   r  r   rY  r  r  r   r  rD  rr  r  rw  rA  r  r  r  r  r  rA  r  r  r  r  r  r  r  r  r  r  rF   r   r   r  )
rS  r   r)  rI  r*  rI  rF   r   r   r  r  r  r  )rS  r   r  r   r  r  r  rB  rF   r   r   rl  r  r  r   r>   r<   r]  r]    sn
   	  !%%)?G!&#'#'+/'+@D?C1526!%:>/3'+,0+## #
 # ## =# # !# !# )# %# ># =# /#  0!#" ##$ 8%#& -'#( %)#* *+#, 
-# #0  !%%)?G!&#'#'@D?C15268</3!%'+,0'## #
 # ## =# # !# !# ># =# /# 0# 6#  -!#" ##$ %%#& *'#( 
)# #6 !%%)?G!&#'#'+/'+@D?C15268<!%:>/3'+,0-r
 r
 r

 r
 #r
 =r
 r
 !r
 !r
 )r
 %r
 >r
 =r
 /r
  0!r
" 6#r
$ %r
& 8'r
( -)r
* %+r
, *-r
. 
/r
h  !%%)?G!&#'#'@D?C!%8</3'+,0# 
  # =  ! ! > =  6 -  %!" *#$ 
% (  !%%)?G!&#'#'+/'+@D?C!%:>/3'+,0' 
  # =  ! ! ) % > =   8!" -#$ %%& *'( 
) 6 !%%)?G!&#'#'+/'+@D?C!%:>8</3'+,0)NJ NJ NJ
 NJ #NJ =NJ NJ !NJ !NJ )NJ %NJ >NJ =NJ NJ  8!NJ" 6#NJ$ -%NJ& %'NJ( *)NJ* 
+NJb QU	M'	M5M	M		M  !%%)#'#'+/'+@D?C!%26:>/3'+,0%00 0
 0 #0 !0 !0 )0 %0 >0 =0 0 00 80  -!0" %#0$ *%0& 
+'0 0*  !%%)#'#'@D?C!%268</3'+,0!00 0
 0 #0 !0 !0 >0 =0 0 00 60 -0 %0  *!0" 
+#0 00 !%%)#'#'+/'+@D?C!%268<:>/3'+,0'w
 w
 w

 w
 #w
 !w
 !w
 )w
 %w
 >w
 =w
 w
 0w
 6w
  8!w
" -#w
$ %%w
& *'w
( 
+)w
z ,0

 	

 
 *
 

J -1UU U
 *U 
UB *,0$
$
 $

 $
 $
 *$
 
$
V -1

 

 *
 

D JN%*,0*
*
 *

 G*
 #*
 **
 
*
b -1QQ Q
 *Q 
Qr>   r]  c            	          e Zd ZdZddZddddddddd	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 ddZddddddddd	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 ddZdd	 	 	 	 	 ddZddd	d
dd	 	 	 	 	 	 	 	 	 	 	 ddZy)r^  aY  Synchronous client for managing cron jobs in LangGraph.

    This class provides methods to create and manage scheduled tasks (cron jobs) for automated graph executions.

    Example:

        client = get_sync_client()
        cron_job = client.crons.create_for_thread(thread_id="thread_123", assistant_id="asst_456", schedule="0 * * * *")
    c                    || _         y ry   r   r  s     r<   r   zSyncCronClient.__init__  r  r>   Nr  c       	   	         ||||||||	d}|
r|
|d<   |j                         D ci c]  \  }}|	|| }}}| j                  j                  d| d||      S c c}}w )a  Create a cron job for a thread.

        Args:
            thread_id: the thread ID to run the cron job on.
            assistant_id: The assistant ID or graph name to use for the cron job.
                If using graph name, will default to first assistant created from that graph.
            schedule: The cron schedule to execute this job on.
            input: The input to the graph.
            metadata: Metadata to assign to the cron job runs.
            config: The configuration for the assistant.
            interrupt_before: Nodes to interrupt immediately before they get executed.

            interrupt_after: Nodes to Nodes to interrupt immediately after they get executed.

            webhook: Webhook to call after LangGraph API call is done.
            multitask_strategy: Multitask strategy to use.
                Must be one of 'reject', 'interrupt', 'rollback', or 'enqueue'.
            headers: Optional custom headers to include with the request.

        Returns:
            Run: The cron run.

        Example Usage:

            cron_run = client.crons.create_for_thread(
                thread_id="my-thread-id",
                assistant_id="agent",
                schedule="27 15 * * *",
                input={"messages": [{"role": "user", "content": "hello!"}]},
                metadata={"name":"my_run"},
                config={"configurable": {"model_name": "openai"}},
                interrupt_before=["node_to_stop_before_1","node_to_stop_before_2"],
                interrupt_after=["node_to_stop_after_1","node_to_stop_after_2"],
                webhook="https://my.fake.webhook.com",
                multitask_strategy="interrupt"
            )

        r  r  rQ  r  r   r  r  s                  r<   r  z SyncCronClient.create_for_thread  s    l ! ( 0.	
 ,>G()$+MMOEDAqq}1a4EEyy~~	{+.Wg  
 	
 Fs
   
AAc       	   	         ||||||||d}|	r|	|d<   |j                         D ci c]  \  }}|	|| }}}| j                  j                  d||
      S c c}}w )r
  r  r  r  r   r  r  s                 r<   r  zSyncCronClient.create  sx    b ! ( 0.	
 ,>G()$+MMOEDAqq}1a4EEyy~~m'7~KK Fs
   
AAr   c               D    | j                   j                  d| |       y)a1  Delete a cron.

        Args:
            cron_id: The cron ID to delete.
            headers: Optional custom headers to include with the request.

        Returns:
            None

        Example Usage:

            client.crons.delete(
                cron_id="cron_to_delete"
            )

        r  r   Nr%  r  s      r<   r   zSyncCronClient.delete3  s"    , 			<y17Cr>   r'  r   r  c                   ||||d}|j                         D ci c]  \  }}|	|| }}}| j                  j                  d||      S c c}}w )a9  Get a list of cron jobs.

        Args:
            assistant_id: The assistant ID or graph name to search for.
            thread_id: the thread ID to search for.
            limit: The maximum number of results to return.
            offset: The number of results to skip.
            headers: Optional custom headers to include with the request.

        Returns:
            list[Cron]: The list of cron jobs returned by the search,

        Example Usage:

            cron_jobs = client.crons.search(
                assistant_id="my_assistant_id",
                thread_id="my_thread_id",
                limit=5,
                offset=5,
            )
            print(cron_jobs)

            ----------------------------------------------------------

            [
                {
                    'cron_id': '1ef3cefa-4c09-6926-96d0-3dc97fd5e39b',
                    'assistant_id': 'my_assistant_id',
                    'thread_id': 'my_thread_id',
                    'user_id': None,
                    'payload':
                        {
                            'input': {'start_time': ''},
                            'schedule': '4 * * * *',
                            'assistant_id': 'my_assistant_id'
                        },
                    'schedule': '4 * * * *',
                    'next_run_date': '2024-07-25T17:04:00+00:00',
                    'end_time': None,
                    'created_at': '2024-07-08T06:02:23.073257+00:00',
                    'updated_at': '2024-07-08T06:02:23.073257+00:00'
                }
            ]

        r  r  r   r  r  s	            r<   r/  zSyncCronClient.searchK  s_    n )"	
 %,MMOEDAqq}1a4EEyy~~2'~RR Fs
   
AA)r   rZ  r   r   r  r  r  r  r  r   r>   r<   r^  r^    s     !%#'#'<@;?!%,0,0D
D
 D

 D
 D
 !D
 !D
 :D
 9D
 D
 *D
 *D
 
D
V !%#'#'<@;?!%,0,0=L=L 	=L
 =L !=L !=L :=L 9=L =L *=L *=L 
=LF -1	DD *	D
 
D6 '+#',0=S $=S !	=S
 =S =S *=S 
=Sr>   r^  c                      e Zd ZdZd
dZ	 	 	 d	 	 	 	 	 	 	 	 	 	 	 	 	 ddZddd	 	 	 	 	 	 	 	 	 ddZ	 d	 	 	 	 	 	 	 ddZ	 	 	 	 	 	 d	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 ddZ	 	 	 	 	 	 d	 	 	 	 	 	 	 	 	 	 	 	 	 dd	Z	y)r_  aZ  A client for synchronous operations on a key-value store.

    Provides methods to interact with a remote key-value store, allowing
    storage and retrieval of items within namespaced hierarchies.

    Example:

        client = get_sync_client()
        client.store.put_item(["users", "profiles"], "user123", {"name": "Alice", "age": 30})
    c                    || _         y ry   r   r   s     r<   r   zSyncStoreClient.__init__  r   r>   Nc                   |D ]  }d|v st        d| d       |||||d}| j                  j                  dt        |      |       y)a  Store or update an item.

        Args:
            namespace: A list of strings representing the namespace path.
            key: The unique identifier for the item within the namespace.
            value: A dictionary containing the item's data.
            index: Controls search indexing - None (use defaults), False (disable), or list of field paths to index.
            ttl: Optional time-to-live in minutes for the item, or None for no expiration.
            headers: Optional custom headers to include with the request.

        Returns:
            None

        Example Usage:

            client.store.put_item(
                ["documents", "user123"],
                key="item456",
                value={"title": "My Document", "content": "Hello World"}
            )
        r  r  r   r!  r&  r   Nr'  r)  s	            r<   r+  zSyncStoreClient.put_item  si    >  	Ee| /w6gh 	 #
 			n>'+BGTr>   r,  c                  |D ]  }d|v st        d| d       |dj                  |      d}|||d<   | j                  j                  d||      S )a  Retrieve a single item.

        Args:
            key: The unique identifier for the item.
            namespace: Optional list of strings representing the namespace path.
            refresh_ttl: Whether to refresh the TTL on this read operation. If None, uses the store's default behavior.
            headers: Optional custom headers to include with the request.

        Returns:
            Item: The retrieved item.

        Example Usage:

            item = client.store.get_item(
                ["documents", "user123"],
                key="item456",
            )
            print(item)

            ----------------------------------------------------------------

            {
                'namespace': ['documents', 'user123'],
                'key': 'item456',
                'value': {'title': 'My Document', 'content': 'Hello World'},
                'created_at': '2024-07-30T12:00:00Z',
                'updated_at': '2024-07-30T12:00:00Z'
            }
        r  r  r   r"  r  r-  r&  r   r0  r1  s          r<   r2  zSyncStoreClient.get_item  ss    L  	Ee| /w6gh 	 388I+>?"$/F=!yy}}^FG}LLr>   c               F    | j                   j                  d||d|       y)a  Delete an item.

        Args:
            key: The unique identifier for the item.
            namespace: Optional list of strings representing the namespace path.
            headers: Optional custom headers to include with the request.

        Returns:
            None

        Example Usage:

            client.store.delete_item(
                ["documents", "user123"],
                key="item456",
            )
        r&  r  r   Nr%  r4  s       r<   r5  zSyncStoreClient.delete_item  s'    0 			9!Ew 	 	
r>   c               b    ||||||d}| j                   j                  dt        |      |      S )aO  Search for items within a namespace prefix.

        Args:
            namespace_prefix: List of strings representing the namespace prefix.
            filter: Optional dictionary of key-value pairs to filter results.
            limit: Maximum number of items to return (default is 10).
            offset: Number of items to skip before returning results (default is 0).
            query: Optional query for natural language search.
            refresh_ttl: Whether to refresh the TTL on items returned by this search. If None, uses the store's default behavior.
            headers: Optional custom headers to include with the request.

        Returns:
            List[Item]: A list of items matching the search criteria.

        Example Usage:

            items = client.store.search_items(
                ["documents"],
                filter={"author": "John Doe"},
                limit=5,
                offset=0
            )
            print(items)

            ----------------------------------------------------------------

            {
                "items": [
                    {
                        "namespace": ["documents", "user123"],
                        "key": "item789",
                        "value": {
                            "title": "Another Document",
                            "author": "John Doe"
                        },
                        "created_at": "2024-07-30T12:00:00Z",
                        "updated_at": "2024-07-30T12:00:00Z"
                    },
                    # ... additional items ...
                ]
            }
        r7  r;  r   r<  r=  s	            r<   r>  zSyncStoreClient.search_items  sF    l !1&
 yy~~!w(?  
 	
r>   c                `    |||||d}| j                   j                  dt        |      |      S )a  List namespaces with optional match conditions.

        Args:
            prefix: Optional list of strings representing the prefix to filter namespaces.
            suffix: Optional list of strings representing the suffix to filter namespaces.
            max_depth: Optional integer specifying the maximum depth of namespaces to return.
            limit: Maximum number of namespaces to return (default is 100).
            offset: Number of namespaces to skip before returning results (default is 0).
            headers: Optional custom headers to include with the request.

        Returns:
            List[List[str]]: A list of namespaces matching the criteria.

        Example Usage:

            namespaces = client.store.list_namespaces(
                prefix=["documents"],
                max_depth=3,
                limit=10,
                offset=0
            )
            print(namespaces)

            ----------------------------------------------------------------

            [
                ["documents", "user123", "reports"],
                ["documents", "user456", "invoices"],
                ...
            ]
        r@  rC  r   r<  rD  s           r<   rE  zSyncStoreClient.list_namespacesU  sC    R "
 yy~~nW&=w  
 	
r>   r{  rF  rG  rI  ry   rK  rL  rM  rN  rP  rR  r   r>   r<   r_  r_    s   	 =A!,0+U 	+U
 +U :+U +U *+U +U 
+Uf '+,0/M 	/M /M $/M */M 
/Ml -1
 	

 *
 
 

@ ,0#&*,0?
 )	?

 ?
 ?
 ?
 $?
 *?
'?
 
?
F '+&*#',01
#1
 $1
 !	1

 1
 1
 *1
 
1
r>   r_  c                \    | j                         D ci c]  \  }}|	|| c}}S c c}}w ry   r  )dr  r  s      r<   r(  r(    s(    WWY8TQ!-AqD888r  zlist[httpx.ASGITransport]rn   c                (    t         D ]	  }| |_         y ry   )rn   rZ   )rZ   rh   s     r<   configure_loopback_transportsr    s    + 		r>   ry   )r9   rA  r   rA  )r9   rA  rD   r   r   zdict[str, str])rS   r   r   r   )rU   rA  r9   rA  rF   r   r   rV   )r   r   r   ztuple[dict[str, str], bytes])r   zhttpx.Responser   r   )rU   rA  r9   rA  rF   r   r   rS  )r  rJ   )rZ   r   r   r   )Wr   
__future__r   r   loggingr6   r   typingr   r   r   r   r   r	   r
   r   r   r   rl   r   httpx._typesr   rB   langgraph_sdk.schemar   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   r&   r'   r(   r)   r*   langgraph_sdk.sser+   r,   r-   	getLoggerr   r   r@   r=   rG   rT   rv   rV   rz   r   r   r|   r~   r   r   r   rW  rS  rZ  rf  rd  r[  r\  r]  r^  r_  r(  rn   __annotations__r  r   r>   r<   <module>r     s   #   	 
     (        < J I			8	$ "  ,D(P !(,	9#	9# 9# &	9#
 9#x, ,(_ _D l
 l
^E
 E
PiW iWXmY mY`C
 C
P !(,	*'	*' *' &	*'
 *'Z0 0*T Tn	0
k
 k
\G
 G
TaQ aQHhS hSV{
 {
|9 57 1 6r>   