
    Ng|_                    >   d dl mZ d dlmZmZmZmZmZmZm	Z	m
Z
 d dlmZmZ d dlmZ d dlmZ d dlmZ d dlmZmZ d dlmZ d d	lmZ d d
lmZmZmZ d dlm Z  erd dl!Z!d dl"m#Z# d dl$m%Z& ddZ'd dZ(d!dZ)d"dZ*d#dZ+ e             G d de                      Z,dS )$    )annotations)TYPE_CHECKINGAnyCallableDictOptionalSequenceTypeUnion)OpenAIAssistantRunnable
OutputType)beta)CallbackManager)dumpd)RunnableConfigensure_config)BaseTool)convert_to_openai_tool)	BaseModelFieldmodel_validator)SelfN)NotGiven)ToolResourcesreturnopenai.OpenAIc                     	 ddl }  | j        ddi          S # t          $ r}t          d          |d}~wt          $ r}t          d          |d}~ww xY w)zGet the OpenAI client.

    Returns:
        openai.OpenAI: OpenAI client

    Raises:
        ImportError: If `openai` is not installed.
        AttributeError: If the installed `openai` version is not compatible.
    r   NOpenAI-Betaassistants=v2default_headersBUnable to import openai, please install with `pip install openai`.wPlease make sure you are using a v1.23-compatible version of openai. You can install with `pip install "openai>=1.23"`.)openaiOpenAIImportErrorAttributeErrorr$   es     l/var/www/html/ai-engine/env/lib/python3.11/site-packages/langchain_community/agents/openai_assistant/base.py_get_openai_clientr+      s    v}m_-MNNNN   P
 
	    =
 
 	    
A3A AAopenai.AsyncOpenAIc                     	 ddl }  | j        ddi          S # t          $ r}t          d          |d}~wt          $ r}t          d          |d}~ww xY w)zGet the async OpenAI client.

    Returns:
        openai.AsyncOpenAI: Async OpenAI client

    Raises:
        ImportError: If `openai` is not installed.
        AttributeError: If the installed `openai` version is not compatible.
    r   Nr   r   r    r"   r#   )r$   AsyncOpenAIr&   r'   r(   s     r*   _get_openai_async_clientr0   7   s    !v!=/2RSSSS   P
 
	    =
 
 	r,   file_idslistc                P    g }| D ] }|                     |ddiddigd           !|S )a  Convert file_ids into attachments
    File search and Code interpreter will be turned on by default.

    Args:
        file_ids (list): List of file_ids that need to be converted into attachments.

    Returns:
        list: List of attachments converted from file_ids.
    typefile_searchcode_interpreter)file_idtools)append)r1   attachmentsids      r*   "_convert_file_ids_into_attachmentsr<   P   s]     K 
 
!=1F<N3OP 	
 	
 	
 	
     tool:Union[Dict[str, Any], Type[BaseModel], Callable, BaseTool]boolc                L    d}t          | t                    od| v o	| d         |v S )aM  Determine if tool corresponds to OpenAI Assistants built-in.

    Args:
        tool (Union[Dict[str, Any], Type[BaseModel], Callable, BaseTool]):
            Tool that needs to be determined.

    Returns:
        A boolean response of true or false indicating if the tool corresponds to
            OpenAI Assistants built-in.
    )r6   	retrievalr5   r4   )
isinstancedict)r>   assistants_builtin_toolss     r*   _is_assistants_builtin_toolrF   e   s;      P4 	7t^	7&\55r=   Dict[str, Any]c                B    t          |           r| S t          |           S )a  Convert a raw function/class to an OpenAI tool.

    Note that OpenAI assistants supports several built-in tools,
    such as "code_interpreter" and "retrieval."

    Args:
        tool (Union[Dict[str, Any], Type[BaseModel], Callable, BaseTool]):
            Tools or functions that need to be converted to OpenAI tools.

    Returns:
        Dict[str, Any]: A dictionary of tools that are converted into OpenAI tools.
    )rF   r   )r>   s    r*   _get_assistants_toolrI   z   s'     #4(( ,%d+++r=   c                     e Zd ZU dZ ee          Zded<   	 dZded<   	 ded<   	 d	Z	d
