voice-assistant/agent/src/plugins/base_plugin.py

69 lines
2.2 KiB
Python

import inspect
from plugins.homeassistant import HomeAssistant
class BasePlugin:
def __init__(self, config: dict) -> None:
self.config = config
self.homeassistant = HomeAssistant(config)
def prompt(self) -> str | None:
return
def tools(self) -> list:
tools = []
for tool_fn in self._list_tool_methods():
tool_fn_metadata = self._get_function_metadata(tool_fn)
if "input" in tool_fn_metadata["parameters"]:
json_schema = tool_fn_metadata["parameters"]["input"].annotation.model_json_schema()
del json_schema["title"]
for k, v in json_schema["properties"].items():
del json_schema["properties"][k]["title"]
fn_to_call = self._create_function_with_kwargs(
tool_fn_metadata["parameters"]["input"].annotation, tool_fn
)
else:
json_schema = {}
fn_to_call = tool_fn
tools.append(
{
"type": "function",
"function": {
"name": tool_fn_metadata["name"],
"function_to_call": fn_to_call,
"description": tool_fn_metadata["docstring"],
"parameters": json_schema,
},
}
)
return tools
def _get_function_metadata(self, func):
function_name = func.__name__
docstring = inspect.getdoc(func)
signature = inspect.signature(func)
parameters = signature.parameters
metadata = {"name": function_name, "docstring": docstring or "", "parameters": parameters}
return metadata
def _create_function_with_kwargs(self, model_cls, original_function):
def dynamic_function(**kwargs):
model_instance = model_cls(**kwargs)
return original_function(model_instance)
return dynamic_function
def _list_tool_methods(self) -> list:
attributes = dir(self)
tool_functions = [
getattr(self, attr)
for attr in attributes
if callable(getattr(self, attr)) and attr.startswith("tool_")
]
return tool_functions