
    qi(                         d 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mZmZmZ ddlZddlmZ erddlmZ  G d de
      Z G d d	      Z G d
 de      Zy)au  Direct function wrapper utilities for LLM function calling.

This module provides utilities for wrapping "direct" functions that handle LLM
function calls. Direct functions have their metadata automatically extracted
from function signatures and docstrings, allowing them to be used without
accompanying configurations (as FunctionSchemas or in provider-specific
formats).
    N)TYPE_CHECKINGAnyCallableDictListMappingProtocolSetTupleUnionget_args
get_originget_type_hints)FunctionSchema)FunctionCallParamsc                   $    e Zd ZdZdddeddfdZy)DirectFunctiona5  Protocol for a "direct" function that handles LLM function calls.

    "Direct" functions' metadata is automatically extracted from their function signature and
    docstrings, allowing them to be used without accompanying function configurations (as
    FunctionSchemas or in provider-specific formats).
    paramsr   kwargsreturnNc                    K   yw)zExecute the direct function.

        Args:
            params: Function call parameters from the LLM service.
            **kwargs: Additional keyword arguments passed to the function.
        N )selfr   r   s      Z/opt/pipecat/venv/lib/python3.12/site-packages/pipecat/adapters/schemas/direct_function.py__call__zDirectFunction.__call__2   s      	s   )__name__
__module____qualname____doc__r   r   r       r   r   r   *   s"    %9 S T r    r   c            	           e Zd ZdZdefdZedefd       Zededdfd       Z	de
fdZd	 Zd
edeej                     deeeef   ee   f   fdZdedeeef   fdZy)BaseDirectFunctionWrapperzBase class for a wrapper around a DirectFunction.

    Provides functionality to:

    - extract metadata from the function signature and docstring
    - use that metadata to generate a corresponding FunctionSchema
    functionc                 h    | j                   j                  |       || _        | j                          y)zInitialize the direct function wrapper.

        Args:
            function: The function to wrap and extract metadata from.
        N)	__class__validate_functionr#   _initialize_metadata)r   r#   s     r   __init__z"BaseDirectFunctionWrapper.__init__E   s)     	((2 !!#r    r   c                     t        d      )a  Get the name of the special first function parameter.

        The special first parameter is ignored by metadata extraction as it's
        not relevant to the LLM (e.g., 'params' for FunctionCallParams).

        Returns:
            The name of the special first parameter.
        z8Subclasses must define the special first parameter name.)NotImplementedErrorclss    r   special_first_param_namez2BaseDirectFunctionWrapper.special_first_param_nameO   s     ""\]]r    Nc                    t        j                  |      st        d|j                   d      t	        t        j
                  |      j                  j                               }| j                         }t        |      dk(  rt        d|j                   d| d      |d   d   }||k7  rt        d|j                   d| d      y)	a%  Validate that the function meets direct function requirements.

        Args:
            function: The function to validate.

        Raises:
            Exception: If function doesn't meet requirements (not async, missing
                parameters, incorrect first parameter name).
        zDirect function z must be asyncr   z# must have at least one parameter ()z  first parameter must be named ''N)
inspectiscoroutinefunction	Exceptionr   list	signature
parametersitemsr-   len)r,   r#   r   r-   first_param_names        r   r&   z+BaseDirectFunctionWrapper.validate_function[   s     **84.x/@/@.APQQg''1<<BBDE#&#?#?#A v;!"8#4#4"55XYqXrrst  "!9Q<77"8#4#4"55UVnUoopq  8r    c                 p    t        | j                  | j                  | j                  | j                        S )zConvert the wrapped function to a FunctionSchema.

        Returns:
            A FunctionSchema instance with extracted metadata.
        )namedescription
propertiesrequired)r   r;   r<   r=   r>   )r   s    r   to_function_schemaz,BaseDirectFunctionWrapper.to_function_schemat   s/     ((]]	
 	
