From c82b3514579c1277c4b7672e130bd733ccf01c58 Mon Sep 17 00:00:00 2001 From: Tyke Chen <190473011+chentyke@users.noreply.github.com> Date: Wed, 8 Jul 2026 15:15:26 +0800 Subject: [PATCH] Fix agent snapshot history issues --- main/manager-api/pom.xml | 3 +- .../agent/Enums/AgentSnapshotField.java | 103 ++++ .../agent/controller/AgentController.java | 19 +- .../controller/AgentSnapshotController.java | 17 +- .../xiaozhi/modules/agent/dao/AgentDao.java | 7 + .../modules/agent/dao/AgentSnapshotDao.java | 2 + .../agent/dto/AgentSnapshotPageDTO.java | 28 + .../entity/AgentContextProviderEntity.java | 4 +- .../agent/entity/AgentSnapshotEntity.java | 6 + .../modules/agent/service/AgentService.java | 7 + .../agent/service/AgentSnapshotService.java | 11 +- .../agent/service/impl/AgentServiceImpl.java | 61 +- .../impl/AgentSnapshotServiceImpl.java | 504 ++++++++++++---- .../ContextProviderListTypeHandler.java | 31 + .../xiaozhi/modules/agent/vo/AgentInfoVO.java | 3 + .../modules/agent/vo/AgentSnapshotVO.java | 7 + .../resources/db/changelog/202607081150.sql | 7 + .../resources/db/changelog/202607081230.sql | 5 + .../db/changelog/db.changelog-master.yaml | 14 + .../main/resources/mapper/agent/AgentDao.xml | 30 +- .../mapper/agent/AgentSnapshotDao.xml | 17 + .../modules/agent/dto/AgentUpdateDTOTest.java | 44 ++ .../impl/AgentSnapshotServiceImplTest.java | 380 ++++++++++++ .../ContextProviderListTypeHandlerTest.java | 42 ++ main/manager-mobile/src/pages/agent/edit.vue | 32 +- main/manager-mobile/src/pages/agent/tools.vue | 25 +- main/manager-web/package-lock.json | 10 + main/manager-web/src/apis/module/agent.js | 15 + .../src/components/AgentSnapshotDialog.vue | 543 ++++++++++++------ main/manager-web/src/i18n/de.js | 116 +++- main/manager-web/src/i18n/en.js | 63 +- main/manager-web/src/i18n/pt_BR.js | 116 +++- main/manager-web/src/i18n/vi.js | 116 +++- main/manager-web/src/i18n/zh_CN.js | 67 ++- main/manager-web/src/i18n/zh_TW.js | 116 +++- main/manager-web/src/views/roleConfig.vue | 59 +- .../ed76d459636c2481aec828516c1b4f54.wav | Bin 228524 -> 123884 bytes .../config/manage_api_client.py | 1 + .../core/providers/asr/fun_local.py | 10 +- 39 files changed, 2268 insertions(+), 373 deletions(-) create mode 100644 main/manager-api/src/main/java/xiaozhi/modules/agent/Enums/AgentSnapshotField.java create mode 100644 main/manager-api/src/main/java/xiaozhi/modules/agent/dto/AgentSnapshotPageDTO.java create mode 100644 main/manager-api/src/main/java/xiaozhi/modules/agent/typehandler/ContextProviderListTypeHandler.java create mode 100644 main/manager-api/src/main/resources/db/changelog/202607081150.sql create mode 100644 main/manager-api/src/main/resources/db/changelog/202607081230.sql create mode 100644 main/manager-api/src/test/java/xiaozhi/modules/agent/dto/AgentUpdateDTOTest.java create mode 100644 main/manager-api/src/test/java/xiaozhi/modules/agent/service/impl/AgentSnapshotServiceImplTest.java create mode 100644 main/manager-api/src/test/java/xiaozhi/modules/agent/typehandler/ContextProviderListTypeHandlerTest.java diff --git a/main/manager-api/pom.xml b/main/manager-api/pom.xml index b3798571..5981f4b2 100644 --- a/main/manager-api/pom.xml +++ b/main/manager-api/pom.xml @@ -32,6 +32,7 @@ 4.20.0 4.1.0 3.4.0 + true @@ -275,7 +276,7 @@ org.apache.maven.plugins maven-surefire-plugin - true + ${skipTests} diff --git a/main/manager-api/src/main/java/xiaozhi/modules/agent/Enums/AgentSnapshotField.java b/main/manager-api/src/main/java/xiaozhi/modules/agent/Enums/AgentSnapshotField.java new file mode 100644 index 00000000..166b76fe --- /dev/null +++ b/main/manager-api/src/main/java/xiaozhi/modules/agent/Enums/AgentSnapshotField.java @@ -0,0 +1,103 @@ +package xiaozhi.modules.agent.Enums; + +import java.util.Arrays; +import java.util.List; +import java.util.function.BiConsumer; +import java.util.function.Function; + +import lombok.Getter; +import xiaozhi.modules.agent.dto.AgentSnapshotDataDTO; +import xiaozhi.modules.agent.dto.AgentUpdateDTO; +import xiaozhi.modules.agent.entity.AgentEntity; + +@Getter +public enum AgentSnapshotField { + AGENT_CODE("agentCode", AgentSnapshotDataDTO::getAgentCode, AgentUpdateDTO::getAgentCode, + (agent, data) -> agent.setAgentCode(data.getAgentCode())), + AGENT_NAME("agentName", AgentSnapshotDataDTO::getAgentName, AgentUpdateDTO::getAgentName, + (agent, data) -> agent.setAgentName(data.getAgentName())), + ASR_MODEL_ID("asrModelId", AgentSnapshotDataDTO::getAsrModelId, AgentUpdateDTO::getAsrModelId, + (agent, data) -> agent.setAsrModelId(data.getAsrModelId())), + VAD_MODEL_ID("vadModelId", AgentSnapshotDataDTO::getVadModelId, AgentUpdateDTO::getVadModelId, + (agent, data) -> agent.setVadModelId(data.getVadModelId())), + LLM_MODEL_ID("llmModelId", AgentSnapshotDataDTO::getLlmModelId, AgentUpdateDTO::getLlmModelId, + (agent, data) -> agent.setLlmModelId(data.getLlmModelId())), + SLM_MODEL_ID("slmModelId", AgentSnapshotDataDTO::getSlmModelId, AgentUpdateDTO::getSlmModelId, + (agent, data) -> agent.setSlmModelId(data.getSlmModelId())), + VLLM_MODEL_ID("vllmModelId", AgentSnapshotDataDTO::getVllmModelId, AgentUpdateDTO::getVllmModelId, + (agent, data) -> agent.setVllmModelId(data.getVllmModelId())), + TTS_MODEL_ID("ttsModelId", AgentSnapshotDataDTO::getTtsModelId, AgentUpdateDTO::getTtsModelId, + (agent, data) -> agent.setTtsModelId(data.getTtsModelId())), + TTS_VOICE_ID("ttsVoiceId", AgentSnapshotDataDTO::getTtsVoiceId, AgentUpdateDTO::getTtsVoiceId, + (agent, data) -> agent.setTtsVoiceId(data.getTtsVoiceId())), + TTS_LANGUAGE("ttsLanguage", AgentSnapshotDataDTO::getTtsLanguage, AgentUpdateDTO::getTtsLanguage, + (agent, data) -> agent.setTtsLanguage(data.getTtsLanguage())), + TTS_VOLUME("ttsVolume", AgentSnapshotDataDTO::getTtsVolume, AgentUpdateDTO::getTtsVolume, + (agent, data) -> agent.setTtsVolume(data.getTtsVolume())), + TTS_RATE("ttsRate", AgentSnapshotDataDTO::getTtsRate, AgentUpdateDTO::getTtsRate, + (agent, data) -> agent.setTtsRate(data.getTtsRate())), + TTS_PITCH("ttsPitch", AgentSnapshotDataDTO::getTtsPitch, AgentUpdateDTO::getTtsPitch, + (agent, data) -> agent.setTtsPitch(data.getTtsPitch())), + MEM_MODEL_ID("memModelId", AgentSnapshotDataDTO::getMemModelId, AgentUpdateDTO::getMemModelId, + (agent, data) -> agent.setMemModelId(data.getMemModelId())), + INTENT_MODEL_ID("intentModelId", AgentSnapshotDataDTO::getIntentModelId, AgentUpdateDTO::getIntentModelId, + (agent, data) -> agent.setIntentModelId(data.getIntentModelId())), + CHAT_HISTORY_CONF("chatHistoryConf", AgentSnapshotDataDTO::getChatHistoryConf, AgentUpdateDTO::getChatHistoryConf, + (agent, data) -> agent.setChatHistoryConf(data.getChatHistoryConf())), + SYSTEM_PROMPT("systemPrompt", AgentSnapshotDataDTO::getSystemPrompt, AgentUpdateDTO::getSystemPrompt, + (agent, data) -> agent.setSystemPrompt(data.getSystemPrompt())), + SUMMARY_MEMORY("summaryMemory", AgentSnapshotDataDTO::getSummaryMemory, AgentUpdateDTO::getSummaryMemory, + (agent, data) -> agent.setSummaryMemory(data.getSummaryMemory())), + LANG_CODE("langCode", AgentSnapshotDataDTO::getLangCode, AgentUpdateDTO::getLangCode, + (agent, data) -> agent.setLangCode(data.getLangCode())), + LANGUAGE("language", AgentSnapshotDataDTO::getLanguage, AgentUpdateDTO::getLanguage, + (agent, data) -> agent.setLanguage(data.getLanguage())), + SORT("sort", AgentSnapshotDataDTO::getSort, AgentUpdateDTO::getSort, + (agent, data) -> agent.setSort(data.getSort())), + FUNCTIONS("functions", AgentSnapshotDataDTO::getFunctions, AgentUpdateDTO::getFunctions, null), + CONTEXT_PROVIDERS("contextProviders", AgentSnapshotDataDTO::getContextProviders, + AgentUpdateDTO::getContextProviders, null), + CORRECT_WORD_FILE_IDS("correctWordFileIds", AgentSnapshotDataDTO::getCorrectWordFileIds, + AgentUpdateDTO::getCorrectWordFileIds, null), + TAG_NAMES("tagNames", AgentSnapshotDataDTO::getTagNames, AgentUpdateDTO::getTagNames, null); + + private final String fieldName; + private final Function snapshotGetter; + private final Function updateGetter; + private final BiConsumer restoreApplier; + + AgentSnapshotField(String fieldName, Function snapshotGetter, + Function updateGetter, + BiConsumer restoreApplier) { + this.fieldName = fieldName; + this.snapshotGetter = snapshotGetter; + this.updateGetter = updateGetter; + this.restoreApplier = restoreApplier; + } + + public static List names() { + return Arrays.stream(values()).map(AgentSnapshotField::getFieldName).toList(); + } + + public static String canonicalName(String fieldName) { + return "tags".equals(fieldName) ? TAG_NAMES.getFieldName() : fieldName; + } + + public Object snapshotValue(AgentSnapshotDataDTO data) { + return data == null ? null : snapshotGetter.apply(data); + } + + public Object updateValue(AgentUpdateDTO data) { + return data == null ? null : updateGetter.apply(data); + } + + public boolean isRestorableAgentField() { + return restoreApplier != null; + } + + public void applyTo(AgentEntity agent, AgentSnapshotDataDTO data) { + if (restoreApplier != null) { + restoreApplier.accept(agent, data); + } + } +} diff --git a/main/manager-api/src/main/java/xiaozhi/modules/agent/controller/AgentController.java b/main/manager-api/src/main/java/xiaozhi/modules/agent/controller/AgentController.java index d41004fc..eb56be23 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/agent/controller/AgentController.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/agent/controller/AgentController.java @@ -48,11 +48,8 @@ import xiaozhi.modules.agent.service.AgentTagService; import xiaozhi.modules.agent.service.AgentChatAudioService; import xiaozhi.modules.agent.service.AgentChatHistoryService; import xiaozhi.modules.agent.service.AgentChatSummaryService; -import xiaozhi.modules.agent.service.AgentContextProviderService; -import xiaozhi.modules.agent.service.AgentPluginMappingService; import xiaozhi.modules.agent.service.AgentService; import xiaozhi.modules.agent.service.AgentTemplateService; -import xiaozhi.modules.correctword.service.CorrectWordFileService; import xiaozhi.modules.agent.vo.AgentChatHistoryUserVO; import xiaozhi.modules.agent.vo.AgentInfoVO; import xiaozhi.modules.device.entity.DeviceEntity; @@ -69,12 +66,9 @@ public class AgentController { private final DeviceService deviceService; private final AgentChatHistoryService agentChatHistoryService; private final AgentChatAudioService agentChatAudioService; - private final AgentPluginMappingService agentPluginMappingService; - private final AgentContextProviderService agentContextProviderService; private final AgentChatSummaryService agentChatSummaryService; private final RedisUtils redisUtils; private final AgentTagService agentTagService; - private final CorrectWordFileService correctWordFileService; @GetMapping("/list") @Operation(summary = "获取用户智能体列表") @@ -171,18 +165,7 @@ public class AgentController { @Operation(summary = "删除智能体") @RequiresPermissions("sys:role:normal") public Result delete(@PathVariable String id) { - // 先删除关联的设备 - deviceService.deleteByAgentId(id); - // 删除关联的聊天记录 - agentChatHistoryService.deleteByAgentId(id, true, true); - // 删除关联的插件 - agentPluginMappingService.deleteByAgentId(id); - // 删除关联的上下文源配置 - agentContextProviderService.deleteByAgentId(id); - // 删除关联的替换词文件关联记录 - correctWordFileService.deleteMappingsByAgentId(id); - // 再删除智能体 - agentService.deleteById(id); + agentService.deleteAgent(id); return new Result<>(); } diff --git a/main/manager-api/src/main/java/xiaozhi/modules/agent/controller/AgentSnapshotController.java b/main/manager-api/src/main/java/xiaozhi/modules/agent/controller/AgentSnapshotController.java index fff4d81f..255e606d 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/agent/controller/AgentSnapshotController.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/agent/controller/AgentSnapshotController.java @@ -1,13 +1,12 @@ package xiaozhi.modules.agent.controller; -import java.util.Map; - import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springdoc.core.annotations.ParameterObject; +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.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import io.swagger.v3.oas.annotations.Operation; @@ -17,6 +16,7 @@ import xiaozhi.common.exception.RenException; import xiaozhi.common.page.PageData; import xiaozhi.common.user.UserDetail; import xiaozhi.common.utils.Result; +import xiaozhi.modules.agent.dto.AgentSnapshotPageDTO; import xiaozhi.modules.agent.service.AgentService; import xiaozhi.modules.agent.service.AgentSnapshotService; import xiaozhi.modules.agent.vo.AgentSnapshotVO; @@ -35,7 +35,7 @@ public class AgentSnapshotController { @RequiresPermissions("sys:role:normal") public Result> page( @PathVariable String agentId, - @RequestParam Map params) { + @ParameterObject AgentSnapshotPageDTO params) { checkPermission(agentId); return new Result>().ok(agentSnapshotService.page(agentId, params)); } @@ -57,6 +57,15 @@ public class AgentSnapshotController { return new Result<>(); } + @DeleteMapping("/{snapshotId}") + @Operation(summary = "删除智能体历史快照") + @RequiresPermissions("sys:role:normal") + public Result deleteSnapshot(@PathVariable String agentId, @PathVariable String snapshotId) { + checkPermission(agentId); + agentSnapshotService.deleteSnapshot(agentId, snapshotId); + return new Result<>(); + } + private void checkPermission(String agentId) { UserDetail user = SecurityUser.getUser(); if (user == null || !agentService.checkAgentPermission(agentId, user.getId())) { diff --git a/main/manager-api/src/main/java/xiaozhi/modules/agent/dao/AgentDao.java b/main/manager-api/src/main/java/xiaozhi/modules/agent/dao/AgentDao.java index 03e569cd..4def2b67 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/agent/dao/AgentDao.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/agent/dao/AgentDao.java @@ -36,4 +36,11 @@ public interface AgentDao extends BaseDao { * @param agentId 智能体ID */ AgentInfoVO selectAgentInfoById(@Param("agentId") String agentId); + + /** + * 锁定智能体主记录,用于串行化同一智能体的配置写入 + * + * @param agentId 智能体ID + */ + AgentEntity selectByIdForUpdate(@Param("agentId") String agentId); } diff --git a/main/manager-api/src/main/java/xiaozhi/modules/agent/dao/AgentSnapshotDao.java b/main/manager-api/src/main/java/xiaozhi/modules/agent/dao/AgentSnapshotDao.java index 9c6c54f7..955c13dd 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/agent/dao/AgentSnapshotDao.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/agent/dao/AgentSnapshotDao.java @@ -11,4 +11,6 @@ public interface AgentSnapshotDao extends BaseDao { Integer selectMaxVersionNo(@Param("agentId") String agentId); AgentSnapshotEntity selectNextSnapshot(@Param("agentId") String agentId, @Param("versionNo") Integer versionNo); + + int deleteOlderThanKeepLimit(@Param("agentId") String agentId, @Param("keepLimit") int keepLimit); } diff --git a/main/manager-api/src/main/java/xiaozhi/modules/agent/dto/AgentSnapshotPageDTO.java b/main/manager-api/src/main/java/xiaozhi/modules/agent/dto/AgentSnapshotPageDTO.java new file mode 100644 index 00000000..3f3f5d65 --- /dev/null +++ b/main/manager-api/src/main/java/xiaozhi/modules/agent/dto/AgentSnapshotPageDTO.java @@ -0,0 +1,28 @@ +package xiaozhi.modules.agent.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +@Schema(description = "智能体快照分页查询参数") +public class AgentSnapshotPageDTO { + @Schema(description = "当前页码,从1开始", example = "1") + private Integer page = 1; + + @Schema(description = "每页数量", example = "10") + private Integer limit = 10; + + @Schema(description = "版本锚点,只查询小于等于该版本号的历史快照", example = "20") + private Integer maxVersionNo; + + public int pageOrDefault() { + return page == null || page < 1 ? 1 : page; + } + + public int limitOrDefault() { + if (limit == null || limit < 1) { + return 10; + } + return limit; + } +} diff --git a/main/manager-api/src/main/java/xiaozhi/modules/agent/entity/AgentContextProviderEntity.java b/main/manager-api/src/main/java/xiaozhi/modules/agent/entity/AgentContextProviderEntity.java index 937556ef..4269b70f 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/agent/entity/AgentContextProviderEntity.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/agent/entity/AgentContextProviderEntity.java @@ -7,11 +7,11 @@ 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; +import xiaozhi.modules.agent.typehandler.ContextProviderListTypeHandler; @Data @TableName(value = "ai_agent_context_provider", autoResultMap = true) @@ -26,7 +26,7 @@ public class AgentContextProviderEntity { private String agentId; @Schema(description = "上下文源配置") - @TableField(typeHandler = JacksonTypeHandler.class) + @TableField(typeHandler = ContextProviderListTypeHandler.class) private List contextProviders; @Schema(description = "创建者") diff --git a/main/manager-api/src/main/java/xiaozhi/modules/agent/entity/AgentSnapshotEntity.java b/main/manager-api/src/main/java/xiaozhi/modules/agent/entity/AgentSnapshotEntity.java index 2783bcc7..0d99fd36 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/agent/entity/AgentSnapshotEntity.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/agent/entity/AgentSnapshotEntity.java @@ -36,6 +36,12 @@ public class AgentSnapshotEntity { @Schema(description = "快照来源") private String source; + @Schema(description = "恢复来源快照ID") + private String restoreFromSnapshotId; + + @Schema(description = "恢复来源版本号") + private Integer restoreFromVersionNo; + @Schema(description = "创建者") private Long creator; diff --git a/main/manager-api/src/main/java/xiaozhi/modules/agent/service/AgentService.java b/main/manager-api/src/main/java/xiaozhi/modules/agent/service/AgentService.java index c985ae59..709f36ad 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/agent/service/AgentService.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/agent/service/AgentService.java @@ -50,6 +50,13 @@ public interface AgentService extends BaseService { */ void deleteAgentByUserId(Long userId); + /** + * 删除智能体及其关联数据 + * + * @param agentId 智能体ID + */ + void deleteAgent(String agentId); + /** * 获取用户智能体列表 * diff --git a/main/manager-api/src/main/java/xiaozhi/modules/agent/service/AgentSnapshotService.java b/main/manager-api/src/main/java/xiaozhi/modules/agent/service/AgentSnapshotService.java index 511e420a..fe1d8e6e 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/agent/service/AgentSnapshotService.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/agent/service/AgentSnapshotService.java @@ -1,9 +1,8 @@ package xiaozhi.modules.agent.service; -import java.util.Map; - import xiaozhi.common.page.PageData; import xiaozhi.common.service.BaseService; +import xiaozhi.modules.agent.dto.AgentSnapshotPageDTO; import xiaozhi.modules.agent.dto.AgentUpdateDTO; import xiaozhi.modules.agent.entity.AgentSnapshotEntity; import xiaozhi.modules.agent.vo.AgentSnapshotVO; @@ -11,9 +10,15 @@ import xiaozhi.modules.agent.vo.AgentSnapshotVO; public interface AgentSnapshotService extends BaseService { void createSnapshot(String agentId, String source, AgentUpdateDTO pendingUpdate); - PageData page(String agentId, Map params); + PageData page(String agentId, AgentSnapshotPageDTO params); AgentSnapshotVO getSnapshot(String agentId, String snapshotId); void restoreSnapshot(String agentId, String snapshotId); + + void deleteSnapshot(String agentId, String snapshotId); + + Integer getCurrentVersionNo(String agentId); + + void deleteByAgentId(String agentId); } diff --git a/main/manager-api/src/main/java/xiaozhi/modules/agent/service/impl/AgentServiceImpl.java b/main/manager-api/src/main/java/xiaozhi/modules/agent/service/impl/AgentServiceImpl.java index 02d7a76c..75382ea7 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/agent/service/impl/AgentServiceImpl.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/agent/service/impl/AgentServiceImpl.java @@ -15,7 +15,6 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import lombok.AllArgsConstructor; @@ -108,12 +107,13 @@ public class AgentServiceImpl extends BaseServiceImpl imp agent.setContextProviders(contextProviderEntity.getContextProviders()); } - // 查询替换词文件ID列表 - List correctWordFileIds = correctWordFileService.getAgentCorrectWordFileIds(id); - agent.setCorrectWordFileIds(correctWordFileIds); - - // 无需额外查询插件列表,已通过SQL查询出来 - return agent; + // 查询替换词文件ID列表 + List correctWordFileIds = correctWordFileService.getAgentCorrectWordFileIds(id); + agent.setCorrectWordFileIds(correctWordFileIds); + agent.setCurrentVersionNo(agentSnapshotService.getCurrentVersionNo(id)); + + // 无需额外查询插件列表,已通过SQL查询出来 + return agent; } @Override @@ -136,15 +136,35 @@ public class AgentServiceImpl extends BaseServiceImpl imp return super.insert(entity); } - @Override - public void deleteAgentByUserId(Long userId) { - UpdateWrapper wrapper = new UpdateWrapper<>(); - wrapper.eq("user_id", userId); - baseDao.delete(wrapper); - } - - @Override - public List getUserAgents(Long userId, String keyword, String searchType) { + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteAgentByUserId(Long userId) { + List agents = baseDao.selectList(new QueryWrapper() + .select("id") + .eq("user_id", userId)); + for (AgentEntity agent : agents) { + deleteAgent(agent.getId()); + } + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteAgent(String agentId) { + if (agentDao.selectByIdForUpdate(agentId) == null) { + return; + } + deviceService.deleteByAgentId(agentId); + agentChatHistoryService.deleteByAgentId(agentId, true, true); + agentPluginMappingService.deleteByAgentId(agentId); + agentContextProviderService.deleteByAgentId(agentId); + correctWordFileService.deleteMappingsByAgentId(agentId); + agentTagService.deleteAgentTags(agentId); + agentSnapshotService.deleteByAgentId(agentId); + deleteById(agentId); + } + + @Override + public List getUserAgents(Long userId, String keyword, String searchType) { QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.eq("user_id", userId).orderByDesc("created_at"); @@ -285,12 +305,13 @@ public class AgentServiceImpl extends BaseServiceImpl imp @Override @Transactional(rollbackFor = Exception.class) public void updateAgentById(String agentId, AgentUpdateDTO dto, boolean createSnapshot) { - // 先查询现有实体 - AgentEntity existingEntity = this.getAgentById(agentId); - if (existingEntity == null) { + if (agentDao.selectByIdForUpdate(agentId) == null) { throw new RenException(ErrorCode.AGENT_NOT_FOUND); } + // 锁定后查询现有实体和关联配置 + AgentEntity existingEntity = this.getAgentById(agentId); + if (createSnapshot) { agentSnapshotService.createSnapshot(agentId, "config", dto); } @@ -448,7 +469,7 @@ public class AgentServiceImpl extends BaseServiceImpl imp agentTagService.saveAgentTags(agentId, dto.getTagIds(), dto.getTagNames()); } - boolean b = validateLLMIntentParams(dto.getLlmModelId(), dto.getIntentModelId()); + boolean b = validateLLMIntentParams(existingEntity.getLlmModelId(), existingEntity.getIntentModelId()); if (!b) { throw new RenException(ErrorCode.LLM_INTENT_PARAMS_MISMATCH); } diff --git a/main/manager-api/src/main/java/xiaozhi/modules/agent/service/impl/AgentSnapshotServiceImpl.java b/main/manager-api/src/main/java/xiaozhi/modules/agent/service/impl/AgentSnapshotServiceImpl.java index 8cbf7cb5..28c9320a 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/agent/service/impl/AgentSnapshotServiceImpl.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/agent/service/impl/AgentSnapshotServiceImpl.java @@ -7,15 +7,19 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.TreeMap; import java.util.UUID; +import java.util.function.Function; +import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; -import org.springframework.dao.DuplicateKeyException; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.metadata.OrderItem; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.fasterxml.jackson.core.type.TypeReference; import lombok.AllArgsConstructor; @@ -30,6 +34,7 @@ import xiaozhi.modules.agent.dao.AgentSnapshotDao; import xiaozhi.modules.agent.dao.AgentTagDao; import xiaozhi.modules.agent.dao.AgentTagRelationDao; import xiaozhi.modules.agent.dto.AgentSnapshotDataDTO; +import xiaozhi.modules.agent.dto.AgentSnapshotPageDTO; import xiaozhi.modules.agent.dto.AgentSnapshotTagDTO; import xiaozhi.modules.agent.dto.AgentUpdateDTO; import xiaozhi.modules.agent.entity.AgentContextProviderEntity; @@ -38,6 +43,7 @@ import xiaozhi.modules.agent.entity.AgentPluginMapping; import xiaozhi.modules.agent.entity.AgentSnapshotEntity; import xiaozhi.modules.agent.entity.AgentTagEntity; import xiaozhi.modules.agent.entity.AgentTagRelationEntity; +import xiaozhi.modules.agent.Enums.AgentSnapshotField; import xiaozhi.modules.agent.service.AgentChatHistoryService; import xiaozhi.modules.agent.service.AgentContextProviderService; import xiaozhi.modules.agent.service.AgentPluginMappingService; @@ -54,10 +60,14 @@ import xiaozhi.modules.security.user.SecurityUser; @AllArgsConstructor public class AgentSnapshotServiceImpl extends BaseServiceImpl implements AgentSnapshotService { + private static final int MAX_SNAPSHOTS_PER_AGENT = 100; private static final TypeReference> STRING_LIST_TYPE = new TypeReference<>() { }; private static final TypeReference> PARAM_INFO_TYPE = new TypeReference<>() { }; + private static final TypeReference> OBJECT_MAP_TYPE = new TypeReference<>() { + }; + private static final String SECRET_PLACEHOLDER = "__SNAPSHOT_SECRET_REDACTED__"; private final AgentSnapshotDao agentSnapshotDao; private final AgentDao agentDao; @@ -73,33 +83,27 @@ public class AgentSnapshotServiceImpl extends BaseServiceImpl changedFields = getChangedFields(snapshotData, pendingUpdate); if (pendingUpdate != null && changedFields.isEmpty()) { return; } - AgentInfoVO agent = agentDao.selectAgentInfoById(agentId); - if (agent == null) { - throw new RenException(ErrorCode.AGENT_NOT_FOUND); - } - - AgentSnapshotEntity entity = new AgentSnapshotEntity(); - entity.setAgentId(agentId); - entity.setUserId(agent.getUserId()); - entity.setSnapshotData(JsonUtils.toJsonString(snapshotData)); - entity.setChangedFields(JsonUtils.toJsonString(changedFields)); - entity.setSource(StringUtils.defaultIfBlank(source, "config")); - entity.setCreator(SecurityUser.getUserId()); - entity.setCreatedAt(new Date()); - insertSnapshotWithRetry(entity); + insertSnapshot(agentId, agent.getUserId(), source, snapshotData, changedFields); } @Override - public PageData page(String agentId, Map params) { - IPage page = getPage(params, "created_at", false); + @Transactional(rollbackFor = Exception.class) + public PageData page(String agentId, AgentSnapshotPageDTO params) { + ensureInitialSnapshot(agentId); + AgentSnapshotPageDTO pageParams = params == null ? new AgentSnapshotPageDTO() : params; + Page page = new Page<>(pageParams.pageOrDefault(), pageParams.limitOrDefault()); + page.addOrder(OrderItem.desc("version_no")); IPage result = agentSnapshotDao.selectPage(page, - new QueryWrapper().eq("agent_id", agentId)); + new QueryWrapper() + .eq("agent_id", agentId) + .le(pageParams.getMaxVersionNo() != null, "version_no", pageParams.getMaxVersionNo())); List list = result.getRecords().stream() .map(entity -> toVO(entity, false)) .toList(); @@ -115,44 +119,109 @@ public class AgentSnapshotServiceImpl extends BaseServiceImpl changedFields = getChangedFields(currentData, restoreData); + insertSnapshot(agentId, currentAgent.getUserId(), "restore", currentData, changedFields, + snapshot.getId(), snapshot.getVersionNo()); - AgentEntity agent = agentDao.selectById(agentId); - if (agent == null) { - throw new RenException(ErrorCode.AGENT_NOT_FOUND); - } - applyAgentFields(agent, data); + applyAgentFields(agent, restoreData); validateRestoreParams(agent); applyMemoryPolicy(agent); agent.setUpdater(SecurityUser.getUserId()); agent.setUpdatedAt(new Date()); agentDao.updateById(agent); - restoreFunctions(agentId, data.getFunctions()); - restoreContextProviders(agentId, data.getContextProviders()); - correctWordFileService.saveAgentCorrectWords(agentId, nullToEmpty(data.getCorrectWordFileIds())); - restoreTags(agentId, data); + restoreFunctions(agentId, restoreData.getFunctions()); + restoreContextProviders(agentId, restoreData.getContextProviders()); + correctWordFileService.saveAgentCorrectWords(agentId, nullToEmpty(restoreData.getCorrectWordFileIds())); + restoreTags(agentId, restoreData); } - private void insertSnapshotWithRetry(AgentSnapshotEntity entity) { - for (int attempt = 0; attempt < 3; attempt++) { - Integer maxVersionNo = agentSnapshotDao.selectMaxVersionNo(entity.getAgentId()); - entity.setVersionNo((maxVersionNo == null ? 0 : maxVersionNo) + 1); - try { - agentSnapshotDao.insert(entity); - return; - } catch (DuplicateKeyException e) { - if (attempt == 2) { - throw e; - } - } + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteSnapshot(String agentId, String snapshotId) { + AgentSnapshotEntity entity = getSnapshotEntity(agentId, snapshotId); + Integer maxVersionNo = agentSnapshotDao.selectMaxVersionNo(agentId); + if (Objects.equals(entity.getVersionNo(), maxVersionNo)) { + throw new RenException("最新历史版本不能删除"); } + deleteById(snapshotId); + } + + @Override + public Integer getCurrentVersionNo(String agentId) { + Integer maxVersionNo = agentSnapshotDao.selectMaxVersionNo(agentId); + return (maxVersionNo == null ? 0 : maxVersionNo) + 1; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteByAgentId(String agentId) { + agentSnapshotDao.delete(new QueryWrapper().eq("agent_id", agentId)); + } + + private void insertSnapshot(String agentId, Long userId, String source, AgentSnapshotDataDTO snapshotData, + List changedFields) { + insertSnapshot(agentId, userId, source, snapshotData, changedFields, null, null); + } + + private void insertSnapshot(String agentId, Long userId, String source, AgentSnapshotDataDTO snapshotData, + List changedFields, String restoreFromSnapshotId, Integer restoreFromVersionNo) { + AgentSnapshotEntity entity = new AgentSnapshotEntity(); + entity.setAgentId(agentId); + entity.setUserId(userId); + entity.setVersionNo(allocateVersionNo(agentId)); + entity.setSnapshotData(JsonUtils.toJsonString(redactSnapshotData(snapshotData))); + entity.setChangedFields(JsonUtils.toJsonString(changedFields)); + entity.setSource(StringUtils.defaultIfBlank(source, "config")); + entity.setRestoreFromSnapshotId(restoreFromSnapshotId); + entity.setRestoreFromVersionNo(restoreFromVersionNo); + entity.setCreator(SecurityUser.getUserId()); + entity.setCreatedAt(new Date()); + agentSnapshotDao.insert(entity); + pruneSnapshots(agentId); + } + + private void ensureInitialSnapshot(String agentId) { + Integer maxVersionNo = agentSnapshotDao.selectMaxVersionNo(agentId); + if (maxVersionNo != null && maxVersionNo > 0) { + return; + } + AgentEntity agent = agentDao.selectByIdForUpdate(agentId); + if (agent == null) { + throw new RenException(ErrorCode.AGENT_NOT_FOUND); + } + maxVersionNo = agentSnapshotDao.selectMaxVersionNo(agentId); + if (maxVersionNo != null && maxVersionNo > 0) { + return; + } + AgentInfoVO agentInfo = getAgentInfo(agentId); + insertSnapshot(agentId, agentInfo.getUserId(), "initial", buildSnapshotData(agentInfo), List.of("initial")); + } + + private void pruneSnapshots(String agentId) { + agentSnapshotDao.deleteOlderThanKeepLimit(agentId, MAX_SNAPSHOTS_PER_AGENT); + } + + private Integer allocateVersionNo(String agentId) { + Integer maxVersionNo = agentSnapshotDao.selectMaxVersionNo(agentId); + if (maxVersionNo == null || maxVersionNo < 0) { + throw new RenException("快照版本号生成失败"); + } + return maxVersionNo + 1; } private AgentSnapshotEntity getSnapshotEntity(String agentId, String snapshotId) { @@ -163,12 +232,19 @@ public class AgentSnapshotServiceImpl extends BaseServiceImpl tags = getSnapshotTags(agentId); + data.setContextProviders(getContextProviders(agent.getId())); + data.setCorrectWordFileIds(nullToEmpty(correctWordFileService.getAgentCorrectWordFileIds(agent.getId()))); + List tags = getSnapshotTags(agent.getId()); data.setTags(tags); data.setTagNames(tags.stream().map(AgentSnapshotTagDTO::getTagName).toList()); return data; @@ -250,64 +326,124 @@ public class AgentSnapshotServiceImpl extends BaseServiceImpl fields = new ArrayList<>(); - compare(fields, "agentCode", current.getAgentCode(), pendingUpdate.getAgentCode()); - compare(fields, "agentName", current.getAgentName(), pendingUpdate.getAgentName()); - compare(fields, "asrModelId", current.getAsrModelId(), pendingUpdate.getAsrModelId()); - compare(fields, "vadModelId", current.getVadModelId(), pendingUpdate.getVadModelId()); - compare(fields, "llmModelId", current.getLlmModelId(), pendingUpdate.getLlmModelId()); - compare(fields, "slmModelId", current.getSlmModelId(), pendingUpdate.getSlmModelId()); - compare(fields, "vllmModelId", current.getVllmModelId(), pendingUpdate.getVllmModelId()); - compare(fields, "ttsModelId", current.getTtsModelId(), pendingUpdate.getTtsModelId()); - compare(fields, "ttsVoiceId", current.getTtsVoiceId(), pendingUpdate.getTtsVoiceId()); - compare(fields, "ttsLanguage", current.getTtsLanguage(), pendingUpdate.getTtsLanguage()); - compare(fields, "ttsVolume", current.getTtsVolume(), pendingUpdate.getTtsVolume()); - compare(fields, "ttsRate", current.getTtsRate(), pendingUpdate.getTtsRate()); - compare(fields, "ttsPitch", current.getTtsPitch(), pendingUpdate.getTtsPitch()); - compare(fields, "memModelId", current.getMemModelId(), pendingUpdate.getMemModelId()); - compare(fields, "intentModelId", current.getIntentModelId(), pendingUpdate.getIntentModelId()); - compare(fields, "chatHistoryConf", current.getChatHistoryConf(), pendingUpdate.getChatHistoryConf()); - compare(fields, "systemPrompt", current.getSystemPrompt(), pendingUpdate.getSystemPrompt()); - compare(fields, "summaryMemory", current.getSummaryMemory(), pendingUpdate.getSummaryMemory()); - compare(fields, "langCode", current.getLangCode(), pendingUpdate.getLangCode()); - compare(fields, "language", current.getLanguage(), pendingUpdate.getLanguage()); - compare(fields, "sort", current.getSort(), pendingUpdate.getSort()); - compare(fields, "functions", current.getFunctions(), pendingUpdate.getFunctions()); - compare(fields, "contextProviders", current.getContextProviders(), pendingUpdate.getContextProviders()); - compare(fields, "correctWordFileIds", current.getCorrectWordFileIds(), pendingUpdate.getCorrectWordFileIds()); - compare(fields, "tagNames", current.getTagNames(), pendingUpdate.getTagNames()); - compare(fields, "tagIds", current.getTags().stream().map(AgentSnapshotTagDTO::getId).toList(), - pendingUpdate.getTagIds()); + for (AgentSnapshotField field : AgentSnapshotField.values()) { + Object nextValue = field.updateValue(pendingUpdate); + if (nextValue != null && isChanged(field, field.snapshotValue(current), nextValue)) { + fields.add(field.getFieldName()); + } + } return fields; } - private void compare(List fields, String name, T current, T next) { - if (next != null && !Objects.equals(current, next)) { - fields.add(name); + private List getChangedFields(AgentSnapshotDataDTO current, AgentSnapshotDataDTO next) { + if (next == null) { + return List.of("restore"); } + if (current == null) { + current = new AgentSnapshotDataDTO(); + } + + List fields = new ArrayList<>(); + for (AgentSnapshotField field : AgentSnapshotField.values()) { + if (isChanged(field, field.snapshotValue(current), field.snapshotValue(next))) { + fields.add(field.getFieldName()); + } + } + return fields; + } + + private boolean isChanged(AgentSnapshotField field, Object current, Object next) { + return !Objects.equals(normalizeForCompare(field, current), normalizeForCompare(field, next)); + } + + @SuppressWarnings("unchecked") + private Object normalizeForCompare(AgentSnapshotField field, Object value) { + return switch (field) { + case FUNCTIONS -> normalizeFunctions((List) value); + case CONTEXT_PROVIDERS -> normalizeSortedJsonList((List) value); + case CORRECT_WORD_FILE_IDS -> normalizeStringList((List) value); + case TAG_NAMES -> normalizeStringList((List) value); + default -> value; + }; + } + + private Map normalizeFunctions(List functions) { + Map result = new TreeMap<>(); + if (functions == null) { + return result; + } + for (AgentUpdateDTO.FunctionInfo function : functions) { + if (function == null || StringUtils.isBlank(function.getPluginId())) { + continue; + } + result.put(function.getPluginId(), normalizeMap(function.getParamInfo())); + } + return result; + } + + private List normalizeStringList(List values) { + if (values == null) { + return Collections.emptyList(); + } + return values.stream() + .filter(StringUtils::isNotBlank) + .sorted() + .toList(); + } + + private List normalizeSortedJsonList(List values) { + if (values == null) { + return Collections.emptyList(); + } + return values.stream() + .filter(Objects::nonNull) + .map(value -> JsonUtils.toJsonString(normalizeValue(value))) + .sorted() + .toList(); + } + + private Object normalizeValue(Object value) { + if (value == null) { + return null; + } + if (value instanceof Map map) { + return normalizeMap(map); + } + if (value instanceof List list) { + return list.stream().map(this::normalizeValue).toList(); + } + if (isScalarValue(value)) { + return value; + } + return normalizeMap(JsonUtils.parseObject(JsonUtils.toJsonString(value), OBJECT_MAP_TYPE)); + } + + private boolean isScalarValue(Object value) { + return value instanceof CharSequence + || value instanceof Number + || value instanceof Boolean + || value instanceof Character + || value instanceof Enum + || value instanceof Date; + } + + private Map normalizeMap(Map map) { + Map result = new TreeMap<>(); + if (map == null) { + return result; + } + map.forEach((key, value) -> { + if (key != null) { + result.put(String.valueOf(key), normalizeValue(value)); + } + }); + return result; } private void applyAgentFields(AgentEntity agent, AgentSnapshotDataDTO data) { - agent.setAgentCode(data.getAgentCode()); - agent.setAgentName(data.getAgentName()); - agent.setAsrModelId(data.getAsrModelId()); - agent.setVadModelId(data.getVadModelId()); - agent.setLlmModelId(data.getLlmModelId()); - agent.setSlmModelId(data.getSlmModelId()); - agent.setVllmModelId(data.getVllmModelId()); - agent.setTtsModelId(data.getTtsModelId()); - agent.setTtsVoiceId(data.getTtsVoiceId()); - agent.setTtsLanguage(data.getTtsLanguage()); - agent.setTtsVolume(data.getTtsVolume()); - agent.setTtsRate(data.getTtsRate()); - agent.setTtsPitch(data.getTtsPitch()); - agent.setMemModelId(data.getMemModelId()); - agent.setIntentModelId(data.getIntentModelId()); - agent.setChatHistoryConf(data.getChatHistoryConf()); - agent.setSystemPrompt(data.getSystemPrompt()); - agent.setSummaryMemory(data.getSummaryMemory()); - agent.setLangCode(data.getLangCode()); - agent.setLanguage(data.getLanguage()); - agent.setSort(data.getSort()); + for (AgentSnapshotField field : AgentSnapshotField.values()) { + field.applyTo(agent, data); + } } private void validateRestoreParams(AgentEntity agent) { @@ -406,26 +542,22 @@ public class AgentSnapshotServiceImpl extends BaseServiceImpl() .eq("tag_name", snapshotTag.getTagName()) + .eq("deleted", 0) .last("LIMIT 1")); } if (tag != null) { - if (Objects.equals(tag.getDeleted(), 1)) { - tag.setDeleted(0); - tag.setUpdater(SecurityUser.getUserId()); - tag.setUpdatedAt(now); - agentTagDao.updateById(tag); - } return tag.getId(); } AgentTagEntity newTag = new AgentTagEntity(); - if (StringUtils.isNotBlank(snapshotTag.getId())) { - newTag.setId(snapshotTag.getId()); - } + newTag.setId(UUID.randomUUID().toString().replace("-", "")); newTag.setTagName(snapshotTag.getTagName()); newTag.setSort(snapshotTag.getSort() == null ? 0 : snapshotTag.getSort()); newTag.setDeleted(0); @@ -444,12 +576,16 @@ public class AgentSnapshotServiceImpl extends BaseServiceImpl parseChangedFields(String changedFields) { @@ -469,6 +605,158 @@ public class AgentSnapshotServiceImpl extends BaseServiceImpl { + if (function != null) { + function.setParamInfo(redactSensitiveMap(function.getParamInfo())); + } + }); + } + if (copy.getContextProviders() != null) { + copy.getContextProviders().forEach(provider -> { + if (provider != null) { + provider.setHeaders(redactSensitiveMap(provider.getHeaders())); + } + }); + } + return copy; + } + + private AgentSnapshotDataDTO preserveCurrentSensitiveValues(AgentSnapshotDataDTO target, AgentSnapshotDataDTO current) { + if (target == null) { + return null; + } + AgentSnapshotDataDTO copy = JsonUtils.parseObject(JsonUtils.toJsonString(target), AgentSnapshotDataDTO.class); + Map currentFunctions = nullToEmpty(current == null ? null : current.getFunctions()) + .stream() + .filter(function -> function != null && StringUtils.isNotBlank(function.getPluginId())) + .collect(Collectors.toMap(AgentUpdateDTO.FunctionInfo::getPluginId, Function.identity(), + (left, right) -> left)); + if (copy.getFunctions() != null) { + copy.getFunctions().forEach(function -> { + if (function == null) { + return; + } + AgentUpdateDTO.FunctionInfo currentFunction = currentFunctions.get(function.getPluginId()); + function.setParamInfo(preserveCurrentSensitiveMap(function.getParamInfo(), + currentFunction == null ? null : currentFunction.getParamInfo())); + }); + } + + Map currentProviders = nullToEmpty( + current == null ? null : current.getContextProviders()) + .stream() + .filter(provider -> provider != null && StringUtils.isNotBlank(provider.getUrl())) + .collect(Collectors.toMap(xiaozhi.modules.agent.dto.ContextProviderDTO::getUrl, Function.identity(), + (left, right) -> left)); + if (copy.getContextProviders() != null) { + copy.getContextProviders().forEach(provider -> { + if (provider == null) { + return; + } + xiaozhi.modules.agent.dto.ContextProviderDTO currentProvider = currentProviders.get(provider.getUrl()); + provider.setHeaders(preserveCurrentSensitiveMap(provider.getHeaders(), + currentProvider == null ? null : currentProvider.getHeaders())); + }); + } + return copy; + } + + private HashMap redactSensitiveMap(Map map) { + HashMap result = new HashMap<>(); + if (map == null) { + return result; + } + map.forEach((key, value) -> { + if (key != null) { + String keyText = String.valueOf(key); + result.put(keyText, isSensitiveKey(keyText) ? SECRET_PLACEHOLDER : redactSensitiveValue(value)); + } + }); + return result; + } + + private Object redactSensitiveValue(Object value) { + if (value instanceof Map map) { + return redactSensitiveMap(map); + } + if (value instanceof List list) { + return list.stream().map(this::redactSensitiveValue).toList(); + } + return value; + } + + private HashMap preserveCurrentSensitiveMap(Map target, Map current) { + HashMap result = new HashMap<>(); + if (target == null) { + return result; + } + target.forEach((key, value) -> { + if (key == null) { + return; + } + String keyText = String.valueOf(key); + Object currentValue = getMapValue(current, keyText); + if (isSensitiveKey(keyText)) { + result.put(keyText, currentValue == null || SECRET_PLACEHOLDER.equals(currentValue) ? "" : currentValue); + } else { + result.put(keyText, preserveCurrentSensitiveValue(value, currentValue)); + } + }); + return result; + } + + private Object preserveCurrentSensitiveValue(Object target, Object current) { + if (target instanceof Map targetMap) { + return preserveCurrentSensitiveMap(targetMap, current instanceof Map currentMap ? currentMap : null); + } + if (target instanceof List targetList) { + List currentList = current instanceof List list ? list : Collections.emptyList(); + List result = new ArrayList<>(); + for (int i = 0; i < targetList.size(); i++) { + Object currentItem = i < currentList.size() ? currentList.get(i) : null; + result.add(preserveCurrentSensitiveValue(targetList.get(i), currentItem)); + } + return result; + } + return target; + } + + private Object getMapValue(Map map, String key) { + if (map == null) { + return null; + } + if (map.containsKey(key)) { + return map.get(key); + } + for (Map.Entry entry : map.entrySet()) { + if (entry.getKey() != null && Objects.equals(key, String.valueOf(entry.getKey()))) { + return entry.getValue(); + } + } + return null; + } + + private boolean isSensitiveKey(String key) { + String normalized = StringUtils.defaultString(key).toLowerCase().replaceAll("[^a-z0-9]", ""); + return normalized.equals("authorization") + || normalized.equals("token") + || normalized.endsWith("token") + || normalized.contains("apikey") + || normalized.contains("appkey") + || normalized.contains("accesskey") + || normalized.contains("privatekey") + || normalized.contains("password") + || normalized.contains("passwd") + || normalized.contains("secret") + || normalized.contains("credential"); + } + private List nullToEmpty(List list) { return list == null ? Collections.emptyList() : list; } diff --git a/main/manager-api/src/main/java/xiaozhi/modules/agent/typehandler/ContextProviderListTypeHandler.java b/main/manager-api/src/main/java/xiaozhi/modules/agent/typehandler/ContextProviderListTypeHandler.java new file mode 100644 index 00000000..f0762e35 --- /dev/null +++ b/main/manager-api/src/main/java/xiaozhi/modules/agent/typehandler/ContextProviderListTypeHandler.java @@ -0,0 +1,31 @@ +package xiaozhi.modules.agent.typehandler; + +import java.util.Collections; +import java.util.List; + +import org.apache.commons.lang3.StringUtils; + +import com.baomidou.mybatisplus.extension.handlers.AbstractJsonTypeHandler; +import com.fasterxml.jackson.core.type.TypeReference; + +import xiaozhi.common.utils.JsonUtils; +import xiaozhi.modules.agent.dto.ContextProviderDTO; + +public class ContextProviderListTypeHandler extends AbstractJsonTypeHandler> { + private static final TypeReference> CONTEXT_PROVIDER_LIST_TYPE = new TypeReference<>() { + }; + + @Override + protected List parse(String json) { + if (StringUtils.isBlank(json)) { + return Collections.emptyList(); + } + List providers = JsonUtils.parseObject(json, CONTEXT_PROVIDER_LIST_TYPE); + return providers == null ? Collections.emptyList() : providers; + } + + @Override + protected String toJson(List obj) { + return JsonUtils.toJsonString(obj == null ? Collections.emptyList() : obj); + } +} diff --git a/main/manager-api/src/main/java/xiaozhi/modules/agent/vo/AgentInfoVO.java b/main/manager-api/src/main/java/xiaozhi/modules/agent/vo/AgentInfoVO.java index e5998327..ab1ca3fc 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/agent/vo/AgentInfoVO.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/agent/vo/AgentInfoVO.java @@ -25,4 +25,7 @@ public class AgentInfoVO extends AgentEntity @Schema(description = "替换词文件ID列表") private List correctWordFileIds; + + @Schema(description = "当前配置版本号") + private Integer currentVersionNo; } diff --git a/main/manager-api/src/main/java/xiaozhi/modules/agent/vo/AgentSnapshotVO.java b/main/manager-api/src/main/java/xiaozhi/modules/agent/vo/AgentSnapshotVO.java index 2caf3486..69547e58 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/agent/vo/AgentSnapshotVO.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/agent/vo/AgentSnapshotVO.java @@ -12,10 +12,17 @@ import xiaozhi.modules.agent.dto.AgentSnapshotDataDTO; public class AgentSnapshotVO { private String id; private String agentId; + @Schema(description = "所属用户ID,表示该快照归属的智能体所有者") private Long userId; private Integer versionNo; private List changedFields; + private List fieldOrder; private String source; + @Schema(description = "恢复来源快照ID,仅恢复前自动备份版本有值") + private String restoreFromSnapshotId; + @Schema(description = "恢复来源版本号,仅恢复前自动备份版本有值") + private Integer restoreFromVersionNo; + @Schema(description = "创建者,表示触发本次快照写入的操作人") private Long creator; private Date createdAt; private AgentSnapshotDataDTO snapshotData; diff --git a/main/manager-api/src/main/resources/db/changelog/202607081150.sql b/main/manager-api/src/main/resources/db/changelog/202607081150.sql new file mode 100644 index 00000000..b8496eb1 --- /dev/null +++ b/main/manager-api/src/main/resources/db/changelog/202607081150.sql @@ -0,0 +1,7 @@ +-- liquibase formatted sql + +-- changeset codex:202607081150 +ALTER TABLE `ai_agent_snapshot` + ADD COLUMN `restore_from_snapshot_id` VARCHAR(32) DEFAULT NULL COMMENT '恢复来源快照ID' AFTER `source`, + ADD COLUMN `restore_from_version_no` INT UNSIGNED DEFAULT NULL COMMENT '恢复来源版本号' AFTER `restore_from_snapshot_id`, + ADD INDEX `idx_snapshot_user_created_at` (`user_id`, `created_at`); diff --git a/main/manager-api/src/main/resources/db/changelog/202607081230.sql b/main/manager-api/src/main/resources/db/changelog/202607081230.sql new file mode 100644 index 00000000..b62bb584 --- /dev/null +++ b/main/manager-api/src/main/resources/db/changelog/202607081230.sql @@ -0,0 +1,5 @@ +-- liquibase formatted sql + +-- changeset codex:202607081230 +ALTER TABLE `ai_agent_snapshot` + ALTER COLUMN `snapshot_data` SET DEFAULT (JSON_OBJECT()); diff --git a/main/manager-api/src/main/resources/db/changelog/db.changelog-master.yaml b/main/manager-api/src/main/resources/db/changelog/db.changelog-master.yaml index e81ea5c1..4b8c323d 100644 --- a/main/manager-api/src/main/resources/db/changelog/db.changelog-master.yaml +++ b/main/manager-api/src/main/resources/db/changelog/db.changelog-master.yaml @@ -704,3 +704,17 @@ databaseChangeLog: - sqlFile: encoding: utf8 path: classpath:db/changelog/202607071530.sql + - changeSet: + id: 202607081150 + author: Codex + changes: + - sqlFile: + encoding: utf8 + path: classpath:db/changelog/202607081150.sql + - changeSet: + id: 202607081230 + author: Codex + changes: + - sqlFile: + encoding: utf8 + path: classpath:db/changelog/202607081230.sql diff --git a/main/manager-api/src/main/resources/mapper/agent/AgentDao.xml b/main/manager-api/src/main/resources/mapper/agent/AgentDao.xml index 6fb8fb02..c779a5e6 100644 --- a/main/manager-api/src/main/resources/mapper/agent/AgentDao.xml +++ b/main/manager-api/src/main/resources/mapper/agent/AgentDao.xml @@ -36,9 +36,12 @@ + ofType="xiaozhi.modules.agent.entity.AgentPluginMapping"> + + + + + - + SELECT * + FROM ai_agent + WHERE id = #{agentId} + FOR UPDATE + diff --git a/main/manager-api/src/main/resources/mapper/agent/AgentSnapshotDao.xml b/main/manager-api/src/main/resources/mapper/agent/AgentSnapshotDao.xml index 38609ac4..7926cac7 100644 --- a/main/manager-api/src/main/resources/mapper/agent/AgentSnapshotDao.xml +++ b/main/manager-api/src/main/resources/mapper/agent/AgentSnapshotDao.xml @@ -16,6 +16,8 @@ snapshot_data AS snapshotData, changed_fields AS changedFields, source, + restore_from_snapshot_id AS restoreFromSnapshotId, + restore_from_version_no AS restoreFromVersionNo, creator, created_at AS createdAt FROM ai_agent_snapshot @@ -25,4 +27,19 @@ LIMIT 1 + + DELETE FROM ai_agent_snapshot + WHERE agent_id = #{agentId} + AND id NOT IN ( + SELECT id + FROM ( + SELECT id + FROM ai_agent_snapshot + WHERE agent_id = #{agentId} + ORDER BY version_no DESC + LIMIT #{keepLimit} + ) retained_snapshots + ) + + diff --git a/main/manager-api/src/test/java/xiaozhi/modules/agent/dto/AgentUpdateDTOTest.java b/main/manager-api/src/test/java/xiaozhi/modules/agent/dto/AgentUpdateDTOTest.java new file mode 100644 index 00000000..8ffe01c4 --- /dev/null +++ b/main/manager-api/src/test/java/xiaozhi/modules/agent/dto/AgentUpdateDTOTest.java @@ -0,0 +1,44 @@ +package xiaozhi.modules.agent.dto; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.LinkedHashMap; +import java.util.Map; + +import org.junit.jupiter.api.Test; + +class AgentUpdateDTOTest { + + @Test + void functionInfoAcceptsJsonStringParamInfo() { + AgentUpdateDTO.FunctionInfo info = new AgentUpdateDTO.FunctionInfo(); + + info.setParamInfo("{\"api_key\":\"abc\",\"max_results\":5}"); + + assertEquals("abc", info.getParamInfo().get("api_key")); + assertEquals(5, info.getParamInfo().get("max_results")); + } + + @Test + void functionInfoNormalizesMapKeysToStrings() { + AgentUpdateDTO.FunctionInfo info = new AgentUpdateDTO.FunctionInfo(); + Map params = new LinkedHashMap<>(); + params.put("api_key", "abc"); + params.put(42, true); + + info.setParamInfo(params); + + assertEquals("abc", info.getParamInfo().get("api_key")); + assertEquals(true, info.getParamInfo().get("42")); + } + + @Test + void functionInfoFallsBackToEmptyMapForBlankParamInfo() { + AgentUpdateDTO.FunctionInfo info = new AgentUpdateDTO.FunctionInfo(); + + info.setParamInfo(" "); + + assertTrue(info.getParamInfo().isEmpty()); + } +} diff --git a/main/manager-api/src/test/java/xiaozhi/modules/agent/service/impl/AgentSnapshotServiceImplTest.java b/main/manager-api/src/test/java/xiaozhi/modules/agent/service/impl/AgentSnapshotServiceImplTest.java new file mode 100644 index 00000000..2648145d --- /dev/null +++ b/main/manager-api/src/test/java/xiaozhi/modules/agent/service/impl/AgentSnapshotServiceImplTest.java @@ -0,0 +1,380 @@ +package xiaozhi.modules.agent.service.impl; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.argThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import java.lang.reflect.Method; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Date; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.atomic.AtomicReference; + +import org.junit.jupiter.api.Test; +import org.springframework.transaction.annotation.Transactional; + +import xiaozhi.common.utils.JsonUtils; +import xiaozhi.modules.agent.Enums.AgentSnapshotField; +import xiaozhi.modules.agent.dao.AgentDao; +import xiaozhi.modules.agent.dao.AgentSnapshotDao; +import xiaozhi.modules.agent.dao.AgentTagDao; +import xiaozhi.modules.agent.dto.AgentSnapshotDataDTO; +import xiaozhi.modules.agent.dto.AgentSnapshotPageDTO; +import xiaozhi.modules.agent.dto.AgentSnapshotTagDTO; +import xiaozhi.modules.agent.dto.AgentUpdateDTO; +import xiaozhi.modules.agent.dto.ContextProviderDTO; +import xiaozhi.modules.agent.entity.AgentEntity; +import xiaozhi.modules.agent.entity.AgentSnapshotEntity; +import xiaozhi.modules.agent.entity.AgentTagEntity; +import xiaozhi.modules.agent.service.AgentContextProviderService; +import xiaozhi.modules.agent.vo.AgentSnapshotVO; +import xiaozhi.modules.agent.vo.AgentInfoVO; +import xiaozhi.modules.correctword.service.CorrectWordFileService; + +class AgentSnapshotServiceImplTest { + + @Test + @SuppressWarnings("unchecked") + void normalizeSortedJsonListTreatsDtoAndMapShapesEqually() throws Exception { + AgentSnapshotServiceImpl service = new AgentSnapshotServiceImpl(null, null, null, null, null, null, null, null, + null, null); + Method method = AgentSnapshotServiceImpl.class.getDeclaredMethod("normalizeSortedJsonList", List.class); + method.setAccessible(true); + + ContextProviderDTO dto = new ContextProviderDTO(); + dto.setUrl("https://example.com/context"); + dto.setHeaders(Map.of("Authorization", "Bearer token")); + + Map map = new LinkedHashMap<>(); + map.put("headers", Map.of("Authorization", "Bearer token")); + map.put("url", "https://example.com/context"); + + assertEquals(method.invoke(service, List.of(dto)), method.invoke(service, List.of(map))); + } + + @Test + void redactSnapshotDataMasksSensitiveFunctionAndHeaderValues() throws Exception { + AgentSnapshotServiceImpl service = new AgentSnapshotServiceImpl(null, null, null, null, null, null, null, null, + null, null); + Method method = AgentSnapshotServiceImpl.class.getDeclaredMethod("redactSnapshotData", + AgentSnapshotDataDTO.class); + method.setAccessible(true); + + AgentSnapshotDataDTO data = new AgentSnapshotDataDTO(); + AgentUpdateDTO.FunctionInfo function = new AgentUpdateDTO.FunctionInfo(); + function.setPluginId("rag"); + function.setParamInfo(Map.of("api_key", "secret-key", "max_tokens", 32)); + ContextProviderDTO provider = new ContextProviderDTO(); + provider.setUrl("https://example.com/context"); + provider.setHeaders(Map.of("Authorization", "Bearer secret-token", "Accept", "application/json")); + data.setFunctions(List.of(function)); + data.setContextProviders(List.of(provider)); + + AgentSnapshotDataDTO redacted = (AgentSnapshotDataDTO) method.invoke(service, data); + String json = JsonUtils.toJsonString(redacted); + + assertFalse(json.contains("secret-key")); + assertFalse(json.contains("secret-token")); + assertTrue(json.contains("__SNAPSHOT_SECRET_REDACTED__")); + assertTrue(json.contains("max_tokens")); + assertTrue(json.contains("application/json")); + } + + @Test + void preserveCurrentSensitiveValuesKeepsCurrentSecretsWhenRestoringSnapshot() throws Exception { + AgentSnapshotServiceImpl service = new AgentSnapshotServiceImpl(null, null, null, null, null, null, null, null, + null, null); + Method method = AgentSnapshotServiceImpl.class.getDeclaredMethod("preserveCurrentSensitiveValues", + AgentSnapshotDataDTO.class, AgentSnapshotDataDTO.class); + method.setAccessible(true); + + AgentSnapshotDataDTO snapshot = buildSnapshot("old-key", "old-token", "old-value"); + AgentSnapshotDataDTO current = buildSnapshot("current-key", "current-token", "current-value"); + + AgentSnapshotDataDTO restored = (AgentSnapshotDataDTO) method.invoke(service, snapshot, current); + + assertEquals("current-key", restored.getFunctions().get(0).getParamInfo().get("api_key")); + assertEquals("old-value", restored.getFunctions().get(0).getParamInfo().get("description")); + assertEquals("current-token", restored.getContextProviders().get(0).getHeaders().get("Authorization")); + } + + @Test + @SuppressWarnings("unchecked") + void getChangedFieldsFollowsCentralFieldOrder() throws Exception { + AgentSnapshotServiceImpl service = new AgentSnapshotServiceImpl(null, null, null, null, null, null, null, null, + null, null); + Method method = AgentSnapshotServiceImpl.class.getDeclaredMethod("getChangedFields", + AgentSnapshotDataDTO.class, AgentUpdateDTO.class); + method.setAccessible(true); + + AgentSnapshotDataDTO current = new AgentSnapshotDataDTO(); + current.setAgentName("old-name"); + current.setCorrectWordFileIds(List.of("b", "a")); + + AgentUpdateDTO pendingUpdate = new AgentUpdateDTO(); + pendingUpdate.setAgentName("new-name"); + pendingUpdate.setCorrectWordFileIds(List.of("a", "b")); + AgentUpdateDTO.FunctionInfo function = new AgentUpdateDTO.FunctionInfo(); + function.setPluginId("rag"); + function.setParamInfo(Map.of("api_key", "secret-key")); + pendingUpdate.setFunctions(List.of(function)); + + List changedFields = (List) method.invoke(service, current, pendingUpdate); + + assertEquals(List.of(AgentSnapshotField.AGENT_NAME.getFieldName(), + AgentSnapshotField.FUNCTIONS.getFieldName()), changedFields); + } + + @Test + @SuppressWarnings("unchecked") + void tagIdsAreNotExposedAsIndependentSnapshotFields() throws Exception { + AgentSnapshotServiceImpl service = new AgentSnapshotServiceImpl(null, null, null, null, null, null, null, null, + null, null); + Method method = AgentSnapshotServiceImpl.class.getDeclaredMethod("getChangedFields", + AgentSnapshotDataDTO.class, AgentUpdateDTO.class); + method.setAccessible(true); + + AgentSnapshotDataDTO current = new AgentSnapshotDataDTO(); + current.setTagNames(List.of("alpha", "beta")); + + AgentUpdateDTO pendingUpdate = new AgentUpdateDTO(); + pendingUpdate.setTagNames(List.of("beta", "alpha")); + pendingUpdate.setTagIds(List.of("new-id")); + + List changedFields = (List) method.invoke(service, current, pendingUpdate); + + assertFalse(AgentSnapshotField.names().contains("tagIds")); + assertFalse(changedFields.contains("tagIds")); + assertTrue(changedFields.isEmpty()); + + pendingUpdate.setTagNames(List.of("alpha", "gamma")); + changedFields = (List) method.invoke(service, current, pendingUpdate); + + assertEquals(List.of(AgentSnapshotField.TAG_NAMES.getFieldName()), changedFields); + } + + @Test + void tagOnlySavePathCreatesSnapshot() throws Exception { + String controller = Files.readString(Path.of("src/main/java/xiaozhi/modules/agent/controller/AgentController.java")); + String roleConfig = Files.readString(Path.of("../manager-web/src/views/roleConfig.vue")); + + assertTrue(controller.contains("agentService.updateAgentById(id, dto);")); + assertFalse(controller.contains("agentService.updateAgentById(id, dto, false);")); + assertTrue(roleConfig.contains("configData.tagNames = tagNames;")); + assertFalse(roleConfig.contains("this.handleSaveAgentTags(agentId, tagNames)")); + } + + @Test + void agentSnapshotFieldAppliesRestorableAgentFields() { + AgentSnapshotDataDTO data = new AgentSnapshotDataDTO(); + data.setAgentName("restored-name"); + data.setLlmModelId("llm-new"); + data.setSystemPrompt("restored prompt"); + data.setSort(7); + + AgentEntity agent = new AgentEntity(); + for (AgentSnapshotField field : AgentSnapshotField.values()) { + field.applyTo(agent, data); + } + + assertEquals("restored-name", agent.getAgentName()); + assertEquals("llm-new", agent.getLlmModelId()); + assertEquals("restored prompt", agent.getSystemPrompt()); + assertEquals(7, agent.getSort()); + } + + @Test + void restoreSnapshotRollsBackForAnyException() throws Exception { + Method method = AgentSnapshotServiceImpl.class.getMethod("restoreSnapshot", String.class, String.class); + + Transactional transactional = method.getAnnotation(Transactional.class); + + assertNotNull(transactional); + assertTrue(List.of(transactional.rollbackFor()).contains(Exception.class)); + } + + @Test + void deleteSnapshotRollsBackForAnyException() throws Exception { + Method method = AgentSnapshotServiceImpl.class.getMethod("deleteSnapshot", String.class, String.class); + + Transactional transactional = method.getAnnotation(Transactional.class); + + assertNotNull(transactional); + assertTrue(List.of(transactional.rollbackFor()).contains(Exception.class)); + } + + @Test + void versionAllocationDoesNotDependOnSequenceTable() throws Exception { + String xml = Files.readString(Path.of("src/main/resources/mapper/agent/AgentSnapshotDao.xml")); + String dao = Files.readString(Path.of("src/main/java/xiaozhi/modules/agent/dao/AgentSnapshotDao.java")); + String createMigration = Files.readString(Path.of("src/main/resources/db/changelog/202607071530.sql")); + String master = Files.readString(Path.of("src/main/resources/db/changelog/db.changelog-master.yaml")); + + assertFalse(xml.contains("ai_agent_snapshot_sequence")); + assertFalse(xml.contains("LAST_INSERT_ID")); + assertFalse(dao.contains("allocateVersionNo")); + assertFalse(dao.contains("selectLastInsertId")); + assertFalse(createMigration.contains("ai_agent_snapshot_sequence")); + assertFalse(master.contains("202607081430.sql")); + } + + @Test + void snapshotMigrationAddsRestoreTraceAndUserIndex() throws Exception { + String sql = Files.readString(Path.of("src/main/resources/db/changelog/202607081150.sql")); + String defaultSql = Files.readString(Path.of("src/main/resources/db/changelog/202607081230.sql")); + String master = Files.readString(Path.of("src/main/resources/db/changelog/db.changelog-master.yaml")); + + assertTrue(sql.contains("restore_from_snapshot_id")); + assertTrue(sql.contains("restore_from_version_no")); + assertTrue(sql.contains("idx_snapshot_user_created_at")); + assertTrue(master.contains("202607081150.sql")); + assertTrue(defaultSql.contains("DEFAULT (JSON_OBJECT())")); + assertTrue(master.contains("202607081230.sql")); + } + + @Test + void selectNextSnapshotLoadsRestoreTraceColumns() throws Exception { + String xml = Files.readString(Path.of("src/main/resources/mapper/agent/AgentSnapshotDao.xml")); + + assertTrue(xml.contains("restore_from_snapshot_id AS restoreFromSnapshotId")); + assertTrue(xml.contains("restore_from_version_no AS restoreFromVersionNo")); + } + + @Test + void retentionPruneSqlKeepsLatestVersions() throws Exception { + String xml = Files.readString(Path.of("src/main/resources/mapper/agent/AgentSnapshotDao.xml")); + + assertTrue(xml.contains("deleteOlderThanKeepLimit")); + assertTrue(xml.contains("ORDER BY version_no DESC")); + assertTrue(xml.contains("LIMIT #{keepLimit}")); + } + + @Test + void agentInfoMapperLoadsFunctionsWithJoinInsteadOfNestedSelect() throws Exception { + String xml = Files.readString(Path.of("src/main/resources/mapper/agent/AgentDao.xml")); + + assertTrue(xml.contains("LEFT JOIN ai_agent_plugin_mapping f ON f.agent_id = a.id")); + assertFalse(xml.contains("selectAgentFunctionsByAgentId")); + assertFalse(xml.contains("select=\"selectAgentFunctions")); + } + + @Test + void toVOIncludesRestoreTraceFields() throws Exception { + AgentSnapshotServiceImpl service = new AgentSnapshotServiceImpl(null, null, null, null, null, null, null, null, + null, null); + Method method = AgentSnapshotServiceImpl.class.getDeclaredMethod("toVO", + AgentSnapshotEntity.class, boolean.class); + method.setAccessible(true); + + AgentSnapshotEntity entity = new AgentSnapshotEntity(); + entity.setId("snapshot-id"); + entity.setAgentId("agent-id"); + entity.setVersionNo(3); + entity.setChangedFields("[]"); + entity.setSource("restore"); + entity.setRestoreFromSnapshotId("target-id"); + entity.setRestoreFromVersionNo(1); + + AgentSnapshotVO vo = (AgentSnapshotVO) method.invoke(service, entity, false); + + assertEquals("target-id", vo.getRestoreFromSnapshotId()); + assertEquals(1, vo.getRestoreFromVersionNo()); + } + + @Test + void pageCreatesInitialSnapshotWhenAgentHasNoHistory() { + AgentSnapshotDao snapshotDao = mock(AgentSnapshotDao.class); + AgentDao agentDao = mock(AgentDao.class); + AgentTagDao tagDao = mock(AgentTagDao.class); + AgentContextProviderService contextProviderService = mock(AgentContextProviderService.class); + CorrectWordFileService correctWordFileService = mock(CorrectWordFileService.class); + AgentSnapshotServiceImpl service = new AgentSnapshotServiceImpl(snapshotDao, agentDao, tagDao, null, null, + contextProviderService, null, null, null, correctWordFileService); + + AgentEntity lockedAgent = new AgentEntity(); + lockedAgent.setId("agent-id"); + AgentInfoVO agentInfo = new AgentInfoVO(); + agentInfo.setId("agent-id"); + agentInfo.setUserId(7L); + agentInfo.setAgentName("agent"); + when(snapshotDao.selectMaxVersionNo("agent-id")).thenReturn(0, 0, 0); + when(agentDao.selectByIdForUpdate("agent-id")).thenReturn(lockedAgent); + when(agentDao.selectAgentInfoById("agent-id")).thenReturn(agentInfo); + when(correctWordFileService.getAgentCorrectWordFileIds("agent-id")).thenReturn(List.of()); + when(tagDao.selectByAgentId("agent-id")).thenReturn(List.of()); + when(snapshotDao.selectPage(any(), any())).thenReturn(new Page(1, 10)); + + service.page("agent-id", new AgentSnapshotPageDTO()); + + verify(snapshotDao, times(3)).selectMaxVersionNo("agent-id"); + verify(snapshotDao).insert(argThat(snapshot -> Integer.valueOf(1).equals(snapshot.getVersionNo()))); + verify(snapshotDao).deleteOlderThanKeepLimit("agent-id", 100); + } + + @Test + void restoreTagDoesNotReviveSoftDeletedSnapshotTagId() throws Exception { + AgentTagDao tagDao = mock(AgentTagDao.class); + AgentSnapshotServiceImpl service = new AgentSnapshotServiceImpl(null, null, tagDao, null, null, null, null, null, + null, null); + Method method = AgentSnapshotServiceImpl.class.getDeclaredMethod("restoreTag", + AgentSnapshotTagDTO.class, Date.class); + method.setAccessible(true); + + AgentTagEntity deletedTag = new AgentTagEntity(); + deletedTag.setId("deleted-tag-id"); + deletedTag.setTagName("archived"); + deletedTag.setDeleted(1); + when(tagDao.selectById("deleted-tag-id")).thenReturn(deletedTag); + when(tagDao.selectOne(any())).thenReturn(null); + AtomicReference insertedTag = new AtomicReference<>(); + when(tagDao.insert(any())).thenAnswer(invocation -> { + insertedTag.set(invocation.getArgument(0)); + return 1; + }); + + AgentSnapshotTagDTO snapshotTag = new AgentSnapshotTagDTO(); + snapshotTag.setId("deleted-tag-id"); + snapshotTag.setTagName("archived"); + + String restoredTagId = (String) method.invoke(service, snapshotTag, new Date()); + + verify(tagDao, never()).updateById(any()); + assertNotEquals("deleted-tag-id", restoredTagId); + assertNotNull(insertedTag.get()); + assertEquals(restoredTagId, insertedTag.get().getId()); + assertEquals(0, insertedTag.get().getDeleted()); + } + + private AgentSnapshotDataDTO buildSnapshot(String apiKey, String authToken, String description) { + AgentSnapshotDataDTO data = new AgentSnapshotDataDTO(); + + AgentUpdateDTO.FunctionInfo function = new AgentUpdateDTO.FunctionInfo(); + function.setPluginId("rag"); + HashMap params = new HashMap<>(); + params.put("api_key", apiKey); + params.put("description", description); + function.setParamInfo(params); + + ContextProviderDTO provider = new ContextProviderDTO(); + provider.setUrl("https://example.com/context"); + provider.setHeaders(Map.of("Authorization", authToken)); + + data.setFunctions(List.of(function)); + data.setContextProviders(List.of(provider)); + return data; + } +} diff --git a/main/manager-api/src/test/java/xiaozhi/modules/agent/typehandler/ContextProviderListTypeHandlerTest.java b/main/manager-api/src/test/java/xiaozhi/modules/agent/typehandler/ContextProviderListTypeHandlerTest.java new file mode 100644 index 00000000..e1d0e6c4 --- /dev/null +++ b/main/manager-api/src/test/java/xiaozhi/modules/agent/typehandler/ContextProviderListTypeHandlerTest.java @@ -0,0 +1,42 @@ +package xiaozhi.modules.agent.typehandler; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.List; + +import org.apache.ibatis.type.TypeHandler; +import org.apache.ibatis.type.TypeHandlerRegistry; +import org.junit.jupiter.api.Test; + +import xiaozhi.modules.agent.dto.ContextProviderDTO; + +class ContextProviderListTypeHandlerTest { + + private final ContextProviderListTypeHandler handler = new ContextProviderListTypeHandler(); + + @Test + void parseKeepsContextProviderDtoElementType() { + List providers = handler + .parse("[{\"url\":\"https://example.com/context\",\"headers\":{\"Authorization\":\"Bearer token\"}}]"); + + assertEquals(1, providers.size()); + assertInstanceOf(ContextProviderDTO.class, providers.get(0)); + assertEquals("https://example.com/context", providers.get(0).getUrl()); + assertEquals("Bearer token", providers.get(0).getHeaders().get("Authorization")); + } + + @Test + void parseBlankJsonAsEmptyList() { + assertTrue(handler.parse(" ").isEmpty()); + } + + @Test + void myBatisCanInstantiateHandlerForListField() { + TypeHandler typeHandler = new TypeHandlerRegistry().getInstance(List.class, + ContextProviderListTypeHandler.class); + + assertInstanceOf(ContextProviderListTypeHandler.class, typeHandler); + } +} diff --git a/main/manager-mobile/src/pages/agent/edit.vue b/main/manager-mobile/src/pages/agent/edit.vue index 964ad0b2..e33c0211 100644 --- a/main/manager-mobile/src/pages/agent/edit.vue +++ b/main/manager-mobile/src/pages/agent/edit.vue @@ -169,6 +169,28 @@ function handleInputConfirm() { // 是否禁用历史记忆输入框 const isMemoryDisabled = computed(() => formData.value.memModelId !== 'Memory_mem_local_short') +function normalizeFunctionParams(paramInfo: any) { + if (!paramInfo) + return {} + if (typeof paramInfo === 'string') { + try { + const parsed = JSON.parse(paramInfo) + return parsed && typeof parsed === 'object' && !Array.isArray(parsed) ? parsed : {} + } + catch { + return {} + } + } + return typeof paramInfo === 'object' && !Array.isArray(paramInfo) ? { ...paramInfo } : {} +} + +function normalizeAgentFunctions(functions: any[] = []) { + return functions.map(item => ({ + ...item, + paramInfo: normalizeFunctionParams(item.paramInfo), + })) +} + // 打开上下文源编辑弹窗 function openContextProviderDialog() { uni.navigateTo({ @@ -191,11 +213,12 @@ async function loadAgentDetail() { loading.value = true tempSummaryMemory.value = '' const detail = await getAgentDetail(agentId.value) - formData.value = { ...detail } + const normalizedFunctions = normalizeAgentFunctions(detail.functions || []) + formData.value = { ...detail, functions: normalizedFunctions } // 更新插件store pluginStore.setCurrentAgentId(agentId.value) - pluginStore.setCurrentFunctions(detail.functions || []) + pluginStore.setCurrentFunctions(normalizedFunctions) // 更新语速音调 speedPitchStore.updateSpeedPitch({ @@ -626,6 +649,7 @@ async function saveAgent() { ...speedPitchStore.speedPitch, ttsLanguage: formData.value.language, contextProviders: providerStore.providers, + functions: normalizeAgentFunctions(formData.value.functions || []), } await updateAgent(agentId.value, saveData) loadAgentDetail() @@ -663,7 +687,7 @@ function handleTools() { // 确保store中有最新数据 pluginStore.setCurrentAgentId(agentId.value) - pluginStore.setCurrentFunctions(formData.value.functions || []) + pluginStore.setCurrentFunctions(normalizeAgentFunctions(formData.value.functions || [])) pluginStore.setAllFunctions(allFunctions.value) uni.navigateTo({ @@ -688,7 +712,7 @@ async function handleUpdateAgentTags() { // 监听store中的插件配置变化 watch(() => pluginStore.currentFunctions, (newFunctions) => { - formData.value.functions = newFunctions + formData.value.functions = normalizeAgentFunctions(newFunctions || []) }, { deep: true }) onMounted(async () => { diff --git a/main/manager-mobile/src/pages/agent/tools.vue b/main/manager-mobile/src/pages/agent/tools.vue index fb47deae..6d835a30 100644 --- a/main/manager-mobile/src/pages/agent/tools.vue +++ b/main/manager-mobile/src/pages/agent/tools.vue @@ -41,17 +41,32 @@ const tempParams = ref>({}) const arrayTextCache = ref>({}) const jsonTextCache = ref>({}) +function normalizeFunctionParams(paramInfo: any, fallback: Record = {}) { + if (!paramInfo) + return { ...fallback } + if (typeof paramInfo === 'string') { + try { + const parsed = JSON.parse(paramInfo) + return parsed && typeof parsed === 'object' && !Array.isArray(parsed) ? parsed : { ...fallback } + } + catch { + return { ...fallback } + } + } + return typeof paramInfo === 'object' && !Array.isArray(paramInfo) ? { ...fallback, ...paramInfo } : { ...fallback } +} + async function mergeFunctions() { selectedList.value = functions.value.map((mapping) => { const meta = allFunctions.value.find(f => f.id === mapping.pluginId) if (!meta) { - return { id: mapping.pluginId, name: mapping.pluginId, params: {} } + return { id: mapping.pluginId, name: mapping.pluginId, params: normalizeFunctionParams(mapping.paramInfo) } } return { id: mapping.pluginId, name: meta.name, - params: mapping.paramInfo || { ...meta.params }, + params: normalizeFunctionParams(mapping.paramInfo, meta.params), fieldsMeta: meta.fieldsMeta, } }) @@ -91,7 +106,7 @@ function selectFunction(func: any) { selectedList.value = [...selectedList.value, { id: func.id, name: func.name, - params: { ...func.params }, + params: normalizeFunctionParams(func.params), fieldsMeta: func.fieldsMeta, }] @@ -118,7 +133,7 @@ function editFunction(func: any) { currentFunction.value = func // 直接使用当前函数的参数 - tempParams.value = { ...func.params } + tempParams.value = normalizeFunctionParams(func.params) // 初始化文本缓存 if (func.fieldsMeta) { @@ -252,7 +267,7 @@ function getFieldRemark(field: any) { watch(() => selectedList.value, (newSelectedList) => { const finalFunctions = newSelectedList.map(f => ({ pluginId: f.id, - paramInfo: f.params, + paramInfo: normalizeFunctionParams(f.params), })) pluginStore.updateFunctions(finalFunctions) }) diff --git a/main/manager-web/package-lock.json b/main/manager-web/package-lock.json index acc4aec2..44829664 100644 --- a/main/manager-web/package-lock.json +++ b/main/manager-web/package-lock.json @@ -11096,6 +11096,16 @@ "node": ">= 0.4.0" } }, + "node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmmirror.com/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "license": "MIT", + "bin": { + "uuid": "bin/uuid" + } + }, "node_modules/validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmmirror.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", diff --git a/main/manager-web/src/apis/module/agent.js b/main/manager-web/src/apis/module/agent.js index 2a45f197..3c9522db 100644 --- a/main/manager-web/src/apis/module/agent.js +++ b/main/manager-web/src/apis/module/agent.js @@ -127,6 +127,21 @@ export default { }); }).send(); }, + // 删除智能体配置快照 + deleteAgentSnapshot(agentId, snapshotId, callback) { + RequestService.sendRequest() + .url(`${getServiceUrl()}/agent/${agentId}/snapshots/${snapshotId}`) + .method('DELETE') + .success((res) => { + RequestService.clearRequestTime(); + callback(res); + }) + .networkFail(() => { + RequestService.reAjaxFun(() => { + this.deleteAgentSnapshot(agentId, snapshotId, callback); + }); + }).send(); + }, // 新增方法:获取智能体模板 getAgentTemplate(callback) { // 移除templateName参数 RequestService.sendRequest() diff --git a/main/manager-web/src/components/AgentSnapshotDialog.vue b/main/manager-web/src/components/AgentSnapshotDialog.vue index 5efc20d3..9b09a00a 100644 --- a/main/manager-web/src/components/AgentSnapshotDialog.vue +++ b/main/manager-web/src/components/AgentSnapshotDialog.vue @@ -5,7 +5,7 @@ :visible="visible" width="760px" class="agent-snapshot-dialog" - @open="fetchSnapshots" + @open="open" @close="close" > — - + @@ -185,7 +195,7 @@ -
功能配置无变化
+
{{ $t('agentSnapshot.noFunctionChange') }}
@@ -306,7 +316,7 @@
-
功能配置无变化
+
{{ $t('agentSnapshot.noFunctionChange') }}
@@ -339,6 +349,22 @@ :description="$t('agentSnapshot.noChangedContent')" :image-size="80" /> + +
@@ -361,33 +387,33 @@ import Api from "@/apis/api"; import { formatDate } from "@/utils/date"; -const FALLBACK_PLUGIN_NAMES = { - SYSTEM_PLUGIN_WEATHER: "天气查询", - SYSTEM_PLUGIN_MUSIC: "服务器音乐播放", - SYSTEM_PLUGIN_NEWS_CHINANEWS: "中新网新闻", - SYSTEM_PLUGIN_NEWS_NEWSNOW: "newsnow新闻聚合", - SYSTEM_PLUGIN_HA_GET_STATE: "HomeAssistant设备状态查询", - SYSTEM_PLUGIN_HA_SET_STATE: "HomeAssistant设备状态修改", - SYSTEM_PLUGIN_HA_PLAY_MUSIC: "HomeAssistant音乐播放", - SYSTEM_PLUGIN_WEB_SEARCH: "联网搜索", - SYSTEM_PLUGIN_CALL_DEVICE: "设备呼叫设备" +const FALLBACK_PLUGIN_NAME_KEYS = { + SYSTEM_PLUGIN_WEATHER: "agentSnapshot.plugin.SYSTEM_PLUGIN_WEATHER", + SYSTEM_PLUGIN_MUSIC: "agentSnapshot.plugin.SYSTEM_PLUGIN_MUSIC", + SYSTEM_PLUGIN_NEWS_CHINANEWS: "agentSnapshot.plugin.SYSTEM_PLUGIN_NEWS_CHINANEWS", + SYSTEM_PLUGIN_NEWS_NEWSNOW: "agentSnapshot.plugin.SYSTEM_PLUGIN_NEWS_NEWSNOW", + SYSTEM_PLUGIN_HA_GET_STATE: "agentSnapshot.plugin.SYSTEM_PLUGIN_HA_GET_STATE", + SYSTEM_PLUGIN_HA_SET_STATE: "agentSnapshot.plugin.SYSTEM_PLUGIN_HA_SET_STATE", + SYSTEM_PLUGIN_HA_PLAY_MUSIC: "agentSnapshot.plugin.SYSTEM_PLUGIN_HA_PLAY_MUSIC", + SYSTEM_PLUGIN_WEB_SEARCH: "agentSnapshot.plugin.SYSTEM_PLUGIN_WEB_SEARCH", + SYSTEM_PLUGIN_CALL_DEVICE: "agentSnapshot.plugin.SYSTEM_PLUGIN_CALL_DEVICE" }; -const FALLBACK_FIELD_LABELS = { - url: "接口地址", - news_sources: "新闻源配置", - default_rss_url: "默认 RSS 源", - society_rss_url: "社会新闻 RSS 地址", - world_rss_url: "国际新闻 RSS 地址", - finance_rss_url: "财经新闻 RSS 地址", - api_key: "API 密钥", - default_location: "默认查询城市", - api_host: "开发者 API Host", - base_url: "服务器地址", - devices: "设备列表", - provider: "搜索源", - description: "工具描述", - max_results: "返回数量" +const FALLBACK_FIELD_LABEL_KEYS = { + url: "agentSnapshot.pluginField.url", + news_sources: "agentSnapshot.pluginField.news_sources", + default_rss_url: "agentSnapshot.pluginField.default_rss_url", + society_rss_url: "agentSnapshot.pluginField.society_rss_url", + world_rss_url: "agentSnapshot.pluginField.world_rss_url", + finance_rss_url: "agentSnapshot.pluginField.finance_rss_url", + api_key: "agentSnapshot.pluginField.api_key", + default_location: "agentSnapshot.pluginField.default_location", + api_host: "agentSnapshot.pluginField.api_host", + base_url: "agentSnapshot.pluginField.base_url", + devices: "agentSnapshot.pluginField.devices", + provider: "agentSnapshot.pluginField.provider", + description: "agentSnapshot.pluginField.description", + max_results: "agentSnapshot.pluginField.max_results" }; const MODEL_FIELD_TYPES = { @@ -403,29 +429,29 @@ const MODEL_FIELD_TYPES = { const MODEL_TYPES = ["ASR", "VAD", "LLM", "SLM", "VLLM", "TTS", "Memory", "Intent"]; -const FALLBACK_MODEL_NAMES = { - Memory_nomem: "无记忆", - Memory_mem_local_short: "本地短记忆", - Memory_mem0ai: "Mem0AI记忆", - Memory_mem_report_only: "仅上报记忆", - Intent_nointent: "无意图识别", - Intent_intent_llm: "外挂的大模型意图识别", - Intent_function_call: "大模型自主函数调用" +const FALLBACK_MODEL_NAME_KEYS = { + Memory_nomem: "agentSnapshot.model.Memory_nomem", + Memory_mem_local_short: "agentSnapshot.model.Memory_mem_local_short", + Memory_mem0ai: "agentSnapshot.model.Memory_mem0ai", + Memory_mem_report_only: "agentSnapshot.model.Memory_mem_report_only", + Intent_nointent: "agentSnapshot.model.Intent_nointent", + Intent_intent_llm: "agentSnapshot.model.Intent_intent_llm", + Intent_function_call: "agentSnapshot.model.Intent_function_call" }; -const FALLBACK_VOICE_NAMES = { - TTS_EdgeTTS0001: "EdgeTTS女声-晓晓", - TTS_EdgeTTS0002: "EdgeTTS男声-云扬", - TTS_EdgeTTS0003: "EdgeTTS女声-晓伊", - TTS_EdgeTTS0004: "EdgeTTS男声-云健", - TTS_EdgeTTS0005: "EdgeTTS男声-云希", - TTS_EdgeTTS0006: "EdgeTTS男声-云夏" +const FALLBACK_VOICE_NAME_KEYS = { + TTS_EdgeTTS0001: "agentSnapshot.voice.TTS_EdgeTTS0001", + TTS_EdgeTTS0002: "agentSnapshot.voice.TTS_EdgeTTS0002", + TTS_EdgeTTS0003: "agentSnapshot.voice.TTS_EdgeTTS0003", + TTS_EdgeTTS0004: "agentSnapshot.voice.TTS_EdgeTTS0004", + TTS_EdgeTTS0005: "agentSnapshot.voice.TTS_EdgeTTS0005", + TTS_EdgeTTS0006: "agentSnapshot.voice.TTS_EdgeTTS0006" }; -const CHAT_HISTORY_CONF_LABELS = { - 0: "不记录聊天记录", - 1: "上报文字", - 2: "上报文字+语音" +const CHAT_HISTORY_CONF_LABEL_KEYS = { + 0: "agentSnapshot.chatHistoryConf.none", + 1: "agentSnapshot.chatHistoryConf.text", + 2: "agentSnapshot.chatHistoryConf.textVoice" }; export default { @@ -456,16 +482,22 @@ export default { currentSnapshot: null, restorePreviewSnapshot: null, restorePreviewRow: null, + deletingSnapshotId: null, pluginMetadata: {}, pluginMetadataLoaded: false, pluginMetadataLoading: null, modelNameMap: {}, modelMetadataLoaded: false, modelMetadataLoading: null, - voiceNameMap: { ...FALLBACK_VOICE_NAMES }, + voiceNameMap: {}, voiceMetadataLoading: {}, loadedVoiceModelIds: {}, snapshotFetchSeq: 0, + detailFetchSeq: 0, + restorePreviewFetchSeq: 0, + restoreActionSeq: 0, + deleteActionSeq: 0, + historyAnchorVersionNo: null, historyTotal: 0, page: 1, limit: 10, @@ -503,10 +535,11 @@ export default { const beforeData = this.currentSnapshot.snapshotData || {}; const afterData = this.currentSnapshot.afterSnapshotData || {}; return this.buildDiffs(beforeData, afterData, this.currentSnapshot.changedFields || [], { - beforeLabel: "变化前", - afterLabel: "变化后", + beforeLabel: this.$t("agentSnapshot.beforeChange"), + afterLabel: this.$t("agentSnapshot.afterChange"), beforeVersionNo: this.currentSnapshot.beforeVersionNo, - afterVersionNo: this.currentSnapshot.afterVersionNo || this.currentSnapshot.versionNo + afterVersionNo: this.currentSnapshot.afterVersionNo || this.currentSnapshot.versionNo, + fieldOrder: this.currentSnapshot.fieldOrder }); }, restorePreviewDiffs() { @@ -519,17 +552,35 @@ export default { this.restorePreviewSnapshot.afterSnapshotData || {}, [], { - beforeLabel: "恢复前", - afterLabel: "恢复后", + beforeLabel: this.$t("agentSnapshot.beforeRestore"), + afterLabel: this.$t("agentSnapshot.afterRestore"), beforeVersionNo: this.restorePreviewSnapshot.beforeVersionNo || this.resolveCurrentVersionNo(), - afterVersionNo: this.restorePreviewSnapshot.afterVersionNo || this.restorePreviewSnapshot.versionNo + afterVersionNo: this.restorePreviewSnapshot.afterVersionNo || this.restorePreviewSnapshot.versionNo, + fieldOrder: this.restorePreviewSnapshot.fieldOrder } ); + }, + restoreWillClearChatHistory() { + return this.restorePreviewSnapshot?.afterSnapshotData?.memModelId === "Memory_nomem"; + }, + restoreTargetVersion() { + return this.restorePreviewSnapshot?.versionNo || this.restorePreviewRow?.versionNo || ""; } }, + watch: { + currentVersionNo(newValue, oldValue) { + if (this.visible && newValue !== oldValue) { + this.historyAnchorVersionNo = null; + this.fetchSnapshots({ clearTable: false }); + } + } + }, + beforeDestroy() { + this.cancelPendingSnapshotRequests(); + }, methods: { buildDiffs(beforeData, afterData, changedFields, options = {}) { - const fields = this.resolveDiffFields(beforeData, afterData, changedFields); + const fields = this.resolveDiffFields(beforeData, afterData, changedFields, options.fieldOrder); return fields.map((field) => { const beforeValue = this.getFieldValue(beforeData, field); const afterValue = this.getFieldValue(afterData, field); @@ -552,10 +603,27 @@ export default { }); }, close() { - this.snapshotFetchSeq += 1; - this.loading = false; + this.cancelPendingSnapshotRequests(); + this.historyAnchorVersionNo = null; this.$emit("update:visible", false); }, + open() { + this.historyAnchorVersionNo = null; + this.page = 1; + this.fetchSnapshots(); + }, + cancelPendingSnapshotRequests() { + this.snapshotFetchSeq += 1; + this.detailFetchSeq += 1; + this.restorePreviewFetchSeq += 1; + this.restoreActionSeq += 1; + this.deleteActionSeq += 1; + this.loading = false; + this.detailLoading = false; + this.restorePreviewLoading = false; + this.restoring = false; + this.deletingSnapshotId = null; + }, snapshotRowKey(row) { if (row?.isCurrentVersion) { return "current-version"; @@ -566,11 +634,14 @@ export default { return row?.isCurrentVersion ? "current-version-row" : ""; }, canViewSnapshot(row) { - return Number(row?.versionNo) > 1; + return !!row && (row.isCurrentVersion || row.previousSnapshotId || row.previousVersionNo); }, canRestoreSnapshot(row) { return !!row && !row.isCurrentVersion; }, + canDeleteSnapshot(row) { + return !!row && !row.isCurrentVersion && !row.isLatestSnapshot; + }, fetchSnapshots(options = {}) { if (!this.agentId) { this.snapshots = []; @@ -582,7 +653,7 @@ export default { const requestSeq = ++this.snapshotFetchSeq; const displayStart = (this.page - 1) * this.limit; const displayEnd = displayStart + this.limit; - const historyFetchLimit = Math.max(displayEnd, this.limit, 1); + const historyFetchLimit = Math.max(displayEnd + 1, this.limit, 1); this.ensurePluginMetadata(); this.ensureModelMetadata(); this.loading = true; @@ -591,24 +662,32 @@ export default { } Api.agent.getAgentSnapshots( this.agentId, - { page: "1", limit: String(historyFetchLimit) }, + this.snapshotQueryParams({ page: "1", limit: String(historyFetchLimit) }), ({ data }) => { if (requestSeq !== this.snapshotFetchSeq) { return; } this.loading = false; if (data.code === 0) { - const historyRows = data.data?.list || []; + const historyRows = this.decorateSnapshotRows(data.data?.list || []); + if (!this.historyAnchorVersionNo && historyRows[0]?.versionNo) { + this.historyAnchorVersionNo = Number(historyRows[0].versionNo); + } + const currentRow = this.buildCurrentVersionRow(historyRows[0]); + const historyOffset = currentRow ? 1 : 0; this.historyTotal = data.data?.total || 0; - this.total = this.historyTotal + 1; + this.total = this.historyTotal + historyOffset; if (this.page === 1) { + const firstPageRows = historyRows.slice(0, currentRow ? this.limit - 1 : this.limit); this.snapshots = [ - this.buildCurrentVersionRow(historyRows[0]), - ...this.applyPreviousChangedFields(historyRows.slice(0, this.limit - 1), historyRows) + ...(currentRow ? [currentRow] : []), + ...this.applyPreviousChangedFields(firstPageRows, historyRows) ]; } else { + const historyStart = Math.max(displayStart - historyOffset, 0); + const historyEnd = Math.max(displayEnd - historyOffset, 0); this.snapshots = this.applyPreviousChangedFields( - historyRows.slice(displayStart - 1, displayEnd - 1), + historyRows.slice(historyStart, historyEnd), historyRows ); } @@ -629,18 +708,27 @@ export default { this.detailVisible = true; this.detailLoading = true; this.currentSnapshot = null; + const requestSeq = ++this.detailFetchSeq; this.ensurePluginMetadata(); this.ensureModelMetadata(); this.buildVersionDiffSnapshot(row) .then((snapshot) => this.ensureDisplayMetadata(snapshot).then(() => snapshot)) .then((snapshot) => { + if (requestSeq !== this.detailFetchSeq) { + return; + } this.currentSnapshot = snapshot; }) .catch(() => { + if (requestSeq !== this.detailFetchSeq) { + return; + } this.$message.error(this.$t("agentSnapshot.detailFailed")); }) .finally(() => { - this.detailLoading = false; + if (requestSeq === this.detailFetchSeq) { + this.detailLoading = false; + } }); }, restoreSnapshot(row) { @@ -651,6 +739,7 @@ export default { this.restorePreviewLoading = true; this.restorePreviewRow = row; this.restorePreviewSnapshot = null; + const requestSeq = ++this.restorePreviewFetchSeq; this.ensurePluginMetadata(); this.ensureModelMetadata(); @@ -658,41 +747,97 @@ export default { this.fetchSnapshotDetail(row.id), this.fetchCurrentAgentData() ]).then(([targetSnapshot, currentData]) => { + if (requestSeq !== this.restorePreviewFetchSeq) { + return Promise.resolve(); + } const previewSnapshot = { ...targetSnapshot, beforeSnapshotData: currentData, afterSnapshotData: targetSnapshot.snapshotData || {}, beforeVersionNo: this.resolveCurrentVersionNo(), - afterVersionNo: targetSnapshot.versionNo + afterVersionNo: targetSnapshot.versionNo, + fieldOrder: targetSnapshot.fieldOrder || [] }; return this.ensureDisplayMetadata(previewSnapshot).then(() => { + if (requestSeq !== this.restorePreviewFetchSeq) { + return; + } this.restorePreviewSnapshot = previewSnapshot; }); }).catch(() => { + if (requestSeq !== this.restorePreviewFetchSeq) { + return; + } this.restorePreviewVisible = false; this.$message.error(this.$t("agentSnapshot.detailFailed")); }).finally(() => { - this.restorePreviewLoading = false; + if (requestSeq === this.restorePreviewFetchSeq) { + this.restorePreviewLoading = false; + } }); }, + decorateSnapshotRows(rows) { + return (rows || []).map((row, index) => ({ + ...row, + isLatestSnapshot: index === 0 + })); + }, confirmRestoreSnapshot() { if (!this.restorePreviewRow) { return; } this.restoring = true; + const requestSeq = ++this.restoreActionSeq; Api.agent.restoreAgentSnapshot(this.agentId, this.restorePreviewRow.id, ({ data }) => { + if (requestSeq !== this.restoreActionSeq) { + return; + } this.restoring = false; if (data.code === 0) { this.$message.success(this.$t("agentSnapshot.restoreSuccess")); this.restorePreviewVisible = false; this.detailVisible = false; this.$emit("restored"); + this.historyAnchorVersionNo = null; this.fetchSnapshots(); } else { - this.$message.error(data.msg || this.$t("agentSnapshot.restoreFailed")); + this.$message.error(this.restoreFailedMessage(data)); } }); }, + deleteSnapshot(row) { + if (!this.canDeleteSnapshot(row)) { + return; + } + this.$confirm( + this.$t("agentSnapshot.deleteConfirm", { version: row.versionNo }), + this.$t("common.warning"), + { + confirmButtonText: this.$t("common.confirm"), + cancelButtonText: this.$t("common.cancel"), + type: "warning" + } + ).then(() => { + const requestSeq = ++this.deleteActionSeq; + this.deletingSnapshotId = row.id; + Api.agent.deleteAgentSnapshot(this.agentId, row.id, ({ data }) => { + if (requestSeq !== this.deleteActionSeq) { + return; + } + this.deletingSnapshotId = null; + if (data.code === 0) { + this.$message.success(this.$t("agentSnapshot.deleteSuccess")); + const savedRowsOnPage = this.snapshots.filter((item) => !item.isCurrentVersion); + if (savedRowsOnPage.length <= 1 && this.page > 1) { + this.page -= 1; + } + this.fetchSnapshots(); + } else { + this.$message.error(data.msg || this.$t("agentSnapshot.deleteFailed")); + } + }); + }).catch(() => {}); + }, hasAfterSnapshotData(snapshot) { return !!( snapshot && @@ -701,8 +846,9 @@ export default { ); }, resolveCurrentVersionNo() { - if (this.currentVersionNo) { - return this.currentVersionNo; + const propVersionNo = Number(this.currentVersionNo); + if (Number.isFinite(propVersionNo) && propVersionNo > 0) { + return propVersionNo; } const currentRow = this.snapshots.find((item) => item.isCurrentVersion); @@ -710,12 +856,7 @@ export default { return currentRow.versionNo; } - const maxVersionNo = Math.max( - ...this.snapshots - .filter((item) => !item.isCurrentVersion) - .map((item) => Number(item.versionNo) || 0) - ); - return maxVersionNo > 0 ? maxVersionNo + 1 : 1; + return null; }, formatPaneTitle(label, versionNo) { return versionNo ? `${label} #${versionNo}` : label; @@ -745,7 +886,7 @@ export default { }, fetchSnapshotRows(params) { return new Promise((resolve, reject) => { - Api.agent.getAgentSnapshots(this.agentId, params, ({ data }) => { + Api.agent.getAgentSnapshots(this.agentId, this.snapshotQueryParams(params), ({ data }) => { if (data.code === 0) { resolve(data.data || { list: [], total: 0 }); } else { @@ -754,6 +895,15 @@ export default { }); }); }, + snapshotQueryParams(params = {}) { + if (!this.historyAnchorVersionNo) { + return params; + } + return { + ...params, + maxVersionNo: String(this.historyAnchorVersionNo) + }; + }, applyPreviousChangedFields(rows, sourceRows) { return rows.map((row) => { const versionNo = Number(row.versionNo); @@ -763,27 +913,38 @@ export default { changedFields: [] }; } - const previousRow = sourceRows.find((item) => Number(item.versionNo) === versionNo - 1); + const previousRow = this.findPreviousSnapshotRow(row, sourceRows); return { ...row, + previousSnapshotId: previousRow?.id || null, + previousVersionNo: previousRow?.versionNo || null, changedFields: previousRow?.changedFields || [] }; }); }, + findPreviousSnapshotRow(row, sourceRows) { + const versionNo = Number(row?.versionNo); + if (!Number.isFinite(versionNo)) { + return null; + } + return (sourceRows || []).find((item) => { + return !item.isCurrentVersion && Number(item.versionNo) < versionNo; + }) || null; + }, buildCurrentVersionRow(latestSnapshot) { const latestVersionNo = Number(latestSnapshot?.versionNo) || 0; const propVersionNo = Number(this.currentVersionNo); - const inferredVersionNo = latestVersionNo + 1 || 1; - const currentVersionNo = Number.isFinite(propVersionNo) && propVersionNo > latestVersionNo - ? propVersionNo - : inferredVersionNo; + if (!Number.isFinite(propVersionNo) || propVersionNo <= latestVersionNo) { + return null; + } return { id: "__current__", agentId: this.agentId, - versionNo: currentVersionNo, + versionNo: propVersionNo, source: "current", createdAt: latestSnapshot?.createdAt || null, changedFields: latestSnapshot?.changedFields || [], + fieldOrder: latestSnapshot?.fieldOrder || [], isCurrentVersion: true, previousVersionNo: latestVersionNo || null, previousSnapshotId: latestSnapshot?.id || null @@ -797,9 +958,8 @@ export default { }, buildCurrentVersionDiffSnapshot(row) { const currentVersionNo = Number(row.versionNo); - const previousVersionNo = currentVersionNo - 1; return Promise.all([ - this.fetchSnapshotDetailByVersion(previousVersionNo), + this.fetchPreviousSnapshotDetail(row), this.fetchCurrentAgentData() ]).then(([previousSnapshot, currentData]) => ({ ...row, @@ -807,26 +967,41 @@ export default { changedFields: previousSnapshot.changedFields || [], snapshotData: previousSnapshot.snapshotData || {}, afterSnapshotData: currentData, - beforeVersionNo: previousVersionNo, - afterVersionNo: currentVersionNo + beforeVersionNo: previousSnapshot.versionNo, + afterVersionNo: currentVersionNo, + fieldOrder: previousSnapshot.fieldOrder || row.fieldOrder || [] })); }, buildSavedVersionDiffSnapshot(row) { const versionNo = Number(row.versionNo); - const previousVersionNo = versionNo - 1; return Promise.all([ this.fetchSnapshotDetail(row.id), - this.fetchSnapshotDetailByVersion(previousVersionNo) + this.fetchPreviousSnapshotDetail(row) ]).then(([selectedSnapshot, previousSnapshot]) => ({ ...selectedSnapshot, versionNo, changedFields: previousSnapshot.changedFields || [], snapshotData: previousSnapshot.snapshotData || {}, afterSnapshotData: selectedSnapshot.snapshotData || {}, - beforeVersionNo: previousVersionNo, - afterVersionNo: versionNo + beforeVersionNo: previousSnapshot.versionNo, + afterVersionNo: versionNo, + fieldOrder: selectedSnapshot.fieldOrder || previousSnapshot.fieldOrder || row.fieldOrder || [] })); }, + fetchPreviousSnapshotDetail(row) { + if (row?.previousSnapshotId) { + return this.fetchSnapshotDetail(row.previousSnapshotId); + } + if (row?.previousVersionNo) { + return this.fetchSnapshotDetailByVersion(row.previousVersionNo); + } + return this.fetchSnapshotRowBeforeVersion(row?.versionNo).then((previousRow) => { + if (!previousRow?.id) { + return Promise.reject(new Error("previous snapshot not found")); + } + return this.fetchSnapshotDetail(previousRow.id); + }); + }, fetchSnapshotDetailByVersion(versionNo) { return this.fetchSnapshotRowByVersion(versionNo).then((row) => { if (!row?.id) { @@ -867,6 +1042,17 @@ export default { }); }); }, + fetchSnapshotRowBeforeVersion(versionNo) { + const cached = this.findPreviousSnapshotRow({ versionNo }, this.snapshots); + if (cached) { + return Promise.resolve(cached); + } + + return this.fetchSnapshotRows({ + page: "1", + limit: String(Math.max(this.historyTotal, this.limit, 1)) + }).then((data) => this.findPreviousSnapshotRow({ versionNo }, data.list || [])); + }, ensurePluginMetadata() { if (this.pluginMetadataLoaded) { return Promise.resolve(); @@ -927,7 +1113,7 @@ export default { this.modelMetadataLoading = Promise.all(fetchers) .then((groups) => { - const metadata = { ...FALLBACK_MODEL_NAMES }; + const metadata = {}; groups.flat().forEach((item) => { if (item.id) { metadata[item.id] = item.name || item.id; @@ -1166,13 +1352,13 @@ export default { const name = this.functionDisplayName(pluginId); const statusMap = { added: { - badge: "已开启" + badge: this.$t("agentSnapshot.function.added") }, removed: { - badge: "已关闭" + badge: this.$t("agentSnapshot.function.removed") }, updated: { - badge: "参数变更" + badge: this.$t("agentSnapshot.function.updated") } }; return { @@ -1188,18 +1374,18 @@ export default { if (!func) { return { active: false, - status: "未开启", + status: this.$t("agentSnapshot.function.disabled"), params: [], - note: "未开启此功能" + note: this.$t("agentSnapshot.function.disabledNote") }; } const params = this.functionParamRows(pluginId, func.params, changedParamKeys); return { active: true, - status: "已开启", + status: this.$t("agentSnapshot.function.enabled"), params, - note: params.length ? "" : "无需配置参数" + note: params.length ? "" : this.$t("agentSnapshot.function.noParams") }; }, changedFunctionParamKeys(pluginId, beforeParams, afterParams) { @@ -1235,11 +1421,12 @@ export default { }, functionDisplayName(pluginId) { const meta = this.resolveFunctionMeta(pluginId); - return meta?.name || FALLBACK_PLUGIN_NAMES[pluginId] || pluginId || this.$t("agentSnapshot.emptyValue"); + return meta?.name || this.translateKey(FALLBACK_PLUGIN_NAME_KEYS[pluginId], pluginId) + || pluginId || this.$t("agentSnapshot.emptyValue"); }, functionParamLabel(pluginId, key) { const field = this.functionFields(pluginId).find((item) => item.key === key); - return field?.label || FALLBACK_FIELD_LABELS[key] || key; + return field?.label || this.translateKey(FALLBACK_FIELD_LABEL_KEYS[key], key) || key; }, functionFields(pluginId) { const meta = this.resolveFunctionMeta(pluginId); @@ -1273,7 +1460,7 @@ export default { const lines = String(value).replace(/\r\n/g, "\n").split("\n"); const html = []; let paragraph = []; - let listType = null; + const listStack = []; const closeParagraph = () => { if (paragraph.length) { @@ -1281,59 +1468,89 @@ export default { paragraph = []; } }; - const closeList = () => { - if (listType) { - html.push(``); - listType = null; + const closeOneList = () => { + const list = listStack.pop(); + if (!list) { + return; + } + if (list.liOpen) { + html.push(""); + } + html.push(``); + }; + const closeLists = () => { + while (listStack.length) { + closeOneList(); } }; - const openList = (type) => { - if (listType !== type) { - closeList(); - html.push(`<${type}>`); - listType = type; + const openList = (type, indent) => { + html.push(`<${type}>`); + listStack.push({ type, indent, liOpen: false }); + }; + const alignList = (type, indent) => { + while (listStack.length && indent < listStack[listStack.length - 1].indent) { + closeOneList(); } + + let current = listStack[listStack.length - 1]; + if (current && indent === current.indent && type !== current.type) { + closeOneList(); + } + + current = listStack[listStack.length - 1]; + if (!current || indent > current.indent || indent !== current.indent) { + openList(type, indent); + } + }; + const addListItem = (type, indent, text) => { + closeParagraph(); + alignList(type, indent); + const current = listStack[listStack.length - 1]; + if (current.liOpen) { + html.push(""); + } + html.push(`
  • ${this.renderInlineMarkdown(text)}`); + current.liOpen = true; }; lines.forEach((rawLine) => { - const line = rawLine.trim(); + const normalizedLine = rawLine.replace(/\t/g, " "); + const line = normalizedLine.trim(); if (!line) { closeParagraph(); - closeList(); + closeLists(); return; } const heading = line.match(/^(#{1,6})\s+(.+)$/); if (heading) { closeParagraph(); - closeList(); + closeLists(); const level = Math.min(heading[1].length, 4); html.push(`${this.renderInlineMarkdown(heading[2])}`); return; } - const unordered = line.match(/^[-*+]\s+(.+)$/); + const indent = normalizedLine.match(/^ */)[0].length; + const listContent = normalizedLine.slice(indent); + const unordered = listContent.match(/^[-*+]\s+(.+)$/); if (unordered) { - closeParagraph(); - openList("ul"); - html.push(`
  • ${this.renderInlineMarkdown(unordered[1])}
  • `); + addListItem("ul", indent, unordered[1]); return; } - const ordered = line.match(/^\d+\.\s+(.+)$/); + const ordered = listContent.match(/^\d+\.\s+(.+)$/); if (ordered) { - closeParagraph(); - openList("ol"); - html.push(`
  • ${this.renderInlineMarkdown(ordered[1])}
  • `); + addListItem("ol", indent, ordered[1]); return; } - closeList(); + closeLists(); paragraph.push(line); }); closeParagraph(); - closeList(); + closeLists(); return html.join(""); }, renderInlineMarkdown(value) { @@ -1351,13 +1568,19 @@ export default { .replace(/"/g, """) .replace(/'/g, "'"); }, - resolveDiffFields(beforeData, afterData, changedFields) { - const directFields = changedFields + restoreFailedMessage(data) { + return data?.msg + ? `${this.$t("agentSnapshot.restoreFailedRollback")}: ${data.msg}` + : this.$t("agentSnapshot.restoreFailedRollback"); + }, + resolveDiffFields(beforeData, afterData, changedFields = [], fieldOrder = []) { + const safeChangedFields = Array.isArray(changedFields) ? changedFields : []; + const directFields = safeChangedFields .filter((field) => field && field !== "restore") .map((field) => this.canonicalField(field)); - const candidates = directFields.length > 0 && !changedFields.includes("restore") + const candidates = directFields.length > 0 && !safeChangedFields.includes("restore") ? directFields - : this.snapshotFieldOrder(); + : this.snapshotFieldOrder(fieldOrder, beforeData, afterData); return Array.from(new Set(candidates)).filter((field) => { return !this.isSameValue( @@ -1366,38 +1589,19 @@ export default { ); }); }, - snapshotFieldOrder() { - return [ - "agentCode", - "agentName", - "asrModelId", - "vadModelId", - "llmModelId", - "slmModelId", - "vllmModelId", - "ttsModelId", - "ttsVoiceId", - "ttsLanguage", - "ttsVolume", - "ttsRate", - "ttsPitch", - "memModelId", - "intentModelId", - "chatHistoryConf", - "systemPrompt", - "summaryMemory", - "langCode", - "language", - "sort", - "functions", - "contextProviders", - "correctWordFileIds", - "tagNames", - "tagIds" - ]; + snapshotFieldOrder(fieldOrder = [], beforeData = {}, afterData = {}) { + const backendOrder = Array.isArray(fieldOrder) ? fieldOrder : []; + if (backendOrder.length) { + return backendOrder.map((field) => this.canonicalField(field)); + } + const dataFields = [ + ...Object.keys(beforeData || {}), + ...Object.keys(afterData || {}) + ].map((field) => this.canonicalField(field)); + return Array.from(new Set(dataFields)).filter((field) => field !== "tags"); }, canonicalField(field) { - return field === "tags" ? "tagNames" : field; + return field === "tags" || field === "tagIds" ? "tagNames" : field; }, getFieldValue(data, field) { if (!data) { @@ -1434,7 +1638,8 @@ export default { return this.voiceDisplayName(data.ttsModelId, value); } if (field === "chatHistoryConf") { - return CHAT_HISTORY_CONF_LABELS[value] || CHAT_HISTORY_CONF_LABELS[Number(value)] || this.formatValue(value); + return this.translateKey(CHAT_HISTORY_CONF_LABEL_KEYS[value] || CHAT_HISTORY_CONF_LABEL_KEYS[Number(value)]) + || this.formatValue(value); } return this.formatValue(value); }, @@ -1442,13 +1647,14 @@ export default { if (value === null || value === undefined || value === "") { return this.$t("agentSnapshot.emptyValue"); } - return this.modelNameMap[value] || FALLBACK_MODEL_NAMES[value] || String(value); + return this.modelNameMap[value] || this.translateKey(FALLBACK_MODEL_NAME_KEYS[value], String(value)) || String(value); }, voiceDisplayName(modelId, value) { if (value === null || value === undefined || value === "") { return this.$t("agentSnapshot.emptyValue"); } - return this.voiceNameMap[`${modelId}:${value}`] || this.voiceNameMap[value] || String(value); + return this.voiceNameMap[`${modelId}:${value}`] || this.voiceNameMap[value] + || this.translateKey(FALLBACK_VOICE_NAME_KEYS[value], String(value)) || String(value); }, formatValue(value) { if (value === null || value === undefined || value === "") { @@ -1481,6 +1687,9 @@ export default { fieldLabel(field) { const key = `agentSnapshot.field.${field}`; return this.$te && this.$te(key) ? this.$t(key) : field; + }, + translateKey(key, fallback = "") { + return key && this.$te && this.$te(key) ? this.$t(key) : fallback; } } }; @@ -1540,6 +1749,10 @@ export default { background: #fbfffa; } +.snapshot-delete-button { + color: #f56c6c; +} + .field-tags { display: flex; flex-wrap: wrap; @@ -1564,6 +1777,10 @@ export default { @include scrollbar-style; } +.restore-risk-alert { + margin-top: 14px; +} + .detail-summary { display: flex; flex-wrap: wrap; diff --git a/main/manager-web/src/i18n/de.js b/main/manager-web/src/i18n/de.js index d1a42bb9..414a3283 100644 --- a/main/manager-web/src/i18n/de.js +++ b/main/manager-web/src/i18n/de.js @@ -806,12 +806,126 @@ export default { 'roleConfig.addTag': 'Neues Label hinzufügen', 'roleConfig.restartNotice': 'Neustart nach Konfigurationsspeichern zur Aktivierung.', 'roleConfig.saveConfig': 'Konfiguration speichern', + 'roleConfig.snapshotHistory': 'Versionsverlauf', + 'roleConfig.currentVersion': 'Aktuelle Version {version}', + 'roleConfig.functionName': 'Funktionsname', 'roleConfig.reset': 'Zurücksetzen', 'roleConfig.agentName': 'Spitzname', 'roleConfig.roleTemplate': 'Vorlage', 'roleConfig.roleIntroduction': 'Einführung', 'roleConfig.languageCode': 'Sprachcode', 'roleConfig.interactionLanguage': 'Interaktionssprache', + 'agentSnapshot.title': 'Versionsverlauf', + 'agentSnapshot.empty': 'Noch keine Versionen', + 'agentSnapshot.version': 'Version', + 'agentSnapshot.createdAt': 'Gespeichert am', + 'agentSnapshot.source': 'Quelle', + 'agentSnapshot.changedFields': 'Änderungen', + 'agentSnapshot.actions': 'Aktionen', + 'agentSnapshot.view': 'Anzeigen', + 'agentSnapshot.restore': 'Wiederherstellen', + 'agentSnapshot.delete': 'Löschen', + 'agentSnapshot.detailTitle': 'Änderungsdetails', + 'agentSnapshot.restorePreviewTitle': 'Wiederherstellungsvorschau', + 'agentSnapshot.confirmRestore': 'Wiederherstellung bestätigen', + 'agentSnapshot.before': 'Vorher', + 'agentSnapshot.after': 'Nachher', + 'agentSnapshot.emptyValue': 'Keine', + 'agentSnapshot.noChangedContent': 'Keine anzeigbaren Änderungen', + 'agentSnapshot.noFunctionChange': 'Keine Funktionsänderungen', + 'agentSnapshot.beforeChange': 'Vor der Änderung', + 'agentSnapshot.afterChange': 'Nach der Änderung', + 'agentSnapshot.beforeRestore': 'Vor der Wiederherstellung', + 'agentSnapshot.afterRestore': 'Nach der Wiederherstellung', + 'agentSnapshot.restoreMemoryWarning': 'Beim Wiederherstellen einer Version ohne Speicher wird der Chatverlauf dieses Agenten gelöscht. Fahren Sie nur fort, wenn Sie dieses Risiko bestätigt haben.', + 'agentSnapshot.restoreConfirm': 'Version {version} wiederherstellen? Die aktuelle Konfiguration wird zuerst als neue Version gespeichert.', + 'agentSnapshot.restoreSuccess': 'Version wurde wiederhergestellt', + 'agentSnapshot.restoreFailed': 'Version konnte nicht wiederhergestellt werden', + 'agentSnapshot.restoreFailedRollback': 'Version konnte nicht wiederhergestellt werden. Die Transaktion wurde zurueckgerollt und die aktuelle Konfiguration wurde nicht geaendert', + 'agentSnapshot.deleteConfirm': 'Version {version} löschen? Dies kann nicht rückgängig gemacht werden.', + 'agentSnapshot.deleteSuccess': 'Verlaufsversion gelöscht', + 'agentSnapshot.deleteFailed': 'Verlaufsversion konnte nicht gelöscht werden', + 'agentSnapshot.fetchFailed': 'Versionsverlauf konnte nicht abgerufen werden', + 'agentSnapshot.detailFailed': 'Snapshot-Details konnten nicht abgerufen werden', + 'agentSnapshot.currentVersion': 'Aktuelle Version', + 'agentSnapshot.source.config': 'Konfiguration gespeichert', + 'agentSnapshot.source.current': 'Aktuelle Konfiguration', + 'agentSnapshot.source.restore': 'Vor der Wiederherstellung', + 'agentSnapshot.source.initial': 'Initialversion', + 'agentSnapshot.field.restore': 'Wiederherstellung', + 'agentSnapshot.field.initial': 'Initialer Snapshot', + 'agentSnapshot.field.agentCode': 'Agent-Code', + 'agentSnapshot.field.agentName': 'Spitzname', + 'agentSnapshot.field.asrModelId': 'Spracherkennung', + 'agentSnapshot.field.vadModelId': 'Sprachaktivitätserkennung', + 'agentSnapshot.field.llmModelId': 'Hauptsprachmodell', + 'agentSnapshot.field.slmModelId': 'Kleines Sprachmodell', + 'agentSnapshot.field.vllmModelId': 'Vision-Modell', + 'agentSnapshot.field.ttsModelId': 'Text-zu-Sprache', + 'agentSnapshot.field.ttsVoiceId': 'Stimme', + 'agentSnapshot.field.ttsLanguage': 'Sprache', + 'agentSnapshot.field.ttsVolume': 'Lautstärke', + 'agentSnapshot.field.ttsRate': 'Geschwindigkeit', + 'agentSnapshot.field.ttsPitch': 'Tonhöhe', + 'agentSnapshot.field.memModelId': 'Speichermodell', + 'agentSnapshot.field.intentModelId': 'Absichtserkennung', + 'agentSnapshot.field.chatHistoryConf': 'Chatverlauf', + 'agentSnapshot.field.systemPrompt': 'Einführung', + 'agentSnapshot.field.summaryMemory': 'Speicher', + 'agentSnapshot.field.langCode': 'Sprachcode', + 'agentSnapshot.field.language': 'Interaktionssprache', + 'agentSnapshot.field.sort': 'Sortierung', + 'agentSnapshot.field.functions': 'Funktionen', + 'agentSnapshot.field.contextProviders': 'Kontextquellen', + 'agentSnapshot.field.correctWordFileIds': 'Ersatzwörter', + 'agentSnapshot.field.tagNames': 'Labels', + 'agentSnapshot.field.tagIds': 'Label-IDs', + 'agentSnapshot.function.added': 'Aktiviert', + 'agentSnapshot.function.removed': 'Deaktiviert', + 'agentSnapshot.function.updated': 'Parameter geändert', + 'agentSnapshot.function.enabled': 'Aktiviert', + 'agentSnapshot.function.disabled': 'Deaktiviert', + 'agentSnapshot.function.disabledNote': 'Diese Funktion ist deaktiviert', + 'agentSnapshot.function.noParams': 'Keine Parameter erforderlich', + 'agentSnapshot.chatHistoryConf.none': 'Chatverlauf nicht aufzeichnen', + 'agentSnapshot.chatHistoryConf.text': 'Text melden', + 'agentSnapshot.chatHistoryConf.textVoice': 'Text und Sprache melden', + 'agentSnapshot.plugin.SYSTEM_PLUGIN_WEATHER': 'Wetter', + 'agentSnapshot.plugin.SYSTEM_PLUGIN_MUSIC': 'Server-Musikplayer', + 'agentSnapshot.plugin.SYSTEM_PLUGIN_NEWS_CHINANEWS': 'China News', + 'agentSnapshot.plugin.SYSTEM_PLUGIN_NEWS_NEWSNOW': 'NewsNow-Aggregation', + 'agentSnapshot.plugin.SYSTEM_PLUGIN_HA_GET_STATE': 'HomeAssistant-Statusabfrage', + 'agentSnapshot.plugin.SYSTEM_PLUGIN_HA_SET_STATE': 'HomeAssistant-Statusaktualisierung', + 'agentSnapshot.plugin.SYSTEM_PLUGIN_HA_PLAY_MUSIC': 'HomeAssistant-Musikplayer', + 'agentSnapshot.plugin.SYSTEM_PLUGIN_WEB_SEARCH': 'Websuche', + 'agentSnapshot.plugin.SYSTEM_PLUGIN_CALL_DEVICE': 'Geräteanruf', + 'agentSnapshot.pluginField.url': 'Endpunkt-URL', + 'agentSnapshot.pluginField.news_sources': 'Nachrichtenquellen', + 'agentSnapshot.pluginField.default_rss_url': 'Standard-RSS-URL', + 'agentSnapshot.pluginField.society_rss_url': 'RSS-URL für Gesellschaft', + 'agentSnapshot.pluginField.world_rss_url': 'RSS-URL für Welt', + 'agentSnapshot.pluginField.finance_rss_url': 'RSS-URL für Finanzen', + 'agentSnapshot.pluginField.api_key': 'API-Schlüssel', + 'agentSnapshot.pluginField.default_location': 'Standardstadt', + 'agentSnapshot.pluginField.api_host': 'Entwickler-API-Host', + 'agentSnapshot.pluginField.base_url': 'Server-URL', + 'agentSnapshot.pluginField.devices': 'Geräte', + 'agentSnapshot.pluginField.provider': 'Suchanbieter', + 'agentSnapshot.pluginField.description': 'Werkzeugbeschreibung', + 'agentSnapshot.pluginField.max_results': 'Ergebnisanzahl', + 'agentSnapshot.model.Memory_nomem': 'Kein Speicher', + 'agentSnapshot.model.Memory_mem_local_short': 'Lokaler Kurzzeitspeicher', + 'agentSnapshot.model.Memory_mem0ai': 'Mem0AI-Speicher', + 'agentSnapshot.model.Memory_mem_report_only': 'Nur melden', + 'agentSnapshot.model.Intent_nointent': 'Keine Absichtserkennung', + 'agentSnapshot.model.Intent_intent_llm': 'Externe LLM-Absichtserkennung', + 'agentSnapshot.model.Intent_function_call': 'LLM-Funktionsaufruf', + 'agentSnapshot.voice.TTS_EdgeTTS0001': 'EdgeTTS weiblich - Xiaoxiao', + 'agentSnapshot.voice.TTS_EdgeTTS0002': 'EdgeTTS männlich - Yunyang', + 'agentSnapshot.voice.TTS_EdgeTTS0003': 'EdgeTTS weiblich - Xiaoyi', + 'agentSnapshot.voice.TTS_EdgeTTS0004': 'EdgeTTS männlich - Yunjian', + 'agentSnapshot.voice.TTS_EdgeTTS0005': 'EdgeTTS männlich - Yunxi', + 'agentSnapshot.voice.TTS_EdgeTTS0006': 'EdgeTTS männlich - Yunxia', 'roleConfig.vad': 'VAD', 'roleConfig.asr': 'ASR', 'roleConfig.llm': 'Hauptsprachmodell (LLM)', @@ -1554,4 +1668,4 @@ export default { // Header navigation 'header.addressBook': 'Adressbuch', -} \ No newline at end of file +} diff --git a/main/manager-web/src/i18n/en.js b/main/manager-web/src/i18n/en.js index 9c62c087..9f339ffb 100644 --- a/main/manager-web/src/i18n/en.js +++ b/main/manager-web/src/i18n/en.js @@ -807,6 +807,8 @@ export default { 'roleConfig.restartNotice': 'After saving the configuration, you need to restart the device for the new configuration to take effect.', 'roleConfig.saveConfig': 'Save Configuration', 'roleConfig.snapshotHistory': 'History', + 'roleConfig.currentVersion': 'Current Version {version}', + 'roleConfig.functionName': 'Function Name', 'roleConfig.reset': 'Reset', 'roleConfig.agentName': 'Nickname', 'roleConfig.roleTemplate': 'Template', @@ -873,6 +875,7 @@ export default { 'agentSnapshot.actions': 'Actions', 'agentSnapshot.view': 'View', 'agentSnapshot.restore': 'Restore', + 'agentSnapshot.delete': 'Delete', 'agentSnapshot.detailTitle': 'Change Details', 'agentSnapshot.restorePreviewTitle': 'Restore Preview', 'agentSnapshot.confirmRestore': 'Confirm Restore', @@ -880,16 +883,28 @@ export default { 'agentSnapshot.after': 'After', 'agentSnapshot.emptyValue': 'None', 'agentSnapshot.noChangedContent': 'No changes to display', - 'agentSnapshot.restoreConfirm': 'Restore to version #{version}? The current configuration will be saved as a new version first.', + 'agentSnapshot.noFunctionChange': 'No function changes', + 'agentSnapshot.beforeChange': 'Before Change', + 'agentSnapshot.afterChange': 'After Change', + 'agentSnapshot.beforeRestore': 'Before Restore', + 'agentSnapshot.afterRestore': 'After Restore', + 'agentSnapshot.restoreMemoryWarning': 'Restoring to a no-memory version will clear this agent\'s chat history. Continue only after confirming this risk.', + 'agentSnapshot.restoreConfirm': 'Restore to version {version}? The current configuration will be saved as a new version first.', 'agentSnapshot.restoreSuccess': 'Version restored', 'agentSnapshot.restoreFailed': 'Failed to restore version', + 'agentSnapshot.restoreFailedRollback': 'Failed to restore version. The transaction was rolled back and the current configuration was not changed', + 'agentSnapshot.deleteConfirm': 'Delete version {version}? This cannot be undone.', + 'agentSnapshot.deleteSuccess': 'History version deleted', + 'agentSnapshot.deleteFailed': 'Failed to delete history version', 'agentSnapshot.fetchFailed': 'Failed to fetch versions', 'agentSnapshot.detailFailed': 'Failed to fetch snapshot details', 'agentSnapshot.currentVersion': 'Current Version', 'agentSnapshot.source.config': 'Config Save', 'agentSnapshot.source.current': 'Current Config', 'agentSnapshot.source.restore': 'Before Restore', + 'agentSnapshot.source.initial': 'Initial Version', 'agentSnapshot.field.restore': 'Restore', + 'agentSnapshot.field.initial': 'Initial Snapshot', 'agentSnapshot.field.agentCode': 'Agent Code', 'agentSnapshot.field.agentName': 'Nickname', 'agentSnapshot.field.asrModelId': 'Speech Recognition', @@ -916,6 +931,52 @@ export default { 'agentSnapshot.field.correctWordFileIds': 'Replacement Words', 'agentSnapshot.field.tagNames': 'Tags', 'agentSnapshot.field.tagIds': 'Tag IDs', + 'agentSnapshot.function.added': 'Enabled', + 'agentSnapshot.function.removed': 'Disabled', + 'agentSnapshot.function.updated': 'Parameters changed', + 'agentSnapshot.function.enabled': 'Enabled', + 'agentSnapshot.function.disabled': 'Disabled', + 'agentSnapshot.function.disabledNote': 'This function is disabled', + 'agentSnapshot.function.noParams': 'No parameters required', + 'agentSnapshot.chatHistoryConf.none': 'Do not record chat history', + 'agentSnapshot.chatHistoryConf.text': 'Report text', + 'agentSnapshot.chatHistoryConf.textVoice': 'Report text and voice', + 'agentSnapshot.plugin.SYSTEM_PLUGIN_WEATHER': 'Weather', + 'agentSnapshot.plugin.SYSTEM_PLUGIN_MUSIC': 'Server music player', + 'agentSnapshot.plugin.SYSTEM_PLUGIN_NEWS_CHINANEWS': 'China News', + 'agentSnapshot.plugin.SYSTEM_PLUGIN_NEWS_NEWSNOW': 'NewsNow aggregation', + 'agentSnapshot.plugin.SYSTEM_PLUGIN_HA_GET_STATE': 'HomeAssistant state query', + 'agentSnapshot.plugin.SYSTEM_PLUGIN_HA_SET_STATE': 'HomeAssistant state update', + 'agentSnapshot.plugin.SYSTEM_PLUGIN_HA_PLAY_MUSIC': 'HomeAssistant music player', + 'agentSnapshot.plugin.SYSTEM_PLUGIN_WEB_SEARCH': 'Web search', + 'agentSnapshot.plugin.SYSTEM_PLUGIN_CALL_DEVICE': 'Device-to-device call', + 'agentSnapshot.pluginField.url': 'Endpoint URL', + 'agentSnapshot.pluginField.news_sources': 'News sources', + 'agentSnapshot.pluginField.default_rss_url': 'Default RSS URL', + 'agentSnapshot.pluginField.society_rss_url': 'Society RSS URL', + 'agentSnapshot.pluginField.world_rss_url': 'World RSS URL', + 'agentSnapshot.pluginField.finance_rss_url': 'Finance RSS URL', + 'agentSnapshot.pluginField.api_key': 'API key', + 'agentSnapshot.pluginField.default_location': 'Default city', + 'agentSnapshot.pluginField.api_host': 'Developer API host', + 'agentSnapshot.pluginField.base_url': 'Server URL', + 'agentSnapshot.pluginField.devices': 'Devices', + 'agentSnapshot.pluginField.provider': 'Search provider', + 'agentSnapshot.pluginField.description': 'Tool description', + 'agentSnapshot.pluginField.max_results': 'Result count', + 'agentSnapshot.model.Memory_nomem': 'No memory', + 'agentSnapshot.model.Memory_mem_local_short': 'Local short memory', + 'agentSnapshot.model.Memory_mem0ai': 'Mem0AI memory', + 'agentSnapshot.model.Memory_mem_report_only': 'Report only', + 'agentSnapshot.model.Intent_nointent': 'No intent recognition', + 'agentSnapshot.model.Intent_intent_llm': 'External LLM intent recognition', + 'agentSnapshot.model.Intent_function_call': 'LLM function calling', + 'agentSnapshot.voice.TTS_EdgeTTS0001': 'EdgeTTS female - Xiaoxiao', + 'agentSnapshot.voice.TTS_EdgeTTS0002': 'EdgeTTS male - Yunyang', + 'agentSnapshot.voice.TTS_EdgeTTS0003': 'EdgeTTS female - Xiaoyi', + 'agentSnapshot.voice.TTS_EdgeTTS0004': 'EdgeTTS male - Yunjian', + 'agentSnapshot.voice.TTS_EdgeTTS0005': 'EdgeTTS male - Yunxi', + 'agentSnapshot.voice.TTS_EdgeTTS0006': 'EdgeTTS male - Yunxia', // Form field Tooltip descriptions 'roleConfig.tooltip.agentName': 'Set the name of your AI agent for identification and recognition', diff --git a/main/manager-web/src/i18n/pt_BR.js b/main/manager-web/src/i18n/pt_BR.js index 90e9fc87..8db61171 100644 --- a/main/manager-web/src/i18n/pt_BR.js +++ b/main/manager-web/src/i18n/pt_BR.js @@ -806,12 +806,126 @@ export default { 'roleConfig.addTag': 'Adicionar Novo Rótulo', 'roleConfig.restartNotice': 'Reinicie após salvar a configuração para ativação.', 'roleConfig.saveConfig': 'Salvar Configuração', + 'roleConfig.snapshotHistory': 'Histórico de Versões', + 'roleConfig.currentVersion': 'Versão Atual {version}', + 'roleConfig.functionName': 'Nome da Função', 'roleConfig.reset': 'Redefinir', 'roleConfig.agentName': 'Apelido', 'roleConfig.roleTemplate': 'Modelo', 'roleConfig.roleIntroduction': 'Introdução', 'roleConfig.languageCode': 'Código do Idioma', 'roleConfig.interactionLanguage': 'Idioma de Interação', + 'agentSnapshot.title': 'Histórico de Versões', + 'agentSnapshot.empty': 'Ainda sem versões', + 'agentSnapshot.version': 'Versão', + 'agentSnapshot.createdAt': 'Salvo em', + 'agentSnapshot.source': 'Origem', + 'agentSnapshot.changedFields': 'Alterações', + 'agentSnapshot.actions': 'Ações', + 'agentSnapshot.view': 'Ver', + 'agentSnapshot.restore': 'Restaurar', + 'agentSnapshot.delete': 'Excluir', + 'agentSnapshot.detailTitle': 'Detalhes da Alteração', + 'agentSnapshot.restorePreviewTitle': 'Prévia da Restauração', + 'agentSnapshot.confirmRestore': 'Confirmar Restauração', + 'agentSnapshot.before': 'Antes', + 'agentSnapshot.after': 'Depois', + 'agentSnapshot.emptyValue': 'Nenhum', + 'agentSnapshot.noChangedContent': 'Nenhuma alteração para exibir', + 'agentSnapshot.noFunctionChange': 'Sem alterações de função', + 'agentSnapshot.beforeChange': 'Antes da Alteração', + 'agentSnapshot.afterChange': 'Depois da Alteração', + 'agentSnapshot.beforeRestore': 'Antes da Restauração', + 'agentSnapshot.afterRestore': 'Depois da Restauração', + 'agentSnapshot.restoreMemoryWarning': 'Restaurar para uma versão sem memória apagará o histórico de conversa deste agente. Continue somente após confirmar esse risco.', + 'agentSnapshot.restoreConfirm': 'Restaurar para a versão {version}? A configuração atual será salva primeiro como uma nova versão.', + 'agentSnapshot.restoreSuccess': 'Versão restaurada', + 'agentSnapshot.restoreFailed': 'Falha ao restaurar versão', + 'agentSnapshot.restoreFailedRollback': 'Falha ao restaurar versão. A transação foi revertida e a configuração atual não foi alterada', + 'agentSnapshot.deleteConfirm': 'Excluir a versão {version}? Esta ação não pode ser desfeita.', + 'agentSnapshot.deleteSuccess': 'Versão do histórico excluída', + 'agentSnapshot.deleteFailed': 'Falha ao excluir a versão do histórico', + 'agentSnapshot.fetchFailed': 'Falha ao buscar versões', + 'agentSnapshot.detailFailed': 'Falha ao buscar detalhes do snapshot', + 'agentSnapshot.currentVersion': 'Versão Atual', + 'agentSnapshot.source.config': 'Configuração Salva', + 'agentSnapshot.source.current': 'Configuração Atual', + 'agentSnapshot.source.restore': 'Antes da Restauração', + 'agentSnapshot.source.initial': 'Versão inicial', + 'agentSnapshot.field.restore': 'Restauração', + 'agentSnapshot.field.initial': 'Snapshot inicial', + 'agentSnapshot.field.agentCode': 'Código do Agente', + 'agentSnapshot.field.agentName': 'Apelido', + 'agentSnapshot.field.asrModelId': 'Reconhecimento de Fala', + 'agentSnapshot.field.vadModelId': 'Detecção de Atividade de Voz', + 'agentSnapshot.field.llmModelId': 'Modelo de Linguagem Principal', + 'agentSnapshot.field.slmModelId': 'Modelo de Linguagem Pequeno', + 'agentSnapshot.field.vllmModelId': 'Modelo de Visão', + 'agentSnapshot.field.ttsModelId': 'Texto para Fala', + 'agentSnapshot.field.ttsVoiceId': 'Voz', + 'agentSnapshot.field.ttsLanguage': 'Idioma', + 'agentSnapshot.field.ttsVolume': 'Volume', + 'agentSnapshot.field.ttsRate': 'Velocidade', + 'agentSnapshot.field.ttsPitch': 'Tom', + 'agentSnapshot.field.memModelId': 'Modelo de Memória', + 'agentSnapshot.field.intentModelId': 'Reconhecimento de Intenção', + 'agentSnapshot.field.chatHistoryConf': 'Histórico de Conversa', + 'agentSnapshot.field.systemPrompt': 'Introdução', + 'agentSnapshot.field.summaryMemory': 'Memória', + 'agentSnapshot.field.langCode': 'Código do Idioma', + 'agentSnapshot.field.language': 'Idioma de Interação', + 'agentSnapshot.field.sort': 'Ordenação', + 'agentSnapshot.field.functions': 'Funções', + 'agentSnapshot.field.contextProviders': 'Provedores de Contexto', + 'agentSnapshot.field.correctWordFileIds': 'Palavras de Substituição', + 'agentSnapshot.field.tagNames': 'Rótulos', + 'agentSnapshot.field.tagIds': 'IDs dos Rótulos', + 'agentSnapshot.function.added': 'Ativado', + 'agentSnapshot.function.removed': 'Desativado', + 'agentSnapshot.function.updated': 'Parâmetros alterados', + 'agentSnapshot.function.enabled': 'Ativado', + 'agentSnapshot.function.disabled': 'Desativado', + 'agentSnapshot.function.disabledNote': 'Esta função está desativada', + 'agentSnapshot.function.noParams': 'Nenhum parâmetro necessário', + 'agentSnapshot.chatHistoryConf.none': 'Não registrar histórico de conversa', + 'agentSnapshot.chatHistoryConf.text': 'Enviar texto', + 'agentSnapshot.chatHistoryConf.textVoice': 'Enviar texto e voz', + 'agentSnapshot.plugin.SYSTEM_PLUGIN_WEATHER': 'Clima', + 'agentSnapshot.plugin.SYSTEM_PLUGIN_MUSIC': 'Reprodutor de música do servidor', + 'agentSnapshot.plugin.SYSTEM_PLUGIN_NEWS_CHINANEWS': 'China News', + 'agentSnapshot.plugin.SYSTEM_PLUGIN_NEWS_NEWSNOW': 'Agregação NewsNow', + 'agentSnapshot.plugin.SYSTEM_PLUGIN_HA_GET_STATE': 'Consulta de estado do HomeAssistant', + 'agentSnapshot.plugin.SYSTEM_PLUGIN_HA_SET_STATE': 'Atualização de estado do HomeAssistant', + 'agentSnapshot.plugin.SYSTEM_PLUGIN_HA_PLAY_MUSIC': 'Reprodutor de música do HomeAssistant', + 'agentSnapshot.plugin.SYSTEM_PLUGIN_WEB_SEARCH': 'Pesquisa na web', + 'agentSnapshot.plugin.SYSTEM_PLUGIN_CALL_DEVICE': 'Chamada entre dispositivos', + 'agentSnapshot.pluginField.url': 'URL do endpoint', + 'agentSnapshot.pluginField.news_sources': 'Fontes de notícias', + 'agentSnapshot.pluginField.default_rss_url': 'URL RSS padrão', + 'agentSnapshot.pluginField.society_rss_url': 'URL RSS de sociedade', + 'agentSnapshot.pluginField.world_rss_url': 'URL RSS mundial', + 'agentSnapshot.pluginField.finance_rss_url': 'URL RSS financeiro', + 'agentSnapshot.pluginField.api_key': 'Chave de API', + 'agentSnapshot.pluginField.default_location': 'Cidade padrão', + 'agentSnapshot.pluginField.api_host': 'Host da API de desenvolvedor', + 'agentSnapshot.pluginField.base_url': 'URL do servidor', + 'agentSnapshot.pluginField.devices': 'Dispositivos', + 'agentSnapshot.pluginField.provider': 'Provedor de pesquisa', + 'agentSnapshot.pluginField.description': 'Descrição da ferramenta', + 'agentSnapshot.pluginField.max_results': 'Quantidade de resultados', + 'agentSnapshot.model.Memory_nomem': 'Sem memória', + 'agentSnapshot.model.Memory_mem_local_short': 'Memória curta local', + 'agentSnapshot.model.Memory_mem0ai': 'Memória Mem0AI', + 'agentSnapshot.model.Memory_mem_report_only': 'Somente relatório', + 'agentSnapshot.model.Intent_nointent': 'Sem reconhecimento de intenção', + 'agentSnapshot.model.Intent_intent_llm': 'Reconhecimento de intenção por LLM externo', + 'agentSnapshot.model.Intent_function_call': 'Chamada de função por LLM', + 'agentSnapshot.voice.TTS_EdgeTTS0001': 'EdgeTTS feminino - Xiaoxiao', + 'agentSnapshot.voice.TTS_EdgeTTS0002': 'EdgeTTS masculino - Yunyang', + 'agentSnapshot.voice.TTS_EdgeTTS0003': 'EdgeTTS feminino - Xiaoyi', + 'agentSnapshot.voice.TTS_EdgeTTS0004': 'EdgeTTS masculino - Yunjian', + 'agentSnapshot.voice.TTS_EdgeTTS0005': 'EdgeTTS masculino - Yunxi', + 'agentSnapshot.voice.TTS_EdgeTTS0006': 'EdgeTTS masculino - Yunxia', 'roleConfig.vad': 'Detecção de Voz', 'roleConfig.asr': 'Reconhecimento de Fala', 'roleConfig.llm': 'Modelo de Linguagem Principal', @@ -1554,4 +1668,4 @@ export default { // Header navigation 'header.addressBook': 'Lista de Contatos', -} \ No newline at end of file +} diff --git a/main/manager-web/src/i18n/vi.js b/main/manager-web/src/i18n/vi.js index b58023aa..f78a0c64 100644 --- a/main/manager-web/src/i18n/vi.js +++ b/main/manager-web/src/i18n/vi.js @@ -806,12 +806,126 @@ export default { 'roleConfig.addTag': 'Thêm mới nhãn', 'roleConfig.restartNotice': 'Sau khi lưu cấu hình, bạn cần khởi động lại thiết bị để cấu hình mới có hiệu lực.', 'roleConfig.saveConfig': 'Lưu cấu hình', + 'roleConfig.snapshotHistory': 'Lịch sử phiên bản', + 'roleConfig.currentVersion': 'Phiên bản hiện tại {version}', + 'roleConfig.functionName': 'Tên chức năng', 'roleConfig.reset': 'Đặt lại', 'roleConfig.agentName': 'Biệt danh', 'roleConfig.roleTemplate': 'Mẫu', 'roleConfig.roleIntroduction': 'Giới thiệu', 'roleConfig.languageCode': 'Mã ngôn ngữ', 'roleConfig.interactionLanguage': 'Ngôn ngữ tương tác', + 'agentSnapshot.title': 'Lịch sử phiên bản', + 'agentSnapshot.empty': 'Chưa có phiên bản', + 'agentSnapshot.version': 'Phiên bản', + 'agentSnapshot.createdAt': 'Lưu lúc', + 'agentSnapshot.source': 'Nguồn', + 'agentSnapshot.changedFields': 'Thay đổi', + 'agentSnapshot.actions': 'Thao tác', + 'agentSnapshot.view': 'Xem', + 'agentSnapshot.restore': 'Khôi phục', + 'agentSnapshot.delete': 'Xóa', + 'agentSnapshot.detailTitle': 'Chi tiết thay đổi', + 'agentSnapshot.restorePreviewTitle': 'Xem trước khôi phục', + 'agentSnapshot.confirmRestore': 'Xác nhận khôi phục', + 'agentSnapshot.before': 'Trước', + 'agentSnapshot.after': 'Sau', + 'agentSnapshot.emptyValue': 'Không có', + 'agentSnapshot.noChangedContent': 'Không có thay đổi để hiển thị', + 'agentSnapshot.noFunctionChange': 'Không có thay đổi chức năng', + 'agentSnapshot.beforeChange': 'Trước thay đổi', + 'agentSnapshot.afterChange': 'Sau thay đổi', + 'agentSnapshot.beforeRestore': 'Trước khi khôi phục', + 'agentSnapshot.afterRestore': 'Sau khi khôi phục', + 'agentSnapshot.restoreMemoryWarning': 'Khôi phục về phiên bản không có bộ nhớ sẽ xóa lịch sử trò chuyện của tác nhân này. Chỉ tiếp tục sau khi xác nhận rủi ro này.', + 'agentSnapshot.restoreConfirm': 'Khôi phục về phiên bản {version}? Cấu hình hiện tại sẽ được lưu thành phiên bản mới trước.', + 'agentSnapshot.restoreSuccess': 'Đã khôi phục phiên bản', + 'agentSnapshot.restoreFailed': 'Khôi phục phiên bản thất bại', + 'agentSnapshot.restoreFailedRollback': 'Khôi phục phiên bản thất bại. Giao dịch đã được hoàn tác và cấu hình hiện tại chưa thay đổi', + 'agentSnapshot.deleteConfirm': 'Xóa phiên bản {version}? Không thể hoàn tác thao tác này.', + 'agentSnapshot.deleteSuccess': 'Đã xóa phiên bản lịch sử', + 'agentSnapshot.deleteFailed': 'Xóa phiên bản lịch sử thất bại', + 'agentSnapshot.fetchFailed': 'Không thể tải lịch sử phiên bản', + 'agentSnapshot.detailFailed': 'Không thể tải chi tiết snapshot', + 'agentSnapshot.currentVersion': 'Phiên bản hiện tại', + 'agentSnapshot.source.config': 'Lưu cấu hình', + 'agentSnapshot.source.current': 'Cấu hình hiện tại', + 'agentSnapshot.source.restore': 'Trước khi khôi phục', + 'agentSnapshot.source.initial': 'Phiên bản ban đầu', + 'agentSnapshot.field.restore': 'Khôi phục', + 'agentSnapshot.field.initial': 'Snapshot ban đầu', + 'agentSnapshot.field.agentCode': 'Mã tác nhân', + 'agentSnapshot.field.agentName': 'Biệt danh', + 'agentSnapshot.field.asrModelId': 'Nhận dạng giọng nói', + 'agentSnapshot.field.vadModelId': 'Phát hiện hoạt động giọng nói', + 'agentSnapshot.field.llmModelId': 'Mô hình ngôn ngữ chính', + 'agentSnapshot.field.slmModelId': 'Mô hình ngôn ngữ nhỏ', + 'agentSnapshot.field.vllmModelId': 'Mô hình thị giác', + 'agentSnapshot.field.ttsModelId': 'Văn bản thành giọng nói', + 'agentSnapshot.field.ttsVoiceId': 'Giọng nói', + 'agentSnapshot.field.ttsLanguage': 'Ngôn ngữ', + 'agentSnapshot.field.ttsVolume': 'Âm lượng', + 'agentSnapshot.field.ttsRate': 'Tốc độ', + 'agentSnapshot.field.ttsPitch': 'Cao độ', + 'agentSnapshot.field.memModelId': 'Mô hình bộ nhớ', + 'agentSnapshot.field.intentModelId': 'Nhận dạng ý định', + 'agentSnapshot.field.chatHistoryConf': 'Lịch sử trò chuyện', + 'agentSnapshot.field.systemPrompt': 'Giới thiệu', + 'agentSnapshot.field.summaryMemory': 'Bộ nhớ', + 'agentSnapshot.field.langCode': 'Mã ngôn ngữ', + 'agentSnapshot.field.language': 'Ngôn ngữ tương tác', + 'agentSnapshot.field.sort': 'Sắp xếp', + 'agentSnapshot.field.functions': 'Chức năng', + 'agentSnapshot.field.contextProviders': 'Nguồn ngữ cảnh', + 'agentSnapshot.field.correctWordFileIds': 'Từ thay thế', + 'agentSnapshot.field.tagNames': 'Nhãn', + 'agentSnapshot.field.tagIds': 'ID nhãn', + 'agentSnapshot.function.added': 'Đã bật', + 'agentSnapshot.function.removed': 'Đã tắt', + 'agentSnapshot.function.updated': 'Tham số đã thay đổi', + 'agentSnapshot.function.enabled': 'Đã bật', + 'agentSnapshot.function.disabled': 'Đã tắt', + 'agentSnapshot.function.disabledNote': 'Chức năng này đang tắt', + 'agentSnapshot.function.noParams': 'Không cần cấu hình tham số', + 'agentSnapshot.chatHistoryConf.none': 'Không ghi lịch sử trò chuyện', + 'agentSnapshot.chatHistoryConf.text': 'Báo cáo văn bản', + 'agentSnapshot.chatHistoryConf.textVoice': 'Báo cáo văn bản và giọng nói', + 'agentSnapshot.plugin.SYSTEM_PLUGIN_WEATHER': 'Thời tiết', + 'agentSnapshot.plugin.SYSTEM_PLUGIN_MUSIC': 'Trình phát nhạc máy chủ', + 'agentSnapshot.plugin.SYSTEM_PLUGIN_NEWS_CHINANEWS': 'Tin tức China News', + 'agentSnapshot.plugin.SYSTEM_PLUGIN_NEWS_NEWSNOW': 'Tổng hợp NewsNow', + 'agentSnapshot.plugin.SYSTEM_PLUGIN_HA_GET_STATE': 'Truy vấn trạng thái HomeAssistant', + 'agentSnapshot.plugin.SYSTEM_PLUGIN_HA_SET_STATE': 'Cập nhật trạng thái HomeAssistant', + 'agentSnapshot.plugin.SYSTEM_PLUGIN_HA_PLAY_MUSIC': 'Trình phát nhạc HomeAssistant', + 'agentSnapshot.plugin.SYSTEM_PLUGIN_WEB_SEARCH': 'Tìm kiếm web', + 'agentSnapshot.plugin.SYSTEM_PLUGIN_CALL_DEVICE': 'Gọi thiết bị', + 'agentSnapshot.pluginField.url': 'URL điểm cuối', + 'agentSnapshot.pluginField.news_sources': 'Nguồn tin', + 'agentSnapshot.pluginField.default_rss_url': 'URL RSS mặc định', + 'agentSnapshot.pluginField.society_rss_url': 'URL RSS xã hội', + 'agentSnapshot.pluginField.world_rss_url': 'URL RSS thế giới', + 'agentSnapshot.pluginField.finance_rss_url': 'URL RSS tài chính', + 'agentSnapshot.pluginField.api_key': 'Khóa API', + 'agentSnapshot.pluginField.default_location': 'Thành phố mặc định', + 'agentSnapshot.pluginField.api_host': 'Máy chủ API nhà phát triển', + 'agentSnapshot.pluginField.base_url': 'URL máy chủ', + 'agentSnapshot.pluginField.devices': 'Thiết bị', + 'agentSnapshot.pluginField.provider': 'Nhà cung cấp tìm kiếm', + 'agentSnapshot.pluginField.description': 'Mô tả công cụ', + 'agentSnapshot.pluginField.max_results': 'Số lượng kết quả', + 'agentSnapshot.model.Memory_nomem': 'Không có bộ nhớ', + 'agentSnapshot.model.Memory_mem_local_short': 'Bộ nhớ ngắn cục bộ', + 'agentSnapshot.model.Memory_mem0ai': 'Bộ nhớ Mem0AI', + 'agentSnapshot.model.Memory_mem_report_only': 'Chỉ báo cáo bộ nhớ', + 'agentSnapshot.model.Intent_nointent': 'Không nhận dạng ý định', + 'agentSnapshot.model.Intent_intent_llm': 'Nhận dạng ý định bằng LLM bên ngoài', + 'agentSnapshot.model.Intent_function_call': 'LLM gọi hàm', + 'agentSnapshot.voice.TTS_EdgeTTS0001': 'EdgeTTS nữ - Xiaoxiao', + 'agentSnapshot.voice.TTS_EdgeTTS0002': 'EdgeTTS nam - Yunyang', + 'agentSnapshot.voice.TTS_EdgeTTS0003': 'EdgeTTS nữ - Xiaoyi', + 'agentSnapshot.voice.TTS_EdgeTTS0004': 'EdgeTTS nam - Yunjian', + 'agentSnapshot.voice.TTS_EdgeTTS0005': 'EdgeTTS nam - Yunxi', + 'agentSnapshot.voice.TTS_EdgeTTS0006': 'EdgeTTS nam - Yunxia', 'roleConfig.vad': 'Phát hiện giọng nói', 'roleConfig.asr': 'Nhận dạng giọng nói', 'roleConfig.llm': 'Mô hình ngôn ngữ chính', @@ -1554,4 +1668,4 @@ export default { // Header navigation 'header.addressBook': 'Danh bạ', -} \ No newline at end of file +} diff --git a/main/manager-web/src/i18n/zh_CN.js b/main/manager-web/src/i18n/zh_CN.js index 71c28d3e..285db53c 100644 --- a/main/manager-web/src/i18n/zh_CN.js +++ b/main/manager-web/src/i18n/zh_CN.js @@ -807,6 +807,8 @@ export default { 'roleConfig.restartNotice': '保存配置后,需要重启设备,新的配置才会生效。', 'roleConfig.saveConfig': '保存配置', 'roleConfig.snapshotHistory': '历史版本', + 'roleConfig.currentVersion': '当前版本 {version}', + 'roleConfig.functionName': '功能名称', 'roleConfig.reset': '重置', 'roleConfig.agentName': '助手昵称', 'roleConfig.roleTemplate': '角色模版', @@ -816,7 +818,7 @@ export default { 'roleConfig.vad': '语音活动检测(VAD)', 'roleConfig.asr': '语音识别(ASR)', 'roleConfig.llm': '主语言模型(LLM)', - "roleConfig.slm": "小参数模型(SLM)", + 'roleConfig.slm': '小参数模型(SLM)', 'roleConfig.vllm': '视觉大模型(VLLM)', 'roleConfig.intent': '意图识别(Intent)', 'roleConfig.memoryHis': '记忆', @@ -873,6 +875,7 @@ export default { 'agentSnapshot.actions': '操作', 'agentSnapshot.view': '查看', 'agentSnapshot.restore': '恢复', + 'agentSnapshot.delete': '删除', 'agentSnapshot.detailTitle': '变更详情', 'agentSnapshot.restorePreviewTitle': '恢复确认', 'agentSnapshot.confirmRestore': '确认恢复', @@ -880,16 +883,28 @@ export default { 'agentSnapshot.after': '变化后', 'agentSnapshot.emptyValue': '无', 'agentSnapshot.noChangedContent': '暂无可展示的变更内容', - 'agentSnapshot.restoreConfirm': '确定恢复到版本 #{version} 吗?当前配置会先自动保存为新的历史版本。', + 'agentSnapshot.noFunctionChange': '功能配置无变化', + 'agentSnapshot.beforeChange': '变化前', + 'agentSnapshot.afterChange': '变化后', + 'agentSnapshot.beforeRestore': '恢复前', + 'agentSnapshot.afterRestore': '恢复后', + 'agentSnapshot.restoreMemoryWarning': '恢复到无记忆版本会清空该智能体的聊天记录,请确认后再继续。', + 'agentSnapshot.restoreConfirm': '确定恢复到版本 {version} 吗?当前配置会先自动保存为新的历史版本。', 'agentSnapshot.restoreSuccess': '已恢复历史版本', 'agentSnapshot.restoreFailed': '恢复历史版本失败', + 'agentSnapshot.restoreFailedRollback': '恢复历史版本失败,事务已回滚,当前配置未改变', + 'agentSnapshot.deleteConfirm': '确定删除版本 {version} 吗?删除后不可恢复。', + 'agentSnapshot.deleteSuccess': '已删除历史版本', + 'agentSnapshot.deleteFailed': '删除历史版本失败', 'agentSnapshot.fetchFailed': '获取历史版本失败', 'agentSnapshot.detailFailed': '获取快照详情失败', 'agentSnapshot.currentVersion': '当前版本', 'agentSnapshot.source.config': '配置保存', 'agentSnapshot.source.current': '当前配置', 'agentSnapshot.source.restore': '恢复前', + 'agentSnapshot.source.initial': '初始版本', 'agentSnapshot.field.restore': '恢复操作', + 'agentSnapshot.field.initial': '初始快照', 'agentSnapshot.field.agentCode': '助手编码', 'agentSnapshot.field.agentName': '助手昵称', 'agentSnapshot.field.asrModelId': '语音识别', @@ -916,6 +931,52 @@ export default { 'agentSnapshot.field.correctWordFileIds': '替换词', 'agentSnapshot.field.tagNames': '标签', 'agentSnapshot.field.tagIds': '标签ID', + 'agentSnapshot.function.added': '已开启', + 'agentSnapshot.function.removed': '已关闭', + 'agentSnapshot.function.updated': '参数变更', + 'agentSnapshot.function.enabled': '已开启', + 'agentSnapshot.function.disabled': '未开启', + 'agentSnapshot.function.disabledNote': '未开启此功能', + 'agentSnapshot.function.noParams': '无需配置参数', + 'agentSnapshot.chatHistoryConf.none': '不记录聊天记录', + 'agentSnapshot.chatHistoryConf.text': '上报文字', + 'agentSnapshot.chatHistoryConf.textVoice': '上报文字+语音', + 'agentSnapshot.plugin.SYSTEM_PLUGIN_WEATHER': '天气查询', + 'agentSnapshot.plugin.SYSTEM_PLUGIN_MUSIC': '服务器音乐播放', + 'agentSnapshot.plugin.SYSTEM_PLUGIN_NEWS_CHINANEWS': '中新网新闻', + 'agentSnapshot.plugin.SYSTEM_PLUGIN_NEWS_NEWSNOW': 'newsnow新闻聚合', + 'agentSnapshot.plugin.SYSTEM_PLUGIN_HA_GET_STATE': 'HomeAssistant设备状态查询', + 'agentSnapshot.plugin.SYSTEM_PLUGIN_HA_SET_STATE': 'HomeAssistant设备状态修改', + 'agentSnapshot.plugin.SYSTEM_PLUGIN_HA_PLAY_MUSIC': 'HomeAssistant音乐播放', + 'agentSnapshot.plugin.SYSTEM_PLUGIN_WEB_SEARCH': '联网搜索', + 'agentSnapshot.plugin.SYSTEM_PLUGIN_CALL_DEVICE': '设备呼叫设备', + 'agentSnapshot.pluginField.url': '接口地址', + 'agentSnapshot.pluginField.news_sources': '新闻源配置', + 'agentSnapshot.pluginField.default_rss_url': '默认 RSS 源', + 'agentSnapshot.pluginField.society_rss_url': '社会新闻 RSS 地址', + 'agentSnapshot.pluginField.world_rss_url': '国际新闻 RSS 地址', + 'agentSnapshot.pluginField.finance_rss_url': '财经新闻 RSS 地址', + 'agentSnapshot.pluginField.api_key': 'API 密钥', + 'agentSnapshot.pluginField.default_location': '默认查询城市', + 'agentSnapshot.pluginField.api_host': '开发者 API Host', + 'agentSnapshot.pluginField.base_url': '服务器地址', + 'agentSnapshot.pluginField.devices': '设备列表', + 'agentSnapshot.pluginField.provider': '搜索源', + 'agentSnapshot.pluginField.description': '工具描述', + 'agentSnapshot.pluginField.max_results': '返回数量', + 'agentSnapshot.model.Memory_nomem': '无记忆', + 'agentSnapshot.model.Memory_mem_local_short': '本地短记忆', + 'agentSnapshot.model.Memory_mem0ai': 'Mem0AI记忆', + 'agentSnapshot.model.Memory_mem_report_only': '仅上报记忆', + 'agentSnapshot.model.Intent_nointent': '无意图识别', + 'agentSnapshot.model.Intent_intent_llm': '外挂的大模型意图识别', + 'agentSnapshot.model.Intent_function_call': '大模型自主函数调用', + 'agentSnapshot.voice.TTS_EdgeTTS0001': 'EdgeTTS女声-晓晓', + 'agentSnapshot.voice.TTS_EdgeTTS0002': 'EdgeTTS男声-云扬', + 'agentSnapshot.voice.TTS_EdgeTTS0003': 'EdgeTTS女声-晓伊', + 'agentSnapshot.voice.TTS_EdgeTTS0004': 'EdgeTTS男声-云健', + 'agentSnapshot.voice.TTS_EdgeTTS0005': 'EdgeTTS男声-云希', + 'agentSnapshot.voice.TTS_EdgeTTS0006': 'EdgeTTS男声-云夏', // 表单字段 Tooltip 提示说明 'roleConfig.tooltip.agentName': '设置智能体的名称,用于标识和识别您的AI助手', @@ -928,7 +989,7 @@ export default { 'roleConfig.tooltip.vad': '语音活动检测(Voice Activity Detection):检测用户何时开始或结束说话,用于判断对话的开始和结束,实现打断功能', 'roleConfig.tooltip.asr': '自动语音识别(Automatic Speech Recognition):将用户的语音转换为文字,是人机对话的第一步,支持多语言识别', 'roleConfig.tooltip.llm': '主语言模型(Large Language Model):AI助手的"大脑",负责理解用户意图、生成回答和执行各种任务', - "roleConfig.tooltip.slm": '小参数模型(Small Language Model):用于智能体唤醒,生成记忆总结标题', + 'roleConfig.tooltip.slm': '小参数模型(Small Language Model):用于智能体唤醒,生成记忆总结标题', 'roleConfig.tooltip.vllm': '视觉大语言模型(Visual LLM):处理图像和视频理解,使AI助手能够分析和描述摄像头捕获的画面内容', 'roleConfig.tooltip.intent': '意图识别(Intent Detection):分析用户语音或文本,判断用户的真实意图,如查询、聊天、控制设备等', 'roleConfig.tooltip.memory': '记忆模型(Memory Model):管理对话历史的存储和摘要,决定AI能否记住之前的对话内容,实现长期记忆功能', diff --git a/main/manager-web/src/i18n/zh_TW.js b/main/manager-web/src/i18n/zh_TW.js index cc89ba2f..56b41f86 100644 --- a/main/manager-web/src/i18n/zh_TW.js +++ b/main/manager-web/src/i18n/zh_TW.js @@ -806,12 +806,126 @@ export default { 'roleConfig.addTag': '添加新標籤', 'roleConfig.restartNotice': '保存配置後,需要重啟設備,新的配置才會生效。', 'roleConfig.saveConfig': '保存配置', + 'roleConfig.snapshotHistory': '歷史版本', + 'roleConfig.currentVersion': '目前版本 {version}', + 'roleConfig.functionName': '功能名稱', 'roleConfig.reset': '重置', 'roleConfig.agentName': '助手暱稱', 'roleConfig.roleTemplate': '角色模版', 'roleConfig.roleIntroduction': '角色介紹', 'roleConfig.languageCode': '語言編碼', 'roleConfig.interactionLanguage': '交互語種', + 'agentSnapshot.title': '歷史版本', + 'agentSnapshot.empty': '暫無歷史版本', + 'agentSnapshot.version': '版本', + 'agentSnapshot.createdAt': '保存時間', + 'agentSnapshot.source': '來源', + 'agentSnapshot.changedFields': '變更內容', + 'agentSnapshot.actions': '操作', + 'agentSnapshot.view': '查看', + 'agentSnapshot.restore': '恢復', + 'agentSnapshot.delete': '刪除', + 'agentSnapshot.detailTitle': '變更詳情', + 'agentSnapshot.restorePreviewTitle': '恢復確認', + 'agentSnapshot.confirmRestore': '確認恢復', + 'agentSnapshot.before': '之前', + 'agentSnapshot.after': '之後', + 'agentSnapshot.emptyValue': '無', + 'agentSnapshot.noChangedContent': '暫無可展示的變更內容', + 'agentSnapshot.noFunctionChange': '功能配置無變化', + 'agentSnapshot.beforeChange': '變化前', + 'agentSnapshot.afterChange': '變化後', + 'agentSnapshot.beforeRestore': '恢復前', + 'agentSnapshot.afterRestore': '恢復後', + 'agentSnapshot.restoreMemoryWarning': '恢復到無記憶版本會清空該智能體的聊天記錄,請確認後再繼續。', + 'agentSnapshot.restoreConfirm': '確定恢復到版本 {version} 嗎?目前配置會先自動保存為新的歷史版本。', + 'agentSnapshot.restoreSuccess': '已恢復歷史版本', + 'agentSnapshot.restoreFailed': '恢復歷史版本失敗', + 'agentSnapshot.restoreFailedRollback': '恢復歷史版本失敗,交易已回滾,目前配置未改變', + 'agentSnapshot.deleteConfirm': '確定刪除版本 {version} 嗎?刪除後無法復原。', + 'agentSnapshot.deleteSuccess': '已刪除歷史版本', + 'agentSnapshot.deleteFailed': '刪除歷史版本失敗', + 'agentSnapshot.fetchFailed': '獲取歷史版本失敗', + 'agentSnapshot.detailFailed': '獲取快照詳情失敗', + 'agentSnapshot.currentVersion': '目前版本', + 'agentSnapshot.source.config': '配置保存', + 'agentSnapshot.source.current': '目前配置', + 'agentSnapshot.source.restore': '恢復前', + 'agentSnapshot.source.initial': '初始版本', + 'agentSnapshot.field.restore': '恢復操作', + 'agentSnapshot.field.initial': '初始快照', + 'agentSnapshot.field.agentCode': '助手編碼', + 'agentSnapshot.field.agentName': '助手暱稱', + 'agentSnapshot.field.asrModelId': '語音識別', + 'agentSnapshot.field.vadModelId': '語音活動檢測', + 'agentSnapshot.field.llmModelId': '主語言模型', + 'agentSnapshot.field.slmModelId': '小參數模型', + 'agentSnapshot.field.vllmModelId': '視覺大模型', + 'agentSnapshot.field.ttsModelId': '語音合成', + 'agentSnapshot.field.ttsVoiceId': '聲音音色', + 'agentSnapshot.field.ttsLanguage': '對話語言', + 'agentSnapshot.field.ttsVolume': '音量', + 'agentSnapshot.field.ttsRate': '語速', + 'agentSnapshot.field.ttsPitch': '音調', + 'agentSnapshot.field.memModelId': '記憶模式', + 'agentSnapshot.field.intentModelId': '意圖識別', + 'agentSnapshot.field.chatHistoryConf': '聊天記錄配置', + 'agentSnapshot.field.systemPrompt': '角色介紹', + 'agentSnapshot.field.summaryMemory': '記憶', + 'agentSnapshot.field.langCode': '語言編碼', + 'agentSnapshot.field.language': '交互語種', + 'agentSnapshot.field.sort': '排序', + 'agentSnapshot.field.functions': '功能插件', + 'agentSnapshot.field.contextProviders': '上下文源', + 'agentSnapshot.field.correctWordFileIds': '替換詞', + 'agentSnapshot.field.tagNames': '標籤', + 'agentSnapshot.field.tagIds': '標籤ID', + 'agentSnapshot.function.added': '已開啟', + 'agentSnapshot.function.removed': '已關閉', + 'agentSnapshot.function.updated': '參數變更', + 'agentSnapshot.function.enabled': '已開啟', + 'agentSnapshot.function.disabled': '未開啟', + 'agentSnapshot.function.disabledNote': '未開啟此功能', + 'agentSnapshot.function.noParams': '無需配置參數', + 'agentSnapshot.chatHistoryConf.none': '不記錄聊天記錄', + 'agentSnapshot.chatHistoryConf.text': '上報文字', + 'agentSnapshot.chatHistoryConf.textVoice': '上報文字+語音', + 'agentSnapshot.plugin.SYSTEM_PLUGIN_WEATHER': '天氣查詢', + 'agentSnapshot.plugin.SYSTEM_PLUGIN_MUSIC': '伺服器音樂播放', + 'agentSnapshot.plugin.SYSTEM_PLUGIN_NEWS_CHINANEWS': '中新網新聞', + 'agentSnapshot.plugin.SYSTEM_PLUGIN_NEWS_NEWSNOW': 'newsnow新聞聚合', + 'agentSnapshot.plugin.SYSTEM_PLUGIN_HA_GET_STATE': 'HomeAssistant設備狀態查詢', + 'agentSnapshot.plugin.SYSTEM_PLUGIN_HA_SET_STATE': 'HomeAssistant設備狀態修改', + 'agentSnapshot.plugin.SYSTEM_PLUGIN_HA_PLAY_MUSIC': 'HomeAssistant音樂播放', + 'agentSnapshot.plugin.SYSTEM_PLUGIN_WEB_SEARCH': '聯網搜尋', + 'agentSnapshot.plugin.SYSTEM_PLUGIN_CALL_DEVICE': '設備呼叫設備', + 'agentSnapshot.pluginField.url': '接口地址', + 'agentSnapshot.pluginField.news_sources': '新聞源配置', + 'agentSnapshot.pluginField.default_rss_url': '預設 RSS 源', + 'agentSnapshot.pluginField.society_rss_url': '社會新聞 RSS 地址', + 'agentSnapshot.pluginField.world_rss_url': '國際新聞 RSS 地址', + 'agentSnapshot.pluginField.finance_rss_url': '財經新聞 RSS 地址', + 'agentSnapshot.pluginField.api_key': 'API 密鑰', + 'agentSnapshot.pluginField.default_location': '預設查詢城市', + 'agentSnapshot.pluginField.api_host': '開發者 API Host', + 'agentSnapshot.pluginField.base_url': '伺服器地址', + 'agentSnapshot.pluginField.devices': '設備列表', + 'agentSnapshot.pluginField.provider': '搜尋源', + 'agentSnapshot.pluginField.description': '工具描述', + 'agentSnapshot.pluginField.max_results': '返回數量', + 'agentSnapshot.model.Memory_nomem': '無記憶', + 'agentSnapshot.model.Memory_mem_local_short': '本地短記憶', + 'agentSnapshot.model.Memory_mem0ai': 'Mem0AI記憶', + 'agentSnapshot.model.Memory_mem_report_only': '僅上報記憶', + 'agentSnapshot.model.Intent_nointent': '無意圖識別', + 'agentSnapshot.model.Intent_intent_llm': '外掛的大模型意圖識別', + 'agentSnapshot.model.Intent_function_call': '大模型自主函式呼叫', + 'agentSnapshot.voice.TTS_EdgeTTS0001': 'EdgeTTS女聲-曉曉', + 'agentSnapshot.voice.TTS_EdgeTTS0002': 'EdgeTTS男聲-雲揚', + 'agentSnapshot.voice.TTS_EdgeTTS0003': 'EdgeTTS女聲-曉伊', + 'agentSnapshot.voice.TTS_EdgeTTS0004': 'EdgeTTS男聲-雲健', + 'agentSnapshot.voice.TTS_EdgeTTS0005': 'EdgeTTS男聲-雲希', + 'agentSnapshot.voice.TTS_EdgeTTS0006': 'EdgeTTS男聲-雲夏', 'roleConfig.vad': '語音活動檢測(VAD)', 'roleConfig.asr': '語音識別(ASR)', 'roleConfig.llm': '主語言模型(LLM)', @@ -1553,4 +1667,4 @@ export default { 'addressBookManagement.monthsAgo': '{months}個月前', 'addressBookManagement.yearsAgo': '{years}年前', -} \ No newline at end of file +} diff --git a/main/manager-web/src/views/roleConfig.vue b/main/manager-web/src/views/roleConfig.vue index a0075317..d6dcf4bb 100644 --- a/main/manager-web/src/views/roleConfig.vue +++ b/main/manager-web/src/views/roleConfig.vue @@ -17,7 +17,7 @@
    {{ form.agentName }} - 当前版本 #{{ currentVersionNo }} + {{ $t("roleConfig.currentVersion", { version: currentVersionNo }) }}
    @@ -319,7 +319,7 @@ placement="top" >
    -
    功能名称: {{ func.name }}
    +
    {{ $t("roleConfig.functionName") }}: {{ func.name }}
    {{ getFunctionDisplayChar(func.name) }} @@ -562,6 +562,7 @@ export default { asr: false, // 语音识别功能状态 }, dynamicTags: [], + originalTagNames: [], inputVisible: false, inputValue: '', checkedReplacementWordIds: [] @@ -618,8 +619,12 @@ export default { }), contextProviders: this.currentContextProviders, correctWordFileIds: this.checkedReplacementWordIds, - tagNames: this.dynamicTags.map(tag => tag.tagName), }; + const tagNames = this.dynamicTags.map(tag => tag.tagName); + const tagsChanged = !this.isSameStringList(tagNames, this.originalTagNames); + if (tagsChanged) { + configData.tagNames = tagNames; + } // 只在用户设置了TTS参数时才传递(不为null/undefined) if (this.form.ttsVolume !== null && this.form.ttsVolume !== undefined) { @@ -631,13 +636,20 @@ export default { if (this.form.ttsPitch !== null && this.form.ttsPitch !== undefined) { configData.ttsPitch = this.form.ttsPitch; } - Api.agent.updateAgentConfig(this.$route.query.agentId, configData, ({ data }) => { + const agentId = this.$route.query.agentId; + Api.agent.updateAgentConfig(agentId, configData, ({ data }) => { if (data.code === 0) { - this.$message.success({ - message: i18n.t("roleConfig.saveSuccess"), - showClose: true, - }); - this.fetchCurrentVersion(this.$route.query.agentId); + const afterSave = () => { + if (tagsChanged) { + this.originalTagNames = [...tagNames]; + } + this.$message.success({ + message: i18n.t("roleConfig.saveSuccess"), + showClose: true, + }); + this.fetchCurrentVersion(agentId); + }; + afterSave(); } else { this.$message.error({ message: data.msg || i18n.t("roleConfig.saveFailed"), @@ -661,17 +673,11 @@ export default { return; } - Api.agent.getAgentSnapshots( - agentId, - { page: "1", limit: "1" }, - ({ data }) => { - if (data.code === 0) { - const latest = data.data?.list?.[0]; - const latestVersionNo = Number(latest?.versionNo) || 0; - this.currentVersionNo = latestVersionNo + 1; - } + Api.agent.getDeviceConfig(agentId, ({ data }) => { + if (data.code === 0) { + this.currentVersionNo = data.data?.currentVersionNo || null; } - ); + }); }, resetConfig() { this.$confirm(i18n.t("roleConfig.confirmReset"), i18n.t("message.info"), { @@ -862,7 +868,7 @@ export default { }); this.$set(this.modelOptions, model.type, LLMdata); } else { - this.$message.error(data.msg || "获取LLM模型列表失败"); + this.$message.error(data.msg || i18n.t("roleConfig.fetchModelsFailed")); } }); } @@ -1385,7 +1391,7 @@ export default { handleInputConfirm() { let inputValue = this.inputValue; if (inputValue) { - const tag = { id: new Date().getTime(), tagName: inputValue }; + const tag = { id: `tmp-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`, tagName: inputValue }; this.dynamicTags.push(tag); } this.inputVisible = false; @@ -1395,14 +1401,21 @@ export default { Api.agent.getAgentTags(agentId, ({ data }) => { if (data.code === 0) { this.dynamicTags = data.data || []; + this.originalTagNames = this.dynamicTags.map(tag => tag.tagName); } }); }, - handleSaveAgentTags(agentId) { + isSameStringList(left, right) { + if (!Array.isArray(left) || !Array.isArray(right) || left.length !== right.length) { + return false; + } + return left.every((value, index) => value === right[index]); + }, + handleSaveAgentTags(agentId, tagNames = this.dynamicTags.map(tag => tag.tagName)) { return new Promise((resolve, reject) => { - const tagNames = this.dynamicTags.map(tag => tag.tagName); Api.agent.saveAgentTags(agentId, { tagNames }, ({ data }) => { if (data.code === 0) { + this.originalTagNames = [...tagNames]; resolve(); } else { reject(data.msg); diff --git a/main/xiaozhi-server/config/assets/wakeup_words/ed76d459636c2481aec828516c1b4f54.wav b/main/xiaozhi-server/config/assets/wakeup_words/ed76d459636c2481aec828516c1b4f54.wav index 1e7246be486ff639b29d24241404173e56c9beab..0dd48cb09985cd0c75ab71f1df3b5c6619882fbd 100644 GIT binary patch literal 123884 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
    G26!9U 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 literal 228524 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

    m+q9%(8o7c0CLk@GgQ%e-~!n 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ΝT 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 Y8-Jnfz0lXaHvU52hoL-z|119f3$Ilx&j0`b diff --git a/main/xiaozhi-server/config/manage_api_client.py b/main/xiaozhi-server/config/manage_api_client.py index 7cc4c361..8eb2da20 100644 --- a/main/xiaozhi-server/config/manage_api_client.py +++ b/main/xiaozhi-server/config/manage_api_client.py @@ -73,6 +73,7 @@ class ManageApiClient: }, timeout=cls.config.get("timeout", 30), limits=limits, # 使用限制 + trust_env=False, ) return cls._async_clients[loop_id] except RuntimeError: diff --git a/main/xiaozhi-server/core/providers/asr/fun_local.py b/main/xiaozhi-server/core/providers/asr/fun_local.py index fa428710..ef11ae02 100644 --- a/main/xiaozhi-server/core/providers/asr/fun_local.py +++ b/main/xiaozhi-server/core/providers/asr/fun_local.py @@ -43,9 +43,13 @@ class ASRProvider(ASRProviderBase): # 内存检测,要求大于2G min_mem_bytes = 2 * 1024 * 1024 * 1024 - total_mem = psutil.virtual_memory().total - if total_mem < min_mem_bytes: - logger.bind(tag=TAG).error(f"可用内存不足2G,当前仅有 {total_mem / (1024*1024):.2f} MB,可能无法启动FunASR") + try: + total_mem = psutil.virtual_memory().total + except RuntimeError as e: + logger.bind(tag=TAG).warning(f"获取系统内存信息失败,跳过FunASR内存检测: {e}") + else: + if total_mem < min_mem_bytes: + logger.bind(tag=TAG).error(f"可用内存不足2G,当前仅有 {total_mem / (1024*1024):.2f} MB,可能无法启动FunASR") self.interface_type = InterfaceType.LOCAL self.model_dir = config.get("model_dir")