Module livekit.agents.llm.function_context
Functions
def ai_callable(*, name: str | None = None, description: str | _UseDocMarker | None = None, auto_retry: bool = False) ‑> Callable
def is_type_supported(t: type) ‑> bool
Classes
class CalledFunction (call_info: FunctionCallInfo, task: asyncio.Task[Any], result: Any | None = None, exception: BaseException | None = None)
-
CalledFunction(call_info: 'FunctionCallInfo', task: 'asyncio.Task[Any]', result: 'Any | None' = None, exception: 'BaseException | None' = None)
Expand source code
@dataclass class CalledFunction: call_info: FunctionCallInfo task: asyncio.Task[Any] result: Any | None = None exception: BaseException | None = None
Class variables
var call_info : FunctionCallInfo
var exception : BaseException | None
var result : typing.Any | None
var task : _asyncio.Task[typing.Any]
class FunctionArgInfo (name: str, description: str, type: type, default: Any, choices: tuple | None)
-
FunctionArgInfo(name: 'str', description: 'str', type: 'type', default: 'Any', choices: 'tuple | None')
Expand source code
@dataclass(frozen=True) class FunctionArgInfo: name: str description: str type: type default: Any choices: tuple | None
Class variables
var choices : tuple | None
var default : Any
var description : str
var name : str
var type : type
class FunctionCallInfo (tool_call_id: str, function_info: FunctionInfo, raw_arguments: str, arguments: dict[str, Any])
-
FunctionCallInfo(tool_call_id: 'str', function_info: 'FunctionInfo', raw_arguments: 'str', arguments: 'dict[str, Any]')
Expand source code
@dataclass(frozen=True) class FunctionCallInfo: tool_call_id: str function_info: FunctionInfo raw_arguments: str arguments: dict[str, Any] def execute(self) -> CalledFunction: function_info = self.function_info func = functools.partial(function_info.callable, **self.arguments) if asyncio.iscoroutinefunction(function_info.callable): task = asyncio.create_task(func()) else: task = asyncio.create_task(asyncio.to_thread(func)) called_fnc = CalledFunction(call_info=self, task=task) def _on_done(fut): try: called_fnc.result = fut.result() except BaseException as e: called_fnc.exception = e task.add_done_callback(_on_done) return called_fnc
Class variables
var arguments : dict[str, typing.Any]
var function_info : FunctionInfo
var raw_arguments : str
var tool_call_id : str
Methods
def execute(self) ‑> CalledFunction
class FunctionContext
-
Expand source code
class FunctionContext: def __init__(self) -> None: self._fncs = dict[str, FunctionInfo]() for _, member in inspect.getmembers(self, predicate=inspect.ismethod): if hasattr(member, METADATA_ATTR): self._register_ai_function(member) def ai_callable( self, *, name: str | None = None, description: str | _UseDocMarker | None = None, auto_retry: bool = True, ) -> Callable: def deco(f): _set_metadata(f, name=name, desc=description, auto_retry=auto_retry) self._register_ai_function(f) return deco def _register_ai_function(self, fnc: Callable) -> None: if not hasattr(fnc, METADATA_ATTR): logger.warning(f"function {fnc.__name__} does not have ai metadata") return metadata: _AIFncMetadata = getattr(fnc, METADATA_ATTR) fnc_name = metadata.name if fnc_name in self._fncs: raise ValueError(f"duplicate ai_callable name: {fnc_name}") sig = inspect.signature(fnc) # get_type_hints with include_extra=True is needed when using Annotated # using typing.get_args with param.Annotated is returning an empty tuple for some reason type_hints = typing.get_type_hints( fnc, include_extras=True ) # Annotated[T, ...] -> T args = dict[str, FunctionArgInfo]() for name, param in sig.parameters.items(): if param.kind not in ( inspect.Parameter.POSITIONAL_OR_KEYWORD, inspect.Parameter.KEYWORD_ONLY, ): raise ValueError(f"{fnc_name}: unsupported parameter kind {param.kind}") inner_th, type_info = _extract_types(type_hints[name]) if not is_type_supported(inner_th): raise ValueError( f"{fnc_name}: unsupported type {inner_th} for parameter {name}" ) desc = type_info.description if type_info else "" choices = type_info.choices if type_info else None is_optional, optional_inner = _is_optional_type(inner_th) if is_optional: # when the type is optional, only the inner type is relevant # the argument info for default would be None inner_th = optional_inner if issubclass(inner_th, enum.Enum) and not choices: # the enum must be a str or int (and at least one value) # this is verified by is_type_supported choices = tuple([item.value for item in inner_th]) inner_th = type(choices[0]) args[name] = FunctionArgInfo( name=name, description=desc, type=inner_th, default=param.default, choices=choices, ) self._fncs[metadata.name] = FunctionInfo( name=metadata.name, description=metadata.description, auto_retry=metadata.auto_retry, callable=fnc, arguments=args, ) @property def ai_functions(self) -> dict[str, FunctionInfo]: return self._fncs
Instance variables
prop ai_functions : dict[str, FunctionInfo]
-
Expand source code
@property def ai_functions(self) -> dict[str, FunctionInfo]: return self._fncs
Methods
def ai_callable(self, *, name: str | None = None, description: str | _UseDocMarker | None = None, auto_retry: bool = True) ‑> Callable
class FunctionInfo (name: str, description: str, auto_retry: bool, callable: Callable, arguments: dict[str, FunctionArgInfo])
-
FunctionInfo(name: 'str', description: 'str', auto_retry: 'bool', callable: 'Callable', arguments: 'dict[str, FunctionArgInfo]')
Expand source code
@dataclass(frozen=True) class FunctionInfo: name: str description: str auto_retry: bool callable: Callable arguments: dict[str, FunctionArgInfo]
Class variables
var arguments : dict[str, FunctionArgInfo]
var auto_retry : bool
var callable : Callable
var description : str
var name : str
class TypeInfo (description: str, choices: tuple | list[Any] = ())
-
TypeInfo(description: 'str', choices: 'tuple | list[Any]' = ()) -> 'None'
Expand source code
@dataclass(frozen=True, init=False) class TypeInfo: description: str choices: tuple def __init__(self, description: str, choices: tuple | list[Any] = tuple()) -> None: object.__setattr__(self, "description", description) if isinstance(choices, list): choices = tuple(choices) object.__setattr__(self, "choices", choices)
Class variables
var choices : tuple
var description : str