mirror of
https://github.com/xinnan-tech/xiaozhi-esp32-server.git
synced 2026-07-27 17:43:55 +08:00
update:删除模型前检查是否有引用
This commit is contained in:
+64
@@ -3,6 +3,7 @@ package xiaozhi.modules.model.service.impl;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
@@ -19,6 +20,10 @@ import xiaozhi.common.redis.RedisKeys;
|
|||||||
import xiaozhi.common.redis.RedisUtils;
|
import xiaozhi.common.redis.RedisUtils;
|
||||||
import xiaozhi.common.service.impl.BaseServiceImpl;
|
import xiaozhi.common.service.impl.BaseServiceImpl;
|
||||||
import xiaozhi.common.utils.ConvertUtils;
|
import xiaozhi.common.utils.ConvertUtils;
|
||||||
|
import xiaozhi.modules.agent.dao.AgentDao;
|
||||||
|
import xiaozhi.modules.agent.dao.AgentTemplateDao;
|
||||||
|
import xiaozhi.modules.agent.entity.AgentEntity;
|
||||||
|
import xiaozhi.modules.agent.service.AgentTemplateService;
|
||||||
import xiaozhi.modules.model.dao.ModelConfigDao;
|
import xiaozhi.modules.model.dao.ModelConfigDao;
|
||||||
import xiaozhi.modules.model.dto.ModelBasicInfoDTO;
|
import xiaozhi.modules.model.dto.ModelBasicInfoDTO;
|
||||||
import xiaozhi.modules.model.dto.ModelConfigBodyDTO;
|
import xiaozhi.modules.model.dto.ModelConfigBodyDTO;
|
||||||
@@ -36,6 +41,9 @@ public class ModelConfigServiceImpl extends BaseServiceImpl<ModelConfigDao, Mode
|
|||||||
private final ModelConfigDao modelConfigDao;
|
private final ModelConfigDao modelConfigDao;
|
||||||
private final ModelProviderService modelProviderService;
|
private final ModelProviderService modelProviderService;
|
||||||
private final RedisUtils redisUtils;
|
private final RedisUtils redisUtils;
|
||||||
|
private final AgentTemplateDao agentTemplateDao;
|
||||||
|
private final AgentTemplateService agentTemplateService;
|
||||||
|
private final AgentDao agentDao;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<ModelBasicInfoDTO> getModelCodeList(String modelType, String modelName) {
|
public List<ModelBasicInfoDTO> getModelCodeList(String modelType, String modelName) {
|
||||||
@@ -75,6 +83,7 @@ public class ModelConfigServiceImpl extends BaseServiceImpl<ModelConfigDao, Mode
|
|||||||
// 再保存供应器提供的模型
|
// 再保存供应器提供的模型
|
||||||
ModelConfigEntity modelConfigEntity = ConvertUtils.sourceToTarget(modelConfigBodyDTO, ModelConfigEntity.class);
|
ModelConfigEntity modelConfigEntity = ConvertUtils.sourceToTarget(modelConfigBodyDTO, ModelConfigEntity.class);
|
||||||
modelConfigEntity.setModelType(modelType);
|
modelConfigEntity.setModelType(modelType);
|
||||||
|
modelConfigEntity.setIsDefault(0);
|
||||||
modelConfigDao.insert(modelConfigEntity);
|
modelConfigDao.insert(modelConfigEntity);
|
||||||
return ConvertUtils.sourceToTarget(modelConfigEntity, ModelConfigDTO.class);
|
return ConvertUtils.sourceToTarget(modelConfigEntity, ModelConfigDTO.class);
|
||||||
}
|
}
|
||||||
@@ -102,9 +111,64 @@ public class ModelConfigServiceImpl extends BaseServiceImpl<ModelConfigDao, Mode
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void delete(String id) {
|
public void delete(String id) {
|
||||||
|
// 查看是否是默认
|
||||||
|
ModelConfigEntity modelConfig = modelConfigDao.selectById(id);
|
||||||
|
if (modelConfig != null && modelConfig.getIsDefault() == 1) {
|
||||||
|
throw new RenException("该模型为默认模型,请先设置其他模型为默认模型");
|
||||||
|
}
|
||||||
|
// 验证是否有引用
|
||||||
|
checkAgentReference(id);
|
||||||
|
checkIntentConfigReference(id);
|
||||||
|
|
||||||
modelConfigDao.deleteById(id);
|
modelConfigDao.deleteById(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查智能体配置是否有引用
|
||||||
|
*
|
||||||
|
* @param modelId 模型ID
|
||||||
|
*/
|
||||||
|
private void checkAgentReference(String modelId) {
|
||||||
|
List<AgentEntity> agents = agentDao.selectList(
|
||||||
|
new QueryWrapper<AgentEntity>()
|
||||||
|
.eq("vad_model_id", modelId)
|
||||||
|
.or()
|
||||||
|
.eq("asr_model_id", modelId)
|
||||||
|
.or()
|
||||||
|
.eq("llm_model_id", modelId)
|
||||||
|
.or()
|
||||||
|
.eq("tts_model_id", modelId)
|
||||||
|
.or()
|
||||||
|
.eq("mem_model_id", modelId)
|
||||||
|
.or()
|
||||||
|
.eq("intent_model_id", modelId));
|
||||||
|
if (!agents.isEmpty()) {
|
||||||
|
String agentNames = agents.stream()
|
||||||
|
.map(AgentEntity::getAgentName)
|
||||||
|
.collect(Collectors.joining("、"));
|
||||||
|
throw new RenException(String.format("该模型配置已被智能体[%s]引用,无法删除", agentNames));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查意图识别配置是否有引用
|
||||||
|
*
|
||||||
|
* @param modelId 模型ID
|
||||||
|
*/
|
||||||
|
private void checkIntentConfigReference(String modelId) {
|
||||||
|
ModelConfigEntity modelConfig = modelConfigDao.selectById(modelId);
|
||||||
|
if (modelConfig != null
|
||||||
|
&& "LLM".equals(modelConfig.getModelType() == null ? null : modelConfig.getModelType().toUpperCase())) {
|
||||||
|
List<ModelConfigEntity> intentConfigs = modelConfigDao.selectList(
|
||||||
|
new QueryWrapper<ModelConfigEntity>()
|
||||||
|
.eq("model_type", "Intent")
|
||||||
|
.like("config_json", "%" + modelId + "%"));
|
||||||
|
if (!intentConfigs.isEmpty()) {
|
||||||
|
throw new RenException("该LLM模型已被意图识别配置引用,无法删除");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getModelNameById(String id) {
|
public String getModelNameById(String id) {
|
||||||
if (StringUtils.isBlank(id)) {
|
if (StringUtils.isBlank(id)) {
|
||||||
|
|||||||
@@ -10,7 +10,10 @@ class ToolType(Enum):
|
|||||||
NONE = (1, "调用完工具后,不做其他操作")
|
NONE = (1, "调用完工具后,不做其他操作")
|
||||||
WAIT = (2, "调用工具,等待函数返回")
|
WAIT = (2, "调用工具,等待函数返回")
|
||||||
CHANGE_SYS_PROMPT = (3, "修改系统提示词,切换角色性格或职责")
|
CHANGE_SYS_PROMPT = (3, "修改系统提示词,切换角色性格或职责")
|
||||||
SYSTEM_CTL = (4, "系统控制,影响正常的对话流程,如退出、播放音乐等,需要传递conn参数")
|
SYSTEM_CTL = (
|
||||||
|
4,
|
||||||
|
"系统控制,影响正常的对话流程,如退出、播放音乐等,需要传递conn参数",
|
||||||
|
)
|
||||||
IOT_CTL = (5, "IOT设备控制,需要传递conn参数")
|
IOT_CTL = (5, "IOT设备控制,需要传递conn参数")
|
||||||
MCP_CLIENT = (6, "MCP客户端")
|
MCP_CLIENT = (6, "MCP客户端")
|
||||||
|
|
||||||
@@ -30,12 +33,14 @@ class Action(Enum):
|
|||||||
self.code = code
|
self.code = code
|
||||||
self.message = message
|
self.message = message
|
||||||
|
|
||||||
|
|
||||||
class ActionResponse:
|
class ActionResponse:
|
||||||
def __init__(self, action: Action, result, response):
|
def __init__(self, action: Action, result, response):
|
||||||
self.action = action # 动作类型
|
self.action = action # 动作类型
|
||||||
self.result = result # 动作产生的结果
|
self.result = result # 动作产生的结果
|
||||||
self.response = response # 直接回复的内容
|
self.response = response # 直接回复的内容
|
||||||
|
|
||||||
|
|
||||||
class FunctionItem:
|
class FunctionItem:
|
||||||
def __init__(self, name, description, func, type):
|
def __init__(self, name, description, func, type):
|
||||||
self.name = name
|
self.name = name
|
||||||
@@ -43,8 +48,10 @@ class FunctionItem:
|
|||||||
self.func = func
|
self.func = func
|
||||||
self.type = type
|
self.type = type
|
||||||
|
|
||||||
|
|
||||||
class DeviceTypeRegistry:
|
class DeviceTypeRegistry:
|
||||||
"""设备类型注册表,用于管理IOT设备类型及其函数"""
|
"""设备类型注册表,用于管理IOT设备类型及其函数"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.type_functions = {} # type_signature -> {func_name: FunctionItem}
|
self.type_functions = {} # type_signature -> {func_name: FunctionItem}
|
||||||
|
|
||||||
@@ -53,7 +60,9 @@ class DeviceTypeRegistry:
|
|||||||
properties = sorted(descriptor["properties"].keys())
|
properties = sorted(descriptor["properties"].keys())
|
||||||
methods = sorted(descriptor["methods"].keys())
|
methods = sorted(descriptor["methods"].keys())
|
||||||
# 使用属性和方法的组合作为设备类型的唯一标识
|
# 使用属性和方法的组合作为设备类型的唯一标识
|
||||||
type_signature = f"{descriptor['name']}:{','.join(properties)}:{','.join(methods)}"
|
type_signature = (
|
||||||
|
f"{descriptor['name']}:{','.join(properties)}:{','.join(methods)}"
|
||||||
|
)
|
||||||
return type_signature
|
return type_signature
|
||||||
|
|
||||||
def get_device_functions(self, type_id):
|
def get_device_functions(self, type_id):
|
||||||
@@ -65,18 +74,23 @@ class DeviceTypeRegistry:
|
|||||||
if type_id not in self.type_functions:
|
if type_id not in self.type_functions:
|
||||||
self.type_functions[type_id] = functions
|
self.type_functions[type_id] = functions
|
||||||
|
|
||||||
|
|
||||||
# 初始化函数注册字典
|
# 初始化函数注册字典
|
||||||
all_function_registry = {}
|
all_function_registry = {}
|
||||||
device_type_registry = DeviceTypeRegistry()
|
device_type_registry = DeviceTypeRegistry()
|
||||||
|
|
||||||
|
|
||||||
def register_function(name, desc, type=None):
|
def register_function(name, desc, type=None):
|
||||||
"""注册函数到函数注册字典的装饰器"""
|
"""注册函数到函数注册字典的装饰器"""
|
||||||
|
|
||||||
def decorator(func):
|
def decorator(func):
|
||||||
all_function_registry[name] = FunctionItem(name, desc, func, type)
|
all_function_registry[name] = FunctionItem(name, desc, func, type)
|
||||||
logger.bind(tag=TAG).debug(f"函数 '{name}' 已加载,可以注册使用")
|
logger.bind(tag=TAG).debug(f"函数 '{name}' 已加载,可以注册使用")
|
||||||
return func
|
return func
|
||||||
|
|
||||||
return decorator
|
return decorator
|
||||||
|
|
||||||
|
|
||||||
class FunctionRegistry:
|
class FunctionRegistry:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.function_registry = {}
|
self.function_registry = {}
|
||||||
@@ -89,7 +103,7 @@ class FunctionRegistry:
|
|||||||
self.logger.bind(tag=TAG).error(f"函数 '{name}' 未找到")
|
self.logger.bind(tag=TAG).error(f"函数 '{name}' 未找到")
|
||||||
return None
|
return None
|
||||||
self.function_registry[name] = func
|
self.function_registry[name] = func
|
||||||
self.logger.bind(tag=TAG).info(f"函数 '{name}' 注册成功")
|
self.logger.bind(tag=TAG).debug(f"函数 '{name}' 注册成功")
|
||||||
return func
|
return func
|
||||||
|
|
||||||
def unregister_function(self, name):
|
def unregister_function(self, name):
|
||||||
|
|||||||
Reference in New Issue
Block a user