ed<   	 dZ
ded<   	  ed          d3d            Zei ddddd4d#            Z	 d5d6d)Zeddd*d7d,            Z	 d5d6d-Zd8d.Zd9d0Zd8d1Zd9d2ZdS ):OpenAIAssistantV2Runnablea  Run an OpenAI Assistant.

    Attributes:
        client (Any): OpenAI or AzureOpenAI client.
        async_client (Any): Async OpenAI or AzureOpenAI client.
        assistant_id (str): OpenAI assistant ID.
        check_every_ms (float): Frequency to check progress in milliseconds.
        as_agent (bool): Whether to use the assistant as a LangChain agent.

    Example using OpenAI tools:
        .. code-block:: python

            from langchain.agents.openai_assistant import OpenAIAssistantV2Runnable

            assistant = OpenAIAssistantV2Runnable.create_assistant(
                name="math assistant",
                instructions="You are a personal math tutor. Write and run code to answer math questions.",
                tools=[{"type": "code_interpreter"}],
                model="gpt-4-1106-preview"
            )
            output = assistant.invoke({"content": "What's 10 - 4 raised to the 2.7"})

    Example using custom tools and AgentExecutor:
        .. code-block:: python

            from langchain.agents.openai_assistant import OpenAIAssistantV2Runnable
            from langchain.agents import AgentExecutor
            from langchain.tools import E2BDataAnalysisTool


            tools = [E2BDataAnalysisTool(api_key="...")]
            agent = OpenAIAssistantV2Runnable.create_assistant(
                name="langchain assistant e2b tool",
                instructions="You are a personal math tutor. Write and run code to answer math questions.",
                tools=tools,
                model="gpt-4-1106-preview",
                as_agent=True
            )

            agent_executor = AgentExecutor(agent=agent, tools=tools)
            agent_executor.invoke({"content": "Analyze the data..."})

    Example using custom tools and custom execution:
        .. code-block:: python

            from langchain.agents.openai_assistant import OpenAIAssistantV2Runnable
            from langchain.agents import AgentExecutor
            from langchain_core.agents import AgentFinish
            from langchain.tools import E2BDataAnalysisTool


            tools = [E2BDataAnalysisTool(api_key="...")]
            agent = OpenAIAssistantV2Runnable.create_assistant(
                name="langchain assistant e2b tool",
                instructions="You are a personal math tutor. Write and run code to answer math questions.",
                tools=tools,
                model="gpt-4-1106-preview",
                as_agent=True
            )

            def execute_agent(agent, tools, input):
                tool_map = {tool.name: tool for tool in tools}
                response = agent.invoke(input)
                while not isinstance(response, AgentFinish):
                    tool_outputs = []
                    for action in response:
                        tool_output = tool_map[action.tool].invoke(action.tool_input)
                        tool_outputs.append({"output": tool_output, "tool_call_id": action.tool_call_id})
                    response = agent.invoke(
                        {
                            "tool_outputs": tool_outputs,
                            "run_id": action.run_id,
                            "thread_id": action.thread_id
                        }
                    )

                return response

            response = execute_agent(agent, tools, {"content": "What's 10 - 4 raised to the 2.7"})
            next_response = execute_agent(agent, tools, {"content": "now add 17.241", "thread_id": response.thread_id})

    )default_factoryr   clientNasync_clientstrassistant_idg     @@floatcheck_every_msFr@   as_agentafter)moder   r   c                `    | j         &ddl}| j        j        } |j        |          | _         | S )z?Validate that the async client is set, otherwise initialize it.Nr   )api_key)rN   r$   rM   rW   r/   )selfr$   rW   s      r*   validate_async_clientz/OpenAIAssistantV2Runnable.validate_async_client   s=     $MMMk)G 2 27 C C CDr=   )model_kwargsrM   tool_resources
extra_bodynameinstructionsr8   Sequence[Union[BaseTool, dict]]modelrZ   dict[str, float]2Optional[Union[openai.OpenAI, openai.AzureOpenAI]]r[   7Optional[Union[AssistantToolResources, dict, NotGiven]]r\   Optional[object]kwargsr   c          
         |pt                      }|ddlm}
 |
} |j        j        j        d||d |D             |||d|} | d|j        |d|	S )a  Create an OpenAI Assistant and instantiate the Runnable.

        Args:
            name (str): Assistant name.
            instructions (str): Assistant instructions.
            tools (Sequence[Union[BaseTool, dict]]): Assistant tools. Can be passed
                in OpenAI format or as BaseTools.
            tool_resources (Optional[Union[AssistantToolResources, dict, NotGiven]]):
                Assistant tool resources. Can be passed in OpenAI format.
            model (str): Assistant model to use.
            client (Optional[Union[openai.OpenAI, openai.AzureOpenAI]]): OpenAI or
                AzureOpenAI client. Will create default OpenAI client (Assistant v2)
                if not specified.
            model_kwargs: Additional model arguments. Only available for temperature
                and top_p parameters.
            extra_body: Additional body parameters to be passed to the assistant.

        Returns:
            OpenAIAssistantRunnable: The configured assistant runnable.
        Nr   	NOT_GIVENc                ,    g | ]}t          |          S  rI   .0r>   s     r*   
<listcomp>z>OpenAIAssistantV2Runnable.create_assistant.<locals>.<listcomp>#  s!    @@@$'--@@@r=   )r]   r^   r8   r[   r`   r\   )rP   rM   rj   )r+   openai._typesrh   r   
assistantscreater;   )clsr]   r^   r8   r`   rZ   rM   r[   r\   re   rh   	assistants               r*   create_assistantz*OpenAIAssistantV2Runnable.create_assistant   s    D /-//!//////&N1FK*1 
%@@%@@@)!
 
 
 
	 sF	VFFvFFFr=   inputrD   configOptional[RunnableConfig]r   c           	        t          |          }t          j        |                    d          |                    d          |                    d                    }|                    t          |           ||                    d          p|                                           }t          |                    dg                     }|                    dg           |z   }	 | j        rR|                    d	          r=| 	                    |d	                   } | j
        j        j        j        j        di |}	nd
|vrNd|d         ||                    d          dg|                    d          d}
|                     ||
          }	nd|vrc| j
        j        j        j                            |d
         |d         d||                    d                    }|                     |          }	n! | j
        j        j        j        j        di |}	|                     |	j        |	j                  }	n)# t,          $ r}|                    |           |d}~ww xY w	 |                     |	          }|                    |           |S # t,          $ r0}|                    ||	                                           |d}~ww xY w)a(  Invoke the assistant.

        Args:
            input (dict): Runnable input dict that can have:
                content: User message when starting a new run.
                thread_id: Existing thread to use.
                run_id: Existing run to use. Should only be supplied when providing
                    the tool output for a required action after an initial invocation.
                file_ids: (deprecated) File ids to include in new run. Use
                    'attachments' instead
                attachments: Assistant files to include in new run. (v2 API).
                message_metadata: Metadata to associate with new message.
                thread_metadata: Metadata to associate with new thread. Only relevant
                    when new thread being created.
                instructions: Additional run instructions.
                model: Override Assistant model for this run.
                tools: Override Assistant tools for this run.
                tool_resources: Override Assistant tool resources for this run (v2 API).
                run_metadata: Metadata to associate with new run.
            config (Optional[RunnableConfig]): Configuration for the run.

        Returns:
            OutputType: If self.as_agent, will return
                Union[List[OpenAIAssistantAction], OpenAIAssistantFinish]. Otherwise,
                will return OpenAI types
                Union[List[ThreadMessage], List[RequiredActionFunctionToolCall]].

        Raises:
            BaseException: If an error occurs during the invocation.
        	callbackstagsmetadatainheritable_callbacksinheritable_tagsinheritable_metadatarun_namer]   r1   r:   intermediate_steps	thread_idusercontentmessage_metadataroler   r:   r{   thread_metadatamessagesr{   run_idr   r   r:   r{   Nr{   rj   )r   r   	configuregeton_chain_startr   get_namer<   rS   _parse_intermediate_stepsrM   r   threadsrunssubmit_tool_outputs_create_thread_and_runr   rq   _create_run_wait_for_runr;   r   BaseExceptionon_chain_error_get_responseon_chain_endrD   rX   ru   rv   re   callback_managerrun_managerfilesr:   tool_outputsrunthread_r)   responses                 r*   invokez OpenAIAssistantV2Runnable.invoke+  s
   B v&&*4"(**["9"9#ZZ//!'J!7!7
 
 

 '55$KKVZZ
%;%;%Nt}} 6 
 
 36::j"3M3MNNjj33e;&	}  Q+?!@!@  Q#==./    Hdk&.3GWW,WWE)) %+',Y'7+6(-		2D(E(E	 ! !&		*; < <
 
 11%@@&&K$,5<<+&!), +"YY'9:: =   &&u-- Hdk&.3GPP%PP$$SVS];;CC 	 	 	&&q)))G		))#..H
 $$X...O  	 	 	&&q388::&>>>G	s1   )EH= =
I#II#'J 
K+KK)rN   r[   <Optional[Union[openai.AsyncOpenAI, openai.AsyncAzureOpenAI]]c                  K   |pt                      }|ddlm} |}d |D             }	|j        j                            |||	||           d{V }
 | d|
j        |d|S )a  Create an AsyncOpenAI Assistant and instantiate the Runnable.

        Args:
            name (str): Assistant name.
            instructions (str): Assistant instructions.
            tools (Sequence[Union[BaseTool, dict]]): Assistant tools. Can be passed
                in OpenAI format or as BaseTools.
            tool_resources (Optional[Union[AssistantToolResources, dict, NotGiven]]):
                Assistant tool resources. Can be passed in OpenAI format.
            model (str): Assistant model to use.
            async_client (Optional[Union[openai.OpenAI, openai.AzureOpenAI]]): OpenAI or
            AzureOpenAI async client. Will create default async_client if not specified.

        Returns:
            AsyncOpenAIAssistantRunnable: The configured assistant runnable.
        Nr   rg   c                ,    g | ]}t          |          S rj   rk   rl   s     r*   rn   z?OpenAIAssistantV2Runnable.acreate_assistant.<locals>.<listcomp>  s!    EEEt,T22EEEr=   )r]   r^   r8   r[   r`   )rP   rN   rj   )r0   ro   rh   r   rp   rq   r;   )rr   r]   r^   r8   r`   rN   r[   re   rh   openai_toolsrs   s              r*   acreate_assistantz+OpenAIAssistantV2Runnable.acreate_assistant  s      < $A'?'A'A!//////&NEEuEEE&+6==%) > 
 
 
 
 
 
 
 
	 sR	<RR6RRRr=   c           	       K   |pi }t          j        |                    d          |                    d          |                    d                    }|                    t	          |           ||                    d          p|                                           }t          |                    dg                     }|                    dg           |z   }	 | j        rX|                    d	          rC|                     |d	                   } | j	        j
        j        j        j        di | d
{V }	nd|vrTd|d         ||                    d          dg|                    d          d}
|                     ||
           d
{V }	nd|vro| j	        j
        j        j                            |d         |d         d||                    d                     d
{V }|                     |           d
{V }	n' | j	        j
        j        j        j        di | d
{V }	|                     |	j        |	j                   d
{V }	n)# t*          $ r}|                    |           |d
}~ww xY w	 |                     |	          }|                    |           |S # t*          $ r0}|                    ||	                                           |d
}~ww xY w)a*  Async invoke assistant.

        Args:
            input (dict): Runnable input dict that can have:
                content: User message when starting a new run.
                thread_id: Existing thread to use.
                run_id: Existing run to use. Should only be supplied when providing
                    the tool output for a required action after an initial invocation.
                file_ids: (deprecated) File ids to include in new run. Use
                    'attachments' instead
                attachments: Assistant files to include in new run. (v2 API).
                message_metadata: Metadata to associate with new message.
                thread_metadata: Metadata to associate with new thread. Only relevant
                    when new thread being created.
                instructions: Additional run instructions.
                model: Override Assistant model for this run.
                tools: Override Assistant tools for this run.
                tool_resources: Override Assistant tool resources for this run (v2 API).
                run_metadata: Metadata to associate with new run.
            config (Optional[RunnableConfig]): Configuration for the run.

        Returns:
            OutputType: If self.as_agent, will return
                Union[List[OpenAIAssistantAction], OpenAIAssistantFinish]. Otherwise,
                will return OpenAI types
                Union[List[ThreadMessage], List[RequiredActionFunctionToolCall]].

        Raises:
            BaseException: If an error occurs during the invocation.
        ry   rz   r{   r|   r   r   r1   r:   r   Nr   r   r   r   r   r   r   r   r   r   rj   )r   r   r   r   r   r   r<   rS   r   rN   r   r   r   r   _acreate_thread_and_runr   rq   _acreate_run_await_for_runr;   r   r   r   r   r   rD   r   s                 r*   ainvokez!OpenAIAssistantV2Runnable.ainvoke  s     B 2*4"(**["9"9#ZZ//!'J!7!7
 
 

 '55$KKVZZ
%;%;%Nt}} 6 
 
 36::j"3M3MNNjj33e;*	} $+?!@!@ $#==./    TD-2:?S  "        E)) %+',Y'7+6(-		2D(E(E	 ! !&		*; < <
 
 !88GGGGGGGG&&+08AHH+&!), +"YY'9:: I         !--e44444444 TD-2:?S          ++CFCMBBBBBBBBCC 	 	 	&&q)))G		))#..H
 $$X...O  	 	 	&&q388::&>>>G	s1    E7I 
I>"I99I>J. .
K(8+K##K(c                    dfd|                                 D             } | j        j        j        j        j        |d         fd| j        i|S )zCreate a new run within an existing thread.

        Args:
            input (dict): The input data for the new run.

        Returns:
            Any: The created run object.
        )r^   r`   r8   r[   run_metadatatruncation_strategymax_prompt_tokensc                $    i | ]\  }}|v 	||S rj   rj   )rm   kvallowed_assistant_paramss      r*   
