Files
xiaozhi-esp32-server/main/xiaozhi-server/core/handle/functionHandler.py
T

110 lines
4.2 KiB
Python
Raw Normal View History

2025-03-15 11:48:14 +08:00
from config.logger import setup_logging
import json
from plugins_func.register import (
FunctionRegistry,
ActionResponse,
Action,
ToolType,
DeviceTypeRegistry,
)
2025-03-22 20:39:52 +08:00
from plugins_func.functions.hass_init import append_devices_to_prompt
2025-03-15 11:48:14 +08:00
TAG = __name__
class FunctionHandler:
2025-03-22 20:39:52 +08:00
def __init__(self, conn):
self.conn = conn
self.config = conn.config
self.device_type_registry = DeviceTypeRegistry()
2025-03-15 11:48:14 +08:00
self.function_registry = FunctionRegistry()
self.register_nessary_functions()
self.register_config_functions()
self.functions_desc = self.function_registry.get_all_function_desc()
func_names = self.current_support_functions()
self.modify_plugin_loader_des(func_names)
2025-03-31 22:54:37 +08:00
self.finish_init = True
2025-03-15 11:48:14 +08:00
def modify_plugin_loader_des(self, func_names):
if "plugin_loader" not in func_names:
return
# 可编辑的列表中去掉plugin_loader
surport_plugins = [func for func in func_names if func != "plugin_loader"]
func_names = ",".join(surport_plugins)
for function_desc in self.functions_desc:
if function_desc["function"]["name"] == "plugin_loader":
2025-03-31 22:54:37 +08:00
function_desc["function"]["description"] = function_desc["function"][
"description"
].replace("[plugins]", func_names)
2025-03-15 11:48:14 +08:00
break
2025-03-22 20:39:52 +08:00
2025-03-15 11:48:14 +08:00
def upload_functions_desc(self):
self.functions_desc = self.function_registry.get_all_function_desc()
def current_support_functions(self):
func_names = []
for func in self.functions_desc:
func_names.append(func["function"]["name"])
# 打印当前支持的函数列表
2025-05-07 18:06:13 +08:00
self.conn.logger.bind(tag=TAG, session_id=self.conn.session_id).info(
f"当前支持的函数列表: {func_names}"
)
2025-03-15 11:48:14 +08:00
return func_names
def get_functions(self):
"""获取功能调用配置"""
return self.functions_desc
def register_nessary_functions(self):
"""注册必要的函数"""
self.function_registry.register_function("handle_exit_intent")
self.function_registry.register_function("plugin_loader")
self.function_registry.register_function("get_time")
self.function_registry.register_function("get_lunar")
self.function_registry.register_function("handle_speaker_volume_or_screen_brightness")
2025-03-15 11:48:14 +08:00
def register_config_functions(self):
"""注册配置中的函数,可以不同客户端使用不同的配置"""
2025-04-13 18:10:17 +08:00
for func in self.config["Intent"][self.config["selected_module"]["Intent"]].get(
"functions", []
):
2025-03-15 11:48:14 +08:00
self.function_registry.register_function(func)
2025-03-22 20:39:52 +08:00
"""home assistant需要初始化提示词"""
append_devices_to_prompt(self.conn)
2025-03-15 11:48:14 +08:00
def get_function(self, name):
return self.function_registry.get_function(name)
def handle_llm_function_call(self, conn, function_call_data):
try:
function_name = function_call_data["name"]
funcItem = self.get_function(function_name)
if not funcItem:
2025-03-31 22:54:37 +08:00
return ActionResponse(
action=Action.NOTFOUND, result="没有找到对应的函数", response=""
)
2025-03-15 11:48:14 +08:00
func = funcItem.func
arguments = function_call_data["arguments"]
arguments = json.loads(arguments) if arguments else {}
2025-05-07 18:06:13 +08:00
self.conn.logger.bind(tag=TAG).debug(
f"调用函数: {function_name}, 参数: {arguments}"
)
2025-03-31 22:54:37 +08:00
if (
funcItem.type == ToolType.SYSTEM_CTL
or funcItem.type == ToolType.IOT_CTL
):
2025-03-15 11:48:14 +08:00
return func(conn, **arguments)
elif funcItem.type == ToolType.WAIT:
return func(**arguments)
elif funcItem.type == ToolType.CHANGE_SYS_PROMPT:
return func(conn, **arguments)
else:
2025-03-31 22:54:37 +08:00
return ActionResponse(
action=Action.NOTFOUND, result="没有找到对应的函数", response=""
)
2025-03-15 11:48:14 +08:00
except Exception as e:
2025-05-07 18:06:13 +08:00
self.conn.logger.bind(tag=TAG).error(f"处理function call错误: {e}")
2025-03-15 11:48:14 +08:00
return None