U
    >AfO                     @   sn   d dl Z d dlmZmZmZmZ d dlmZmZm	Z	 d dl
mZ d dlmZmZ dZdZeG dd	 d	ZdS )
    N)AnyCallableDictList)	componentdefault_from_dictdefault_to_dict)ChatMessage)deserialize_callableserialize_callablezgI'm sorry, I tried to run a function that did not exist. Would you like me to correct it and try again?z<Seems there was an error while running the function: {error}c                   @   s   e Zd ZdZeeef dddZeeef dddZ	e
eeef d dd	d
Zejee ee dee dddZdS )OpenAIFunctionCallera<  
    OpenAIFunctionCaller processes a list of chat messages and call Python functions when needed.

    The OpenAIFunctionCaller expects a list of ChatMessages and if there is a tool call with a function name and
    arguments, it runs the function and returns the result as a ChatMessage from role = 'function'
    available_functionsc                 C   s
   || _ dS )a+  
        Initialize the OpenAIFunctionCaller component.

        :param available_functions:
            A dictionary of available functions. This dictionary expects key value pairs of function name,
            and the function itself. For example, `{"weather_function": weather_function}`
        Nr   )selfr    r   a/tmp/pip-unpacked-wheel-ymif1429/haystack_experimental/components/tools/openai/function_caller.py__init__   s    zOpenAIFunctionCaller.__init__)returnc                 C   s4   i }| j  D ]\}}t|||< qt| |d}|S )z{
        Serializes the component to a dictionary.

        :returns:
            Dictionary with serialized data.
        r   )r   itemsr   r   )r   available_function_pathsnamefunctionZserialization_dictr   r   r   to_dict%   s
    zOpenAIFunctionCaller.to_dict)datar   c                 C   sJ   | di  d}i }| D ]\}}t|||< q||d d< t| |S )z
        Deserializes the component from a dictionary.

        :param data:
            The dictionary to deserialize from.
        :returns:
            The deserialized component.
        Zinit_parametersr   )getr   r
   r   )clsr   r   r   r   pathr   r   r   	from_dict2   s    
zOpenAIFunctionCaller.from_dict)function_repliesassistant_replies)messagesc           	      C   s   |d j d dkrt|d j}|D ]}|d d }t|d d }|| jkr| j| }z(|f |}|tjt||d W q t	k
r } z|t
tj|d W 5 d	}~X Y qX q&|t
t q&d
|iS d|iS )a  
        Evaluates `messages` and invokes available functions if the messages contain tool_calls.

        :param messages: A list of messages generated from the `OpenAIChatGenerator`
        :returns: This component returns a list of messages in one of two outputs
            - `function_replies`: List of ChatMessages containing the result of a function invocation.
                This message comes from role = 'function'. If the function name was hallucinated or wrong,
                an assistant message explaining as such is returned
            - `assistant_replies`: List of ChatMessages containing a regular assistant reply. In this case,
                there were no tool_calls in the received messages
        r   Zfinish_reasonZ
tool_callsr   r   	arguments)contentr   )errorNr   r   )metajsonloadsr"   r   appendr	   from_functiondumps	ExceptionZfrom_assistant_FUNCTION_RUN_FAILUREformat_FUNCTION_NAME_FAILURE)	r   r    Zfunction_callsZfunction_callZfunction_nameZfunction_argsZfunction_to_callZfunction_responseer   r   r   runC   s(    


,zOpenAIFunctionCaller.runN)__name__
__module____qualname____doc__r   strr   r   r   r   classmethodr   r   Zoutput_typesr   r	   r/   r   r   r   r   r      s   
r   )r%   typingr   r   r   r   Zhaystackr   r   r   Zhaystack.dataclassesr	   Zhaystack.utilsr
   r   r-   r+   r   r   r   r   r   <module>   s   