<dictcomp>z9OpenAIAssistantV2Runnable._create_run.<locals>.<dictcomp>+  s*    RRR41aA9Q4Q4Q!Q4Q4Q4Qr=   r   rP   )itemsrM   r   r   r   rq   rP   )rX   ru   paramsr   s      @r*   r   z%OpenAIAssistantV2Runnable._create_run  ss    $
  SRRR5;;==RRR3t{',3+
 
*
 
 
 	
r=   r   c                    d |                                 D             }|                    d          x}r||d<    | j        j        j        j        d| j        |d|}|S )zCreate a new thread and run.

        Args:
            input (dict): The input data for the run.
            thread (dict): The thread data to create.

        Returns:
            Any: The created thread and run.
        c                "    i | ]\  }}|d v 	||S )r^   r`   r8   r   rj   rm   r   r   s      r*   r   zDOpenAIAssistantV2Runnable._create_thread_and_run.<locals>.<dictcomp><  4     
 
 
1FFF qFFFr=   r[   rP   r   rj   )r   r   rM   r   r   create_and_runrP   rX   ru   r   r   r[   r   s         r*   r   z0OpenAIAssistantV2Runnable._create_thread_and_run2  s    
 

 
 

 #YY'7888> 	6'5F#$5dk&5 
*
 
 
 

 
r=   c                   K   d |                                 D             } | j        j        j        j        j        |d         fd| j        i| d{V S )zAsynchronously create a new run within an existing thread.

        Args:
            input (dict): The input data for the new run.

        Returns:
            Any: The created run object.
        c                "    i | ]\  }}|d v 	||S ))r^   r`   r8   r[   r   rj   r   s      r*   r   z:OpenAIAssistantV2Runnable._acreate_run.<locals>.<dictcomp>S  s4     
 
 
