Merge branch 'test-manager-api' into main

This commit is contained in:
hrz
2025-03-29 17:11:58 +08:00
committed by GitHub
22 changed files with 486 additions and 125 deletions
+1
View File
@@ -156,3 +156,4 @@ main/manager-web/node_modules
main/xiaozhi-server/models/SenseVoiceSmall/model.pt
main/xiaozhi-server/models/sherpa-onnx*
my_wakeup_words.mp3
main/manager-api/.vscode
+25
View File
@@ -11,6 +11,7 @@ manager-api 该项目基于SpringBoot框架开发。
JDK 21
Maven 3.8+
MySQL 8.0+
Redis 5.0+
Vue 3.x
# 创建数据库
@@ -43,6 +44,30 @@ spring:
password: 123456
```
# 连接Redis
如果还没有Redis,你可以通过docker安装redis
```
docker run --name xiaozhi-esp32-server-redis -d -p 6379:6379 redis
```
# 确认项目Redis连接信息
`src/main/resources/application-dev.yml`中配置Redis连接信息
```
spring:
data:
redis:
host: localhost
port: 6379
password:
database: 0
```
# 测试启动
本项目为SpringBoot项目,启动方式为:
+6 -1
View File
@@ -27,7 +27,6 @@
<shiro.version>2.0.2</shiro.version>
<captcha.version>1.6.2</captcha.version>
<guava.version>33.0.0-jre</guava.version>
<easyexcel.version>3.3.2</easyexcel.version>
<liquibase-core.version>4.20.0</liquibase-core.version>
</properties>
@@ -168,6 +167,12 @@
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- SLF4J + Log4j2 实现(可选) -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.20.0</version>
</dependency>
</dependencies>
<!-- 阿里云maven仓库 -->
@@ -1,17 +1,17 @@
package xiaozhi.common.convert;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
/**
* 日期转换
* Copyright (c) 人人开源 All rights reserved.
@@ -1,13 +1,26 @@
package xiaozhi.modules.agent.controller;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.AllArgsConstructor;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.web.bind.annotation.*;
import xiaozhi.common.constant.Constant;
import xiaozhi.common.page.PageData;
import xiaozhi.common.user.UserDetail;
@@ -19,17 +32,13 @@ import xiaozhi.modules.agent.entity.AgentEntity;
import xiaozhi.modules.agent.service.AgentService;
import xiaozhi.modules.security.user.SecurityUser;
import java.util.Date;
import java.util.List;
import java.util.Map;
@Tag(name = "智能体管理")
@AllArgsConstructor
@RestController
@RequestMapping("/agent")
public class AgentController {
private final AgentService agentService;
@GetMapping("/list")
@Operation(summary = "获取用户智能体列表")
@RequiresPermissions("sys:role:normal")
@@ -38,7 +47,7 @@ public class AgentController {
List<AgentEntity> agents = agentService.getUserAgents(user.getId());
return new Result<List<AgentEntity>>().ok(agents);
}
@GetMapping("/all")
@Operation(summary = "智能体列表(管理员)")
@RequiresPermissions("sys:role:superAdmin")
@@ -51,7 +60,7 @@ public class AgentController {
PageData<AgentEntity> page = agentService.adminAgentList(params);
return new Result<PageData<AgentEntity>>().ok(page);
}
@GetMapping("/{id}")
@Operation(summary = "获取智能体详情")
@RequiresPermissions("sys:role:normal")
@@ -59,25 +68,25 @@ public class AgentController {
AgentEntity agent = agentService.getAgentById(id);
return new Result<AgentEntity>().ok(agent);
}
@PostMapping
@Operation(summary = "创建智能体")
@RequiresPermissions("sys:role:normal")
public Result<Void> save(@RequestBody @Valid AgentCreateDTO dto) {
AgentEntity entity = ConvertUtils.sourceToTarget(dto, AgentEntity.class);
// 设置用户ID和创建者信息
UserDetail user = SecurityUser.getUser();
entity.setUserId(user.getId());
entity.setCreator(user.getId());
entity.setCreatedAt(new Date());
// ID、智能体编码和排序会在Service层自动生成
agentService.insert(entity);
return new Result<>();
}
@PutMapping
@Operation(summary = "更新智能体")
@RequiresPermissions("sys:role:normal")
@@ -87,7 +96,7 @@ public class AgentController {
if (existingEntity == null) {
return new Result<Void>().error("智能体不存在");
}
// 只更新提供的非空字段
if (dto.getAgentName() != null) {
existingEntity.setAgentName(dto.getAgentName());
@@ -128,17 +137,17 @@ public class AgentController {
if (dto.getSort() != null) {
existingEntity.setSort(dto.getSort());
}
// 设置更新者信息
UserDetail user = SecurityUser.getUser();
existingEntity.setUpdater(user.getId());
existingEntity.setUpdatedAt(new Date());
agentService.updateById(existingEntity);
return new Result<>();
}
@DeleteMapping("/{id}")
@Operation(summary = "删除智能体")
@RequiresPermissions("sys:role:normal")
@@ -146,4 +155,4 @@ public class AgentController {
agentService.deleteById(id);
return new Result<>();
}
}
}
@@ -0,0 +1,37 @@
package xiaozhi.modules.agent.controller;
import java.util.List;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import xiaozhi.common.utils.Result;
import xiaozhi.modules.agent.entity.AgentTemplateEntity;
import xiaozhi.modules.agent.service.AgentTemplateService;
@Slf4j
@Tag(name = "智能体模板管理")
@AllArgsConstructor
@RestController
@RequestMapping("/user/agent/template")
public class AgentTemplateController {
private final AgentTemplateService agentTemplateService;
@GetMapping
@Operation(summary = "智能体模板模板列表")
@RequiresPermissions("sys:role:normal")
public Result<List<AgentTemplateEntity>> templateList() {
List<AgentTemplateEntity> list = agentTemplateService
.list(new QueryWrapper<AgentTemplateEntity>().orderByAsc("sort"));
return new Result<List<AgentTemplateEntity>>().ok(list);
}
}
@@ -0,0 +1,20 @@
package xiaozhi.modules.agent.dao;
import org.apache.ibatis.annotations.Mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import xiaozhi.modules.agent.entity.AgentTemplateEntity;
/**
* @author chenerlei
* @description 针对表【ai_agent_template(智能体配置模板表)】的数据库操作Mapper
* @createDate 2025-03-22 11:48:18
*/
@Mapper
public interface AgentTemplateDao extends BaseMapper<AgentTemplateEntity> {
}
@@ -0,0 +1,115 @@
package xiaozhi.modules.agent.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.util.Date;
import lombok.Data;
/**
* 智能体配置模板表
* @TableName ai_agent_template
*/
@TableName(value ="ai_agent_template")
@Data
public class AgentTemplateEntity implements Serializable {
/**
* 智能体唯一标识
*/
@TableId
private String id;
/**
* 智能体编码
*/
private String agentCode;
/**
* 智能体名称
*/
private String agentName;
/**
* 语音识别模型标识
*/
private String asrModelId;
/**
* 语音活动检测标识
*/
private String vadModelId;
/**
* 大语言模型标识
*/
private String llmModelId;
/**
* 语音合成模型标识
*/
private String ttsModelId;
/**
* 音色标识
*/
private String ttsVoiceId;
/**
* 记忆模型标识
*/
private String memoryModelId;
/**
* 意图模型标识
*/
private String intentModelId;
/**
* 角色设定参数
*/
private String systemPrompt;
/**
* 语言编码
*/
private String langCode;
/**
* 交互语种
*/
private String language;
/**
* 排序权重
*/
private Integer sort;
/**
* 是否默认模板:1:是,0:不是
*/
private Integer isDefault;
/**
* 创建者 ID
*/
private Long creator;
/**
* 创建时间
*/
private Date createdAt;
/**
* 更新者 ID
*/
private Long updater;
/**
* 更新时间
*/
private Date updatedAt;
@TableField(exist = false)
private static final long serialVersionUID = 1L;
}
@@ -0,0 +1,14 @@
package xiaozhi.modules.agent.service;
import xiaozhi.modules.agent.entity.AgentTemplateEntity;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* @author chenerlei
* @description 针对表【ai_agent_template(智能体配置模板表)】的数据库操作Service
* @createDate 2025-03-22 11:48:18
*/
public interface AgentTemplateService extends IService<AgentTemplateEntity> {
}
@@ -1,64 +1,65 @@
package xiaozhi.modules.agent.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springframework.stereotype.Service;
import xiaozhi.common.page.PageData;
import xiaozhi.common.service.impl.BaseServiceImpl;
import xiaozhi.modules.agent.dao.AgentDao;
import xiaozhi.modules.agent.entity.AgentEntity;
import xiaozhi.modules.agent.service.AgentService;
import java.util.List;
import java.util.Map;
import java.util.UUID;
@Service
public class AgentServiceImpl extends BaseServiceImpl<AgentDao, AgentEntity> implements AgentService {
private final AgentDao agentDao;
public AgentServiceImpl(AgentDao agentDao) {
this.agentDao = agentDao;
}
@Override
public List<AgentEntity> getUserAgents(Long userId) {
QueryWrapper<AgentEntity> wrapper = new QueryWrapper<>();
wrapper.eq("user_id", userId);
return agentDao.selectList(wrapper);
}
@Override
public PageData<AgentEntity> adminAgentList(Map<String, Object> params) {
IPage<AgentEntity> page = agentDao.selectPage(
getPage(params, "sort", true),
new QueryWrapper<>()
);
return new PageData<>(page.getRecords(), page.getTotal());
}
@Override
public AgentEntity getAgentById(String id) {
return agentDao.selectById(id);
}
@Override
public boolean insert(AgentEntity entity) {
// 如果ID为空,自动生成一个UUID作为ID
if (entity.getId() == null || entity.getId().trim().isEmpty()) {
entity.setId(UUID.randomUUID().toString().replace("-", ""));
}
// 如果智能体编码为空,自动生成一个带前缀的编码
if (entity.getAgentCode() == null || entity.getAgentCode().trim().isEmpty()) {
entity.setAgentCode("AGT_" + System.currentTimeMillis());
}
// 如果排序字段为空,设置默认值0
if (entity.getSort() == null) {
entity.setSort(0);
}
return super.insert(entity);
}
}
package xiaozhi.modules.agent.service.impl;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import xiaozhi.common.page.PageData;
import xiaozhi.common.service.impl.BaseServiceImpl;
import xiaozhi.modules.agent.dao.AgentDao;
import xiaozhi.modules.agent.entity.AgentEntity;
import xiaozhi.modules.agent.service.AgentService;
@Service
public class AgentServiceImpl extends BaseServiceImpl<AgentDao, AgentEntity> implements AgentService {
private final AgentDao agentDao;
public AgentServiceImpl(AgentDao agentDao) {
this.agentDao = agentDao;
}
@Override
public List<AgentEntity> getUserAgents(Long userId) {
QueryWrapper<AgentEntity> wrapper = new QueryWrapper<>();
wrapper.eq("user_id", userId);
return agentDao.selectList(wrapper);
}
@Override
public PageData<AgentEntity> adminAgentList(Map<String, Object> params) {
IPage<AgentEntity> page = agentDao.selectPage(
getPage(params, "sort", true),
new QueryWrapper<>());
return new PageData<>(page.getRecords(), page.getTotal());
}
@Override
public AgentEntity getAgentById(String id) {
return agentDao.selectById(id);
}
@Override
public boolean insert(AgentEntity entity) {
// 如果ID为空,自动生成一个UUID作为ID
if (entity.getId() == null || entity.getId().trim().isEmpty()) {
entity.setId(UUID.randomUUID().toString().replace("-", ""));
}
// 如果智能体编码为空,自动生成一个带前缀的编码
if (entity.getAgentCode() == null || entity.getAgentCode().trim().isEmpty()) {
entity.setAgentCode("AGT_" + System.currentTimeMillis());
}
// 如果排序字段为空,设置默认值0
if (entity.getSort() == null) {
entity.setSort(0);
}
return super.insert(entity);
}
}
@@ -0,0 +1,20 @@
package xiaozhi.modules.agent.service.impl;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import xiaozhi.modules.agent.dao.AgentTemplateDao;
import xiaozhi.modules.agent.entity.AgentTemplateEntity;
import xiaozhi.modules.agent.service.AgentTemplateService;
/**
* @author chenerlei
* @description 针对表【ai_agent_template(智能体配置模板表)】的数据库操作Service实现
* @createDate 2025-03-22 11:48:18
*/
@Service
public class AgentTemplateServiceImpl extends ServiceImpl<AgentTemplateDao, AgentTemplateEntity>
implements AgentTemplateService {
}
@@ -0,0 +1,13 @@
package xiaozhi.modules.agent.vo;
import lombok.Data;
import xiaozhi.modules.agent.entity.AgentTemplateEntity;
@Data
public class AgentTemplateVO extends AgentTemplateEntity {
// 角色音色
private String ttsModelName;
// 角色模型
private String llmModelName;
}
@@ -1,6 +1,7 @@
package xiaozhi.modules.device.service;
import xiaozhi.common.page.PageData;
import xiaozhi.common.service.BaseService;
import xiaozhi.modules.device.dto.DeviceHeaderDTO;
import xiaozhi.modules.device.dto.DeviceReportReqDTO;
import xiaozhi.modules.device.dto.DeviceReportRespDTO;
@@ -19,11 +20,11 @@ public interface DeviceService {
DeviceReportRespDTO checkDeviceActive(String macAddress, String deviceId, String clientId, DeviceReportReqDTO deviceReport);
DeviceEntity bindDevice(Long userId, DeviceHeaderDTO deviceHeader);
List<DeviceEntity> getUserDevices(Long userId);
void unbindDevice(Long userId, Long deviceId);
PageData<DeviceEntity> adminDeviceList(Map<String, Object> params);
Boolean deviceActivation(String activationCode);
@@ -0,0 +1,55 @@
package xiaozhi.modules.device.vo;
import lombok.Data;
@Data
public class DeviceOtaVO {
private Activation activation;
private Mqtt mqtt;
private ServerTime server_time;
private Firmware firmware;
private String error;
@Data
public static class Activation {
private String code;
private String message;
public Activation() {
}
public Activation(String code, String message) {
this.code = code;
this.message = message;
}
}
@Data
public class Mqtt {
}
@Data
public static class ServerTime {
private Long timestamp;
private Integer timezone_offset;
public ServerTime() {
}
public ServerTime(Long timestamp, Integer timezone_offset) {
this.timestamp = timestamp;
this.timezone_offset = timezone_offset;
}
}
@Data
public static class Firmware {
private String version;
private String url;
public Firmware() {
}
public Firmware(String version, String url) {
this.version = version;
this.url = url;
}
}
}
@@ -74,6 +74,7 @@ public class ShiroConfig {
filterMap.put("/user/captcha", "anon");
filterMap.put("/user/login", "anon");
filterMap.put("/user/register", "anon");
filterMap.put("/ota/**", "anon");
filterMap.put("/**", "oauth2");
shiroFilter.setFilterChainDefinitionMap(filterMap);
@@ -1,12 +1,18 @@
package xiaozhi.modules.security.controller;
import java.io.IOException;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import lombok.AllArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;
import xiaozhi.common.exception.ErrorCode;
import xiaozhi.common.exception.RenException;
import xiaozhi.common.page.TokenDTO;
@@ -22,8 +28,6 @@ import xiaozhi.modules.sys.dto.PasswordDTO;
import xiaozhi.modules.sys.dto.SysUserDTO;
import xiaozhi.modules.sys.service.SysUserService;
import java.io.IOException;
/**
* 登录控制层
*/
@@ -36,14 +40,13 @@ public class LoginController {
private final SysUserTokenService sysUserTokenService;
private final CaptchaService captchaService;
@GetMapping("/captcha")
@Operation(summary = "验证码")
public void captcha(HttpServletResponse response, String uuid) throws IOException {
//uuid不能为空
// uuid不能为空
AssertUtils.isBlank(uuid, ErrorCode.IDENTIFIER_NOT_NULL);
//生成验证码
// 生成验证码
captchaService.create(response, uuid);
}
@@ -55,11 +55,6 @@ public class Oauth2Filter extends AuthenticatingFilter {
//获取请求token,如果token不存在,直接返回401
String token = getRequestToken((HttpServletRequest) request);
// TODO 调试接口,临时取消登录限制,需要 token 参数的除外
// if (true) {
// return true;
// }
if (StringUtils.isBlank(token)) {
logger.warn("onAccessDenied:token is empty");
@@ -15,7 +15,7 @@ spring:
druid:
#MySQL
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/xiaozhi_esp32_server?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true
url: jdbc:mysql://127.0.0.1:3306/xiaozhi_esp32_server?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true
username: root
password: 123456
initial-size: 10
@@ -41,4 +41,17 @@ spring:
merge-sql: false
wall:
config:
multi-statement-allow: true
multi-statement-allow: true
data:
redis:
host: 127.0.0.1 # Redis服务器地址
port: 6379 # Redis服务器连接端口
password: # Redis服务器连接密码(默认为空)
database: 0 # Redis数据库索引(默认为0
timeout: 10000ms # 连接超时时间(毫秒)
lettuce:
pool:
max-active: 8 # 连接池最大连接数(使用负值表示没有限制)
max-idle: 8 # 连接池中的最大空闲连接
min-idle: 0 # 连接池中的最小空闲连接
shutdown-timeout: 100ms # 客户端优雅关闭的等待时间
@@ -24,21 +24,9 @@ spring:
max-file-size: 100MB
max-request-size: 100MB
enabled: true
data:
redis:
database: 0
host: 127.0.0.1
port: 6379
password: # 密码(默认为空)
timeout: 6000ms # 连接超时时长(毫秒)
lettuce:
pool:
max-active: 1000 # 连接池最大连接数(使用负值表示没有限制)
max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)
max-idle: 10 # 连接池中的最大空闲连接
min-idle: 5 # 连接池中的最小空闲连接
main:
allow-bean-definition-overriding: true
knife4j:
enable: true
basic:
@@ -50,7 +38,7 @@ knife4j:
renren:
redis:
open: false
open: true
xss:
enabled: true
exclude-urls:
@@ -59,7 +47,7 @@ renren:
mybatis-plus:
mapper-locations: classpath*:/mapper/**/*.xml
#实体扫描,多个package用逗号或者分号分隔
typeAliasesPackage: xiaozhi.modules.*.entity
typeAliasesPackage: xiaozhi.modules.*.entity;xiaozhi.modules.*.domain
global-config:
#数据库相关配置
db-config:
@@ -0,0 +1,32 @@
-- 修改字段名
ALTER TABLE `ai_agent` RENAME COLUMN `mem_model_id` TO `memory_model_id`;
ALTER TABLE `ai_agent_template` RENAME COLUMN `mem_model_id` TO `memory_model_id`;
-- 添加字段
ALTER TABLE `ai_agent_template` ADD COLUMN `is_default` tinyint(1) NULL DEFAULT 0 COMMENT '是否默认模板:1:是,0:不是' AFTER `sort`;
-- 初始化智能体模板数据
INSERT INTO `ai_agent_template` VALUES ('9406648b5cc5fde1b8aa335b6f8b4f76', '小智', '湾湾小何', '45f8b0d6dd3d4bfa8a28e6e0f5912d45', '23e7c9d090ea4d1e9b25f4c8d732a3a1', 'e9f2d891afbe4632b13a47c7a8c6e03d', 'd50b06e9b8104d0d9c0f7316d258abcb', 'fcac83266edadd5a3125f06cfee1906b', 'e2274b90e89ddda85207f55484d8b528', 'c4e12f874a3f4aa99f5b2c18e15d407b', '你是一个叫{{assistant_name}}的台湾女孩,说话机车,声音好听,习惯简短表达,爱用网络梗。\n请注意,要像一个人一样说话,请不要回复表情符号、代码、和xml标签。\n现在我正在和你进行语音聊天,我们开始吧。\n如果用户希望结束对话,请在最后说“拜拜”或“再见”。', 'zh', '中文', 1, 1, NULL, NULL, NULL, NULL);
INSERT INTO `ai_agent_template` VALUES ('0ca32eb728c949e58b1000b2e401f90c', '小智', '通用男声', '45f8b0d6dd3d4bfa8a28e6e0f5912d45', '23e7c9d090ea4d1e9b25f4c8d732a3a1', 'e9f2d891afbe4632b13a47c7a8c6e03d', '896db62c9dd74976ab0e8c14bf924d9d', '1f2e3d4c5b6a7f8e9d0c1b2a3f4e5bx2', 'e2274b90e89ddda85207f55484d8b528', 'c4e12f874a3f4aa99f5b2c18e15d407b', '你是一个叫{{assistant_name}}的男生,说话机车,声音好听,习惯简短表达,爱用网络梗。\n请注意,要像一个人一样说话,请不要回复表情符号、代码、和xml标签。\n现在我正在和你进行语音聊天,我们开始吧。\n如果用户希望结束对话,请在最后说“拜拜”或“再见”。', 'zh', '中文', 2, 0, NULL, NULL, NULL, NULL);
INSERT INTO `ai_agent_template` VALUES ('6c7d8e9f0a1b2c3d4e5f6a7b8c9d0s24', '小智', '通用女声', '45f8b0d6dd3d4bfa8a28e6e0f5912d45', '23e7c9d090ea4d1e9b25f4c8d732a3a1', 'e9f2d891afbe4632b13a47c7a8c6e03d', '896db62c9dd74976ab0e8c14bf924d9d', '9e8f7a6b5c4d3e2f1a0b9c8d7e6f5ad3', 'e2274b90e89ddda85207f55484d8b528', 'c4e12f874a3f4aa99f5b2c18e15d407b', '你是一个叫{{assistant_name}}的女生,说话机车,声音好听,习惯简短表达,爱用网络梗。\n请注意,要像一个人一样说话,请不要回复表情符号、代码、和xml标签。\n现在我正在和你进行语音聊天,我们开始吧。\n如果用户希望结束对话,请在最后说“拜拜”或“再见”。', 'zh', '中文', 3, 0, NULL, NULL, NULL, NULL);
INSERT INTO `ai_agent_template` VALUES ('e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b1', '小智', '阳光男生', '45f8b0d6dd3d4bfa8a28e6e0f5912d45', '23e7c9d090ea4d1e9b25f4c8d732a3a1', 'e9f2d891afbe4632b13a47c7a8c6e03d', '896db62c9dd74976ab0e8c14bf924d9d', '2b3c4d5e6f7a8b9c0d1e2f3a4b5c62a2', 'e2274b90e89ddda85207f55484d8b528', 'c4e12f874a3f4aa99f5b2c18e15d407b', '你是一个叫{{assistant_name}}的男生,说话机车,声音好听,习惯简短表达,爱用网络梗。\n请注意,要像一个人一样说话,请不要回复表情符号、代码、和xml标签。\n现在我正在和你进行语音聊天,我们开始吧。\n如果用户希望结束对话,请在最后说“拜拜”或“再见”。', 'zh', '中文', 4, 0, NULL, NULL, NULL, NULL);
INSERT INTO `ai_agent_template` VALUES ('a45b6c7d8e9f0a1b2c3d4e5f6a7b8c92', '小智', '奶气萌娃', '45f8b0d6dd3d4bfa8a28e6e0f5912d45', '23e7c9d090ea4d1e9b25f4c8d732a3a1', 'e9f2d891afbe4632b13a47c7a8c6e03d', '896db62c9dd74976ab0e8c14bf924d9d', 'f7a38c03d5644e22b6d84f8923a74c51', 'e2274b90e89ddda85207f55484d8b528', 'c4e12f874a3f4aa99f5b2c18e15d407b', '你是一个叫{{assistant_name}}的萌娃,声音可爱,习惯简短表达,爱用网络梗。\n请注意,要像一个人一样说话,请不要回复表情符号、代码、和xml标签。\n现在我正在和你进行语音聊天,我们开始吧。\n如果用户希望结束对话,请在最后说“拜拜”或“再见”。', 'zh', '中文', 5, 0, NULL, NULL, NULL, NULL);
-- 初始化模型配置数据
INSERT INTO `ai_model_config` VALUES ('23e7c9d090ea4d1e9b25f4c8d732a3a1', 'VAD', 'SileroVAD', 'SileroVAD', 1, 1, '{\"SileroVAD\": {\"model_dir\": \"models/snakers4_silero-vad\", \"threshold\": 0.5, \"min_silence_duration_ms\": 700}}', NULL, NULL, 0, NULL, NULL, NULL, NULL);
INSERT INTO `ai_model_config` VALUES ('45f8b0d6dd3d4bfa8a28e6e0f5912d45', 'ASR', 'FunASR', 'FunASR', 1, 1, '{\"FunASR\": {\"type\": \"fun_local\", \"model_dir\": \"models/SenseVoiceSmall\", \"output_dir\": \"tmp/\"}}', NULL, NULL, 0, NULL, NULL, NULL, NULL);
INSERT INTO `ai_model_config` VALUES ('e2274b90e89ddda85207f55484d8b528', 'Memory', 'nomem', 'nomem', 1, 1, '{\"mem0ai\": {\"type\": \"nomem\"}}', NULL, NULL, 0, NULL, NULL, NULL, NULL);
INSERT INTO `ai_model_config` VALUES ('3930ac3448faf621f0a120bc829dfdfa', 'Memory', 'mem_local_short', 'mem_local_short', 1, 1, '{\"mem_local_short\": {\"type\": \"mem_local_short\"}}', NULL, NULL, 0, NULL, NULL, NULL, NULL);
INSERT INTO `ai_model_config` VALUES ('a07f3d25f52340b2b2a1e8d264079e1a', 'Memory', 'mem0ai', 'mem0ai', 1, 1, '{\"mem0ai\": {\"type\": \"mem0ai\", \"api_key\": \"你的mem0ai api key\"}}', NULL, NULL, 0, NULL, NULL, NULL, NULL);
INSERT INTO `ai_model_config` VALUES ('7a1c0a8e6d0e4035b982a4c07c3a5f76', 'LLM', 'AliLLM', 'AliLLM', 1, 1, '{\"AliLLM\": {\"type\": \"openai\", \"top_k\": 50, \"top_p\": 1, \"api_key\": \"你的ali api key\", \"base_url\": \"https://dashscope.aliyuncs.com/compatible-mode/v1\", \"max_tokens\": 500, \"model_name\": \"qwen-turbo\", \"temperature\": 0.7, \"frequency_penalty\": 0}}', NULL, NULL, 0, NULL, NULL, NULL, NULL);
INSERT INTO `ai_model_config` VALUES ('e9f2d891afbe4632b13a47c7a8c6e03d', 'LLM', 'ChatGLMLLM', 'ChatGLMLLM', 1, 1, '{\"ChatGLMLLM\": {\"url\": \"https://open.bigmodel.cn/api/paas/v4/\", \"type\": \"openai\", \"api_key\": \"0415dad4014847babc3e3f03024c50a3.qH7FgTy5Yawc85fl\", \"model_name\": \"glm-4-flash\"}}', NULL, NULL, 0, NULL, NULL, NULL, NULL);
INSERT INTO `ai_model_config` VALUES ('d50b06e9b8104d0d9c0f7316d258abcb', 'TTS', 'EdgeTTS', 'EdgeTTS', 1, 1, '{\"EdgeTTS\": {\"type\": \"edge\", \"voice\": \"zh-CN-XiaoxiaoNeural\", \"output_dir\": \"tmp/\"}}', NULL, NULL, 0, NULL, NULL, NULL, NULL);
INSERT INTO `ai_model_config` VALUES ('896db62c9dd74976ab0e8c14bf924d9d', 'TTS', 'DoubaoTTS', 'DoubaoTTS', 1, 1, '{\"DoubaoTTS\": {\"type\": \"doubao\", \"appid\": \"你的火山引擎语音合成服务appid\", \"voice\": \"BV034_streaming\", \"api_url\": \"https://openspeech.bytedance.com/api/v1/tts\", \"cluster\": \"volcano_tts\", \"output_dir\": \"tmp/\", \"access_token\": \"你的火山引擎语音合成服务access_token\", \"authorization\": \"Bearer;\"}}', NULL, NULL, 0, NULL, NULL, NULL, NULL);
INSERT INTO `ai_model_config` VALUES ('c4e12f874a3f4aa99f5b2c18e15d407b', 'Intent', 'function_call', 'function_call', 1, 1, '{\"function_call\": {\"type\": \"nointent\", \"functions\": [\"change_role\", \"get_weather\", \"get_news\", \"play_music\"]}}', NULL, NULL, 0, NULL, NULL, NULL, NULL);
-- 初始化音色数据
INSERT INTO `ai_tts_voice` VALUES ('fcac83266edadd5a3125f06cfee1906b', 'd50b06e9b8104d0d9c0f7316d258abcb', '湾湾小何', 'zh-CN-XiaoxiaoNeural', '中文', 'https://lf3-static.bytednsdoc.com/obj/eden-cn/lm_hz_ihsph/ljhwZthlaukjlkulzlp/portal/bigtts/湾湾小何.mp3', NULL, 1, NULL, NULL, NULL, NULL);
INSERT INTO `ai_tts_voice` VALUES ('1f2e3d4c5b6a7f8e9d0c1b2a3f4e5bx2', '896db62c9dd74976ab0e8c14bf924d9d', '通用男声', 'BV002_streaming', '中文', 'https://lf3-speech.bytetos.com/obj/speech-tts-external/portal/Portal_Demo_BV002.mp3', NULL, 2, NULL, NULL, NULL, NULL);
INSERT INTO `ai_tts_voice` VALUES ('9e8f7a6b5c4d3e2f1a0b9c8d7e6f5ad3', '896db62c9dd74976ab0e8c14bf924d9d', '通用女声', 'BV001_streaming', '中文', 'https://lf3-speech.bytetos.com/obj/speech-tts-external/portal/Portal_Demo_BV001.mp3', NULL, 3, NULL, NULL, NULL, NULL);
INSERT INTO `ai_tts_voice` VALUES ('2b3c4d5e6f7a8b9c0d1e2f3a4b5c62a2', '896db62c9dd74976ab0e8c14bf924d9d', '阳光男生', 'BV056_streaming', '中文', 'https://lf3-speech.bytetos.com/obj/speech-tts-external/portal/Portal_Demo_BV056.mp3', NULL, 4, NULL, NULL, NULL, NULL);
INSERT INTO `ai_tts_voice` VALUES ('f7a38c03d5644e22b6d84f8923a74c51', '896db62c9dd74976ab0e8c14bf924d9d', '奶气萌娃', 'BV051_streaming', '中文', 'https://lf3-speech.bytetos.com/obj/speech-tts-external/portal/Portal_Demo_BV051.mp3', NULL, 5, NULL, NULL, NULL, NULL);
@@ -15,4 +15,11 @@ databaseChangeLog:
changes:
- sqlFile:
encoding: utf8
path: classpath:db/changelog/202503141346.sql
path: classpath:db/changelog/202503141346.sql
- changeSet:
id: 202503241020
author: dreamchen
changes:
- sqlFile:
encoding: utf8
path: classpath:db/changelog/202503241020.sql
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="xiaozhi.modules.agent.dao.AgentTemplateDao">
</mapper>