r    c                 J   | j                   j                  | _        t        j                  t        j                  | j                               }|j                  xs dj                         | _        | j                  | j                   |j                        \  | _        | _        y)z:Initialize metadata from function signature and docstring. N)r#   r   r;   docstring_parserparser1   getdocr<   strip_get_parameters_as_jsonschemar   r=   r>   )r   	docstrings     r   r'   z.BaseDirectFunctionWrapper._initialize_metadata   s|     MM**	 %**7>>$--+HI	 &117R>>@ *.)K)KMM9++*
&r    funcdocstring_paramsc                    t        j                  |      }t        |      }i }g }|j                  j	                         D ]  \  }}|dk(  r|t        t        |j                              k(  }	|	r0|j                  |      }
| j                  |
      ||<   |j                  t         j                  j                  u r|j                  |       |D ](  }|j                  |k(  s|j                  xs d||   d<   *  ||fS )a   Get function parameters as a dictionary of JSON schemas and a list of required parameters.

        Ignore the first parameter, as it's expected to be the "special" one.

        Args:
            func: Function to get parameters from.
            docstring_params: List of parameters extracted from the function's docstring.

        Returns:
            A tuple containing:

            - A dictionary mapping each function parameter to its JSON schema
            - A list of required parameter names
        r   rA   r<   )r1   r5   r   r6   r7   nextiterget_typehint_to_jsonschemadefault	Parameteremptyappendarg_namer<   )r   rH   rI   sighintsr=   r>   r;   paramis_first_param	type_hint	doc_params               r   rF   z7BaseDirectFunctionWrapper._get_parameters_as_jsonschema   s   " %t$
>>//1 	RKD%v~ "T$s~~*>%??N		$I  $;;IFJt }} 1 1 7 77% . R	%%-6?6K6K6QrJt$]3R-	R4 8##r    rX   c                 P   |i S |t        d      u rddiS |t        u rddiS |t        u rddiS |t        u rddiS |t        u rddiS |t
        u s|t        u rddiS |t        u s|t        u rdd	iS t        |      }t        |      }|t        u s|t        j                  u r!d
|D cg c]  }| j                  |       c}iS |t        t        t        t         t"        t$        fv r|rd	| j                  |d         dS |t
        t        fv r%t'        |      dk(  rd| j                  |d         dS t)        |d      rhi }g }t+        |dd      }t-        |      j/                         D ]-  \  }}	| j                  |	      ||<   |s|j1                  |       / d|d}
|r||
d<   |
S i S c c}w )zConvert a Python type hint to a JSON Schema.

        Args:
            type_hint: A Python type hint

        Returns:
            A dictionary representing the JSON Schema
        NtypenullstringintegernumberbooleanobjectarrayanyOfr   )r[   r7         )r[   additionalProperties__annotations__	__total__T)r[   r=   r>   )r[   strintfloatbooldictr   r4   r   r   r   r   types	UnionTyperN   tupler   setr
   r8   hasattrgetattrr   r7   rR   )r   rX   originargsargr=   r>   all_fields_required
field_name
field_typeschemas              r   rN   z1BaseDirectFunctionWrapper._typehint_to_jsonschema   s    I T
"F##H%%#I&&%H%%$I&&$)t"3H%%$)t"3G$$ I&	" U?f74PCd::3?PQQ dD%S99d#d.J.J4PQ7.STT dD\!c$i1n$d>Z>Z[_`a[b>cdd 9/0JH
 #*)[$"G*8*C*I*I*K 0&
J)-)E)Ej)Q
:&&OOJ/0
 'jAF%-z"M 	E Qs   #F#)r   r   r   r   r   r(   classmethodri   r-   r&   r   r?   r'   r   rB   DocstringParamr   r   r   rF   rN   r   r    r   r"   r"   <   s    $ $ 	^ 	^ 	^  d  0
N 

"0$0$045E5T5T0U0$	tCH~tCy(	)0$dD Dc3h Dr    r"   c                   @    e Zd ZdZedefd       Zdeeef   ddfdZ	y)	DirectFunctionWrapperzWrapper around a DirectFunction for LLM function calling.

    This class:

    - Extracts metadata from the function signature and docstring
    - Generates a corresponding FunctionSchema
    - Helps with function invocation
    r   c                      y)zGet the special first parameter name for direct functions.

        Returns:
            The string "params" which is expected as the first parameter.
        r   r   r+   s    r   r-   z.DirectFunctionWrapper.special_first_param_name  s     r    ru   r   r   c                 F   K    | j                   dd|i| d{   S 7 w)a  Invoke the wrapped function with the provided arguments.

        Args:
            args: Arguments to pass to the function.
            params: Function call parameters from the LLM service.

        Returns:
            The result of the function call.
        r   Nr   )r#   )r   ru   r   s      r   invokezDirectFunctionWrapper.invoke  s'      #T]]9&9D9999s   !!N)
r   r   r   r   r{   ri   r-   r   r   r   r   r    r   r~   r~     s?       
:c!2 
:<P 
:r    r~   )r   r1   rn   typingr   r   r   r   r   r   r	   r
   r   r   r   r   r   rB   (pipecat.adapters.schemas.function_schemar   pipecat.services.llm_servicer   r   r"   r~   r   r    r   <module>r      sZ           C?X $L L^:5 :r    