mirror of
https://github.com/xinnan-tech/xiaozhi-esp32-server.git
synced 2026-07-21 22:53:56 +08:00
update:添加数据库表,添加数据上下文填充功能后端部分,全模块实现数据上下文填充功能
This commit is contained in:
@@ -44,6 +44,7 @@ import xiaozhi.modules.agent.entity.AgentEntity;
|
|||||||
import xiaozhi.modules.agent.entity.AgentTemplateEntity;
|
import xiaozhi.modules.agent.entity.AgentTemplateEntity;
|
||||||
import xiaozhi.modules.agent.service.AgentChatAudioService;
|
import xiaozhi.modules.agent.service.AgentChatAudioService;
|
||||||
import xiaozhi.modules.agent.service.AgentChatHistoryService;
|
import xiaozhi.modules.agent.service.AgentChatHistoryService;
|
||||||
|
import xiaozhi.modules.agent.service.AgentContextProviderService;
|
||||||
import xiaozhi.modules.agent.service.AgentPluginMappingService;
|
import xiaozhi.modules.agent.service.AgentPluginMappingService;
|
||||||
import xiaozhi.modules.agent.service.AgentService;
|
import xiaozhi.modules.agent.service.AgentService;
|
||||||
import xiaozhi.modules.agent.service.AgentTemplateService;
|
import xiaozhi.modules.agent.service.AgentTemplateService;
|
||||||
@@ -64,6 +65,7 @@ public class AgentController {
|
|||||||
private final AgentChatHistoryService agentChatHistoryService;
|
private final AgentChatHistoryService agentChatHistoryService;
|
||||||
private final AgentChatAudioService agentChatAudioService;
|
private final AgentChatAudioService agentChatAudioService;
|
||||||
private final AgentPluginMappingService agentPluginMappingService;
|
private final AgentPluginMappingService agentPluginMappingService;
|
||||||
|
private final AgentContextProviderService agentContextProviderService;
|
||||||
private final RedisUtils redisUtils;
|
private final RedisUtils redisUtils;
|
||||||
|
|
||||||
@GetMapping("/list")
|
@GetMapping("/list")
|
||||||
@@ -135,6 +137,8 @@ public class AgentController {
|
|||||||
agentChatHistoryService.deleteByAgentId(id, true, true);
|
agentChatHistoryService.deleteByAgentId(id, true, true);
|
||||||
// 删除关联的插件
|
// 删除关联的插件
|
||||||
agentPluginMappingService.deleteByAgentId(id);
|
agentPluginMappingService.deleteByAgentId(id);
|
||||||
|
// 删除关联的上下文源配置
|
||||||
|
agentContextProviderService.deleteByAgentId(id);
|
||||||
// 再删除智能体
|
// 再删除智能体
|
||||||
agentService.deleteById(id);
|
agentService.deleteById(id);
|
||||||
return new Result<>();
|
return new Result<>();
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package xiaozhi.modules.agent.dao;
|
||||||
|
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import xiaozhi.common.dao.BaseDao;
|
||||||
|
import xiaozhi.modules.agent.entity.AgentContextProviderEntity;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface AgentContextProviderDao extends BaseDao<AgentContextProviderEntity> {
|
||||||
|
}
|
||||||
@@ -69,6 +69,9 @@ public class AgentUpdateDTO implements Serializable {
|
|||||||
@Schema(description = "排序", example = "1", nullable = true)
|
@Schema(description = "排序", example = "1", nullable = true)
|
||||||
private Integer sort;
|
private Integer sort;
|
||||||
|
|
||||||
|
@Schema(description = "上下文源配置", nullable = true)
|
||||||
|
private List<ContextProviderDTO> contextProviders;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@Schema(description = "插件函数信息")
|
@Schema(description = "插件函数信息")
|
||||||
public static class FunctionInfo implements Serializable {
|
public static class FunctionInfo implements Serializable {
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package xiaozhi.modules.agent.dto;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Schema(description = "上下文源配置DTO")
|
||||||
|
public class ContextProviderDTO implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Schema(description = "URL地址")
|
||||||
|
private String url;
|
||||||
|
|
||||||
|
@Schema(description = "请求头")
|
||||||
|
private Map<String, Object> headers;
|
||||||
|
}
|
||||||
+43
@@ -0,0 +1,43 @@
|
|||||||
|
package xiaozhi.modules.agent.entity;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
import xiaozhi.modules.agent.dto.ContextProviderDTO;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@TableName(value = "ai_agent_context_provider", autoResultMap = true)
|
||||||
|
@Schema(description = "智能体上下文源配置")
|
||||||
|
public class AgentContextProviderEntity {
|
||||||
|
|
||||||
|
@TableId(type = IdType.ASSIGN_UUID)
|
||||||
|
@Schema(description = "主键")
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
@Schema(description = "智能体ID")
|
||||||
|
private String agentId;
|
||||||
|
|
||||||
|
@Schema(description = "上下文源配置")
|
||||||
|
@TableField(typeHandler = JacksonTypeHandler.class)
|
||||||
|
private List<ContextProviderDTO> contextProviders;
|
||||||
|
|
||||||
|
@Schema(description = "创建者")
|
||||||
|
private Long creator;
|
||||||
|
|
||||||
|
@Schema(description = "创建时间")
|
||||||
|
private Date createdAt;
|
||||||
|
|
||||||
|
@Schema(description = "更新者")
|
||||||
|
private Long updater;
|
||||||
|
|
||||||
|
@Schema(description = "更新时间")
|
||||||
|
private Date updatedAt;
|
||||||
|
}
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
package xiaozhi.modules.agent.service;
|
||||||
|
|
||||||
|
import xiaozhi.common.service.BaseService;
|
||||||
|
import xiaozhi.modules.agent.entity.AgentContextProviderEntity;
|
||||||
|
|
||||||
|
public interface AgentContextProviderService extends BaseService<AgentContextProviderEntity> {
|
||||||
|
/**
|
||||||
|
* 根据智能体ID获取上下文源配置
|
||||||
|
* @param agentId 智能体ID
|
||||||
|
* @return 上下文源配置实体
|
||||||
|
*/
|
||||||
|
AgentContextProviderEntity getByAgentId(String agentId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存或更新上下文源配置
|
||||||
|
* @param entity 实体
|
||||||
|
*/
|
||||||
|
void saveOrUpdateByAgentId(AgentContextProviderEntity entity);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据智能体ID删除上下文源配置
|
||||||
|
* @param agentId 智能体ID
|
||||||
|
*/
|
||||||
|
void deleteByAgentId(String agentId);
|
||||||
|
}
|
||||||
+35
@@ -0,0 +1,35 @@
|
|||||||
|
package xiaozhi.modules.agent.service.impl;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
|
||||||
|
import xiaozhi.common.service.impl.BaseServiceImpl;
|
||||||
|
import xiaozhi.modules.agent.dao.AgentContextProviderDao;
|
||||||
|
import xiaozhi.modules.agent.entity.AgentContextProviderEntity;
|
||||||
|
import xiaozhi.modules.agent.service.AgentContextProviderService;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class AgentContextProviderServiceImpl extends BaseServiceImpl<AgentContextProviderDao, AgentContextProviderEntity> implements AgentContextProviderService {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AgentContextProviderEntity getByAgentId(String agentId) {
|
||||||
|
return baseDao.selectOne(new QueryWrapper<AgentContextProviderEntity>().eq("agent_id", agentId));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void saveOrUpdateByAgentId(AgentContextProviderEntity entity) {
|
||||||
|
AgentContextProviderEntity exist = getByAgentId(entity.getAgentId());
|
||||||
|
if (exist != null) {
|
||||||
|
entity.setId(exist.getId());
|
||||||
|
updateById(entity);
|
||||||
|
} else {
|
||||||
|
insert(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteByAgentId(String agentId) {
|
||||||
|
baseDao.delete(new QueryWrapper<AgentContextProviderEntity>().eq("agent_id", agentId));
|
||||||
|
}
|
||||||
|
}
|
||||||
+18
@@ -32,10 +32,12 @@ import xiaozhi.modules.agent.dao.AgentDao;
|
|||||||
import xiaozhi.modules.agent.dto.AgentCreateDTO;
|
import xiaozhi.modules.agent.dto.AgentCreateDTO;
|
||||||
import xiaozhi.modules.agent.dto.AgentDTO;
|
import xiaozhi.modules.agent.dto.AgentDTO;
|
||||||
import xiaozhi.modules.agent.dto.AgentUpdateDTO;
|
import xiaozhi.modules.agent.dto.AgentUpdateDTO;
|
||||||
|
import xiaozhi.modules.agent.entity.AgentContextProviderEntity;
|
||||||
import xiaozhi.modules.agent.entity.AgentEntity;
|
import xiaozhi.modules.agent.entity.AgentEntity;
|
||||||
import xiaozhi.modules.agent.entity.AgentPluginMapping;
|
import xiaozhi.modules.agent.entity.AgentPluginMapping;
|
||||||
import xiaozhi.modules.agent.entity.AgentTemplateEntity;
|
import xiaozhi.modules.agent.entity.AgentTemplateEntity;
|
||||||
import xiaozhi.modules.agent.service.AgentChatHistoryService;
|
import xiaozhi.modules.agent.service.AgentChatHistoryService;
|
||||||
|
import xiaozhi.modules.agent.service.AgentContextProviderService;
|
||||||
import xiaozhi.modules.agent.service.AgentPluginMappingService;
|
import xiaozhi.modules.agent.service.AgentPluginMappingService;
|
||||||
import xiaozhi.modules.agent.service.AgentService;
|
import xiaozhi.modules.agent.service.AgentService;
|
||||||
import xiaozhi.modules.agent.service.AgentTemplateService;
|
import xiaozhi.modules.agent.service.AgentTemplateService;
|
||||||
@@ -62,6 +64,7 @@ public class AgentServiceImpl extends BaseServiceImpl<AgentDao, AgentEntity> imp
|
|||||||
private final AgentChatHistoryService agentChatHistoryService;
|
private final AgentChatHistoryService agentChatHistoryService;
|
||||||
private final AgentTemplateService agentTemplateService;
|
private final AgentTemplateService agentTemplateService;
|
||||||
private final ModelProviderService modelProviderService;
|
private final ModelProviderService modelProviderService;
|
||||||
|
private final AgentContextProviderService agentContextProviderService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PageData<AgentEntity> adminAgentList(Map<String, Object> params) {
|
public PageData<AgentEntity> adminAgentList(Map<String, Object> params) {
|
||||||
@@ -85,6 +88,13 @@ public class AgentServiceImpl extends BaseServiceImpl<AgentDao, AgentEntity> imp
|
|||||||
agent.setChatHistoryConf(Constant.ChatHistoryConfEnum.RECORD_TEXT_AUDIO.getCode());
|
agent.setChatHistoryConf(Constant.ChatHistoryConfEnum.RECORD_TEXT_AUDIO.getCode());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 查询上下文源配置
|
||||||
|
AgentContextProviderEntity contextProviderEntity = agentContextProviderService.getByAgentId(id);
|
||||||
|
if (contextProviderEntity != null) {
|
||||||
|
agent.setContextProviders(contextProviderEntity.getContextProviders());
|
||||||
|
}
|
||||||
|
|
||||||
// 无需额外查询插件列表,已通过SQL查询出来
|
// 无需额外查询插件列表,已通过SQL查询出来
|
||||||
return agent;
|
return agent;
|
||||||
}
|
}
|
||||||
@@ -331,6 +341,14 @@ public class AgentServiceImpl extends BaseServiceImpl<AgentDao, AgentEntity> imp
|
|||||||
agentChatHistoryService.deleteByAgentId(existingEntity.getId(), true, false);
|
agentChatHistoryService.deleteByAgentId(existingEntity.getId(), true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 更新上下文源配置
|
||||||
|
if (dto.getContextProviders() != null) {
|
||||||
|
AgentContextProviderEntity contextEntity = new AgentContextProviderEntity();
|
||||||
|
contextEntity.setAgentId(agentId);
|
||||||
|
contextEntity.setContextProviders(dto.getContextProviders());
|
||||||
|
agentContextProviderService.saveOrUpdateByAgentId(contextEntity);
|
||||||
|
}
|
||||||
|
|
||||||
boolean b = validateLLMIntentParams(dto.getLlmModelId(), dto.getIntentModelId());
|
boolean b = validateLLMIntentParams(dto.getLlmModelId(), dto.getIntentModelId());
|
||||||
if (!b) {
|
if (!b) {
|
||||||
throw new RenException(ErrorCode.LLM_INTENT_PARAMS_MISMATCH);
|
throw new RenException(ErrorCode.LLM_INTENT_PARAMS_MISMATCH);
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
|
|||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
|
import xiaozhi.modules.agent.dto.ContextProviderDTO;
|
||||||
import xiaozhi.modules.agent.entity.AgentEntity;
|
import xiaozhi.modules.agent.entity.AgentEntity;
|
||||||
import xiaozhi.modules.agent.entity.AgentPluginMapping;
|
import xiaozhi.modules.agent.entity.AgentPluginMapping;
|
||||||
|
|
||||||
@@ -21,4 +22,7 @@ public class AgentInfoVO extends AgentEntity
|
|||||||
@Schema(description = "插件列表Id")
|
@Schema(description = "插件列表Id")
|
||||||
@TableField(typeHandler = JacksonTypeHandler.class)
|
@TableField(typeHandler = JacksonTypeHandler.class)
|
||||||
private List<AgentPluginMapping> functions;
|
private List<AgentPluginMapping> functions;
|
||||||
|
|
||||||
|
@Schema(description = "上下文源配置")
|
||||||
|
private List<ContextProviderDTO> contextProviders;
|
||||||
}
|
}
|
||||||
|
|||||||
+10
@@ -20,10 +20,12 @@ import xiaozhi.common.redis.RedisUtils;
|
|||||||
import xiaozhi.common.utils.ConvertUtils;
|
import xiaozhi.common.utils.ConvertUtils;
|
||||||
import xiaozhi.common.utils.JsonUtils;
|
import xiaozhi.common.utils.JsonUtils;
|
||||||
import xiaozhi.modules.agent.dao.AgentVoicePrintDao;
|
import xiaozhi.modules.agent.dao.AgentVoicePrintDao;
|
||||||
|
import xiaozhi.modules.agent.entity.AgentContextProviderEntity;
|
||||||
import xiaozhi.modules.agent.entity.AgentEntity;
|
import xiaozhi.modules.agent.entity.AgentEntity;
|
||||||
import xiaozhi.modules.agent.entity.AgentPluginMapping;
|
import xiaozhi.modules.agent.entity.AgentPluginMapping;
|
||||||
import xiaozhi.modules.agent.entity.AgentTemplateEntity;
|
import xiaozhi.modules.agent.entity.AgentTemplateEntity;
|
||||||
import xiaozhi.modules.agent.entity.AgentVoicePrintEntity;
|
import xiaozhi.modules.agent.entity.AgentVoicePrintEntity;
|
||||||
|
import xiaozhi.modules.agent.service.AgentContextProviderService;
|
||||||
import xiaozhi.modules.agent.service.AgentMcpAccessPointService;
|
import xiaozhi.modules.agent.service.AgentMcpAccessPointService;
|
||||||
import xiaozhi.modules.agent.service.AgentPluginMappingService;
|
import xiaozhi.modules.agent.service.AgentPluginMappingService;
|
||||||
import xiaozhi.modules.agent.service.AgentService;
|
import xiaozhi.modules.agent.service.AgentService;
|
||||||
@@ -53,6 +55,7 @@ public class ConfigServiceImpl implements ConfigService {
|
|||||||
private final TimbreService timbreService;
|
private final TimbreService timbreService;
|
||||||
private final AgentPluginMappingService agentPluginMappingService;
|
private final AgentPluginMappingService agentPluginMappingService;
|
||||||
private final AgentMcpAccessPointService agentMcpAccessPointService;
|
private final AgentMcpAccessPointService agentMcpAccessPointService;
|
||||||
|
private final AgentContextProviderService agentContextProviderService;
|
||||||
private final VoiceCloneService cloneVoiceService;
|
private final VoiceCloneService cloneVoiceService;
|
||||||
private final AgentVoicePrintDao agentVoicePrintDao;
|
private final AgentVoicePrintDao agentVoicePrintDao;
|
||||||
|
|
||||||
@@ -178,6 +181,13 @@ public class ConfigServiceImpl implements ConfigService {
|
|||||||
mcpEndpoint = mcpEndpoint.replace("/mcp/", "/call/");
|
mcpEndpoint = mcpEndpoint.replace("/mcp/", "/call/");
|
||||||
result.put("mcp_endpoint", mcpEndpoint);
|
result.put("mcp_endpoint", mcpEndpoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取上下文源配置
|
||||||
|
AgentContextProviderEntity contextProviderEntity = agentContextProviderService.getByAgentId(agent.getId());
|
||||||
|
if (contextProviderEntity != null && contextProviderEntity.getContextProviders() != null && !contextProviderEntity.getContextProviders().isEmpty()) {
|
||||||
|
result.put("context_providers", contextProviderEntity.getContextProviders());
|
||||||
|
}
|
||||||
|
|
||||||
// 获取声纹信息
|
// 获取声纹信息
|
||||||
buildVoiceprintConfig(agent.getId(), result);
|
buildVoiceprintConfig(agent.getId(), result);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
-- liquibase formatted sql
|
||||||
|
|
||||||
|
-- changeset xiaozhi:202512041515
|
||||||
|
CREATE TABLE ai_agent_context_provider (
|
||||||
|
id VARCHAR(32) NOT NULL COMMENT '主键',
|
||||||
|
agent_id VARCHAR(32) NOT NULL COMMENT '智能体ID',
|
||||||
|
context_providers JSON COMMENT '上下文源配置',
|
||||||
|
creator BIGINT COMMENT '创建者',
|
||||||
|
created_at DATETIME COMMENT '创建时间',
|
||||||
|
updater BIGINT COMMENT '更新者',
|
||||||
|
updated_at DATETIME COMMENT '更新时间',
|
||||||
|
PRIMARY KEY (id),
|
||||||
|
INDEX idx_agent_id (agent_id)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='智能体上下文源配置表';
|
||||||
@@ -423,3 +423,10 @@ databaseChangeLog:
|
|||||||
- sqlFile:
|
- sqlFile:
|
||||||
encoding: utf8
|
encoding: utf8
|
||||||
path: classpath:db/changelog/202511131023.sql
|
path: classpath:db/changelog/202511131023.sql
|
||||||
|
- changeSet:
|
||||||
|
id: 202512041515
|
||||||
|
author: cgd
|
||||||
|
changes:
|
||||||
|
- sqlFile:
|
||||||
|
encoding: utf8
|
||||||
|
path: classpath:db/changelog/202512041515.sql
|
||||||
|
|||||||
@@ -162,7 +162,7 @@ class ConnectionHandler:
|
|||||||
self.conn_from_mqtt_gateway = False
|
self.conn_from_mqtt_gateway = False
|
||||||
|
|
||||||
# 初始化提示词管理器
|
# 初始化提示词管理器
|
||||||
self.prompt_manager = PromptManager(config, self.logger)
|
self.prompt_manager = PromptManager(self.config, self.logger)
|
||||||
|
|
||||||
async def handle_connection(self, ws):
|
async def handle_connection(self, ws):
|
||||||
try:
|
try:
|
||||||
@@ -630,6 +630,8 @@ class ConnectionHandler:
|
|||||||
self.chat_history_conf = int(private_config["chat_history_conf"])
|
self.chat_history_conf = int(private_config["chat_history_conf"])
|
||||||
if private_config.get("mcp_endpoint", None) is not None:
|
if private_config.get("mcp_endpoint", None) is not None:
|
||||||
self.config["mcp_endpoint"] = private_config["mcp_endpoint"]
|
self.config["mcp_endpoint"] = private_config["mcp_endpoint"]
|
||||||
|
if private_config.get("context_providers", None) is not None:
|
||||||
|
self.config["context_providers"] = private_config["context_providers"]
|
||||||
|
|
||||||
# 使用 run_in_executor 在线程池中执行 initialize_modules,避免阻塞主循环
|
# 使用 run_in_executor 在线程池中执行 initialize_modules,避免阻塞主循环
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -191,7 +191,10 @@ class PromptManager:
|
|||||||
|
|
||||||
# 获取配置的上下文数据
|
# 获取配置的上下文数据
|
||||||
if hasattr(conn, "device_id") and conn.device_id:
|
if hasattr(conn, "device_id") and conn.device_id:
|
||||||
self.context_data = self.context_provider.fetch_all(conn.device_id)
|
if self.base_prompt_template and "dynamic_context" in self.base_prompt_template:
|
||||||
|
self.context_data = self.context_provider.fetch_all(conn.device_id)
|
||||||
|
else:
|
||||||
|
self.context_data = ""
|
||||||
|
|
||||||
self.logger.bind(tag=TAG).debug(f"上下文信息更新完成")
|
self.logger.bind(tag=TAG).debug(f"上下文信息更新完成")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user