1XXX qXXXr=   r   rP   N)r   rN   r   r   r   rq   rP   )rX   ru   r   s      r*   r   z&OpenAIAssistantV2Runnable._acreate_runJ  s      
 

 
 

 @T&+38?+
 
*
 
 
 
 
 
 
 
 
 	
r=   c                   K   d |                                 D             }|                    d          x}r||d<    | j        j        j        j        d| j        |d| d{V }|S )zAsynchronously create a new thread and run simultaneously.

        Args:
            input (dict): The input data for the run.
            thread (dict): The thread data to create.

        Returns:
            Any: The created thread and run.
        c                "    i | ]\  }}|d v 	||S r   rj   r   s      r*   r   zEOpenAIAssistantV2Runnable._acreate_thread_and_run.<locals>.<dictcomp>h  r   r=   r[   r   Nrj   )r   r   rN   r   r   r   rP   r   s         r*   r   z1OpenAIAssistantV2Runnable._acreate_thread_and_run^  s      
 

 
 

 #YY'7888> 	6'5F#$AD%*2A 
*
 
 
 
 
 
 
 
 
 

 
r=   )r   r   )r]   rO   r^   rO   r8   r_   r`   rO   rZ   ra   rM   rb   r[   rc   r\   rd   re   r   r   r   )N)ru   rD   rv   rw   re   r   r   r   )r]   rO   r^   rO   r8   r_   r`   rO   rN   r   r[   rc   re   r   r   r   )ru   rD   r   r   )ru   rD   r   rD   r   r   )__name__
__module____qualname____doc__r   r+   rM   __annotations__rN   rR   rS   r   rY   classmethodrt   r   r   r   r   r   r   r   rj   r=   r*   rK   rK      s        Q Qf %(:;;;F;;;;'L-#N####EHF_'"""   #"  *,EIRV'+/G /G /G /G /G [/Gd ?C\ \ \ \ \|  RV+S +S +S +S +S [+S\ ?C` ` ` ` `D
 
 
 
2   0
 
 
 
(     r=   rK   )r   r   )r   r-   )r1   r2   r   r2   )r>   r?   r   r@   )r>   r?   r   rG   )-
__future__r   typingr   r   r   r   r   r	   r
   r   &langchain.agents.openai_assistant.baser   r   langchain_core._apir   langchain_core.callbacksr   langchain_core.loadr   langchain_core.runnablesr   r   langchain_core.toolsr   %langchain_core.utils.function_callingr   pydanticr   r   r   typing_extensionsr   r$   ro   r   openai.types.beta.assistantr   AssistantToolResourcesr+   r0   r<   rF   rI   rK   rj   r=   r*   <module>r      s#   " " " " " "	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 W V V V V V V V $ $ $ $ $ $ 4 4 4 4 4 4 % % % % % % B B B B B B B B ) ) ) ) ) ) H H H H H H 6 6 6 6 6 6 6 6 6 6 " " " " " " TMMM&&&&&&SSSSSS   2   2   *   *, , , ,* d d d d d 7 d d d d dr=   