Source code for autogen_ext.tools.semantic_kernel._kernel_function_from_tool

from typing import Any, TypeVar

from autogen_core import CancellationToken
from autogen_core.tools import BaseTool
from pydantic import BaseModel
from semantic_kernel.functions import KernelFunctionFromMethod, kernel_function
from semantic_kernel.functions.kernel_parameter_metadata import KernelParameterMetadata

InputT = TypeVar("InputT", bound=BaseModel)
OutputT = TypeVar("OutputT", bound=BaseModel)


[docs] class KernelFunctionFromTool(KernelFunctionFromMethod): def __init__(self, tool: BaseTool[InputT, OutputT], plugin_name: str | None = None): # Get the pydantic model types from the tool args_type = tool.args_type() return_type = tool.return_type() # 1) Define an async function that calls the tool @kernel_function(name=tool.name, description=tool.description) async def tool_method(**kwargs: dict[str, Any]) -> Any: return await tool.run_json(kwargs, cancellation_token=CancellationToken()) # Parse schema for parameters parameters_meta: list[KernelParameterMetadata] = [] properties = tool.schema.get("parameters", {}).get("properties", {}) # Get the field types from the pydantic model field_types = args_type.model_fields for prop_name, prop_info in properties.items(): assert prop_name in field_types, f"Property {prop_name} not found in Tool {tool.name}" assert isinstance(prop_info, dict), f"Property {prop_name} is not a dict in Tool {tool.name}" # Get the actual type from the pydantic model field field_type = field_types[prop_name] parameters_meta.append( KernelParameterMetadata( name=prop_name, description=field_type.description or "", default_value=field_type.get_default(), type=prop_info.get("type", "string"), # type: ignore type_object=field_type.annotation, is_required=field_type.is_required(), ) ) # Create return parameter metadata return_parameter = KernelParameterMetadata( name="return", description=f"Result from '{tool.name}' tool", default_value=None, type="object" if issubclass(return_type, BaseModel) else "string", type_object=return_type, is_required=True, ) # Initialize the parent class super().__init__( method=tool_method, plugin_name=plugin_name, parameters=parameters_meta, return_parameter=return_parameter, additional_metadata=None, ) self._tool = tool