Commit 38cc822b35c666ea38d7b0c780706318f05c47db
1 parent
e7d66b07
添加未清选择 改成动态引导语
Showing
4 changed files
with
39 additions
and
6 deletions
src/main/java/com/xly/entity/UserSceneSession.java
| ... | ... | @@ -6,6 +6,7 @@ import lombok.Data; |
| 6 | 6 | |
| 7 | 7 | import java.util.List; |
| 8 | 8 | import java.util.Map; |
| 9 | +import java.util.concurrent.atomic.AtomicBoolean; | |
| 9 | 10 | import java.util.concurrent.atomic.AtomicInteger; |
| 10 | 11 | import java.util.stream.Collectors; |
| 11 | 12 | |
| ... | ... | @@ -101,6 +102,15 @@ public class UserSceneSession { |
| 101 | 102 | **/ |
| 102 | 103 | private String sCopyToSrcId; |
| 103 | 104 | |
| 105 | + /*** | |
| 106 | + * @Author 钱豹 | |
| 107 | + * @Date 10:03 2026/4/24 | |
| 108 | + * @Param | |
| 109 | + * @return | |
| 110 | + * @Description 工具是否已执行 | |
| 111 | + **/ | |
| 112 | + private Boolean toolExecuted=false; | |
| 113 | + | |
| 104 | 114 | /** |
| 105 | 115 | * 构建场景选择提示语:展示权限内场景,引导用户选择 |
| 106 | 116 | * @return 自然语言提示语 |
| ... | ... | @@ -181,5 +191,4 @@ public class UserSceneSession { |
| 181 | 191 | return false; |
| 182 | 192 | } |
| 183 | 193 | |
| 184 | - | |
| 185 | 194 | } |
| 186 | 195 | \ No newline at end of file | ... | ... |
src/main/java/com/xly/tool/DynamicToolProvider.java
| ... | ... | @@ -198,6 +198,11 @@ public class DynamicToolProvider implements ToolProvider { |
| 198 | 198 | Map<ToolSpecification, ToolExecutor> executors = new HashMap<>(); |
| 199 | 199 | // 获取Session |
| 200 | 200 | UserSceneSession session = UserSceneSessionService.USER_SCENE_SESSION_CACHE.get(sUserId); |
| 201 | + // 工具已执行,不再提供任何工具 | |
| 202 | + if (session != null && session.getToolExecuted()) { | |
| 203 | + log.info("工具已执行完成,清空可用工具列表"); | |
| 204 | + return ToolProviderResult.builder().build(); | |
| 205 | + } | |
| 201 | 206 | |
| 202 | 207 | // 过滤对应的权限方法 |
| 203 | 208 | List<ToolSpecificationHolder> datalist = new ArrayList<>(); |
| ... | ... | @@ -255,9 +260,9 @@ public class DynamicToolProvider implements ToolProvider { |
| 255 | 260 | // ====================== 【超级强制:必须调用工具】 ====================== |
| 256 | 261 | String forceToolPrompt = """ |
| 257 | 262 | 【重要·强制指令】 |
| 258 | - 1. 这是当前唯一可用工具,必须调用,禁止直接回答 | |
| 259 | - 2. 用户输入包含:确认、全部确认、合并确认、行号(第1行/第一行等) | |
| 260 | - 3. 必须调用本工具,必须调用,必须调用! | |
| 263 | + 1. 这是当前唯一可用工具,必须调用,禁止直接回答 | |
| 264 | + 2. 用户输入包含:确认、全部确认、合并确认、行号(第1行/第一行等) | |
| 265 | + 3. 必须调用本工具,必须调用,并且只调用一次,不要重复调用! | |
| 261 | 266 | """; |
| 262 | 267 | stoolDesc.append(forceToolPrompt); |
| 263 | 268 | // ======================================================================== |
| ... | ... | @@ -530,7 +535,13 @@ public class DynamicToolProvider implements ToolProvider { |
| 530 | 535 | |
| 531 | 536 | UserSceneSession session = UserSceneSessionService.USER_SCENE_SESSION_CACHE.get(memoryId.toString()); |
| 532 | 537 | session.setCurrentTool(meta); // 标记当前工具 |
| 533 | - | |
| 538 | + // 防止重复执行 | |
| 539 | + if (session.getToolExecuted()) { | |
| 540 | + log.warn("工具已执行过,拒绝重复调用: {}", meta.getSMethodNo()); | |
| 541 | + return String.valueOf(successResult(toolExecutionRequest, "{\"status\":\"already_executed\"}")); | |
| 542 | + } | |
| 543 | + //标记执行了(所有工具方法只执行一次) | |
| 544 | + session.setToolExecuted(true); | |
| 534 | 545 | // 1. 解析参数 |
| 535 | 546 | Map<String, Object> argsNew; |
| 536 | 547 | try { |
| ... | ... | @@ -1096,6 +1107,8 @@ public class DynamicToolProvider implements ToolProvider { |
| 1096 | 1107 | sBody.put("pageSize",10000); |
| 1097 | 1108 | log.info("doGetFromData========================"); |
| 1098 | 1109 | List<Map<String,Object>> list = new ArrayList<>(); |
| 1110 | + //移除确认标识 | |
| 1111 | + args.remove("operateType"); | |
| 1099 | 1112 | if(ObjectUtil.isNotEmpty(args)){ |
| 1100 | 1113 | List<ParamRule> paramDefs = meta.getParamRuleList(); |
| 1101 | 1114 | args.forEach((k,v)->{ | ... | ... |
src/main/java/com/xly/tts/service/PythonTtsProxyService.java
| ... | ... | @@ -6,6 +6,7 @@ import com.xly.constant.BusinessCode; |
| 6 | 6 | import com.xly.constant.ReturnTypeCode; |
| 7 | 7 | import com.xly.entity.AiResponseAccumulator; |
| 8 | 8 | import com.xly.entity.AiResponseDTO; |
| 9 | +import com.xly.entity.UserSceneSession; | |
| 9 | 10 | import com.xly.service.UserSceneSessionService; |
| 10 | 11 | import com.xly.service.XlyErpService; |
| 11 | 12 | import com.xly.tts.bean.*; |
| ... | ... | @@ -117,10 +118,20 @@ public class PythonTtsProxyService { |
| 117 | 118 | String sSubsidiaryId = request.getSubsidiaryid(); |
| 118 | 119 | String sUserType = request.getUsertype(); |
| 119 | 120 | String authorization = request.getAuthorization(); |
| 121 | + cleanupAfterExecution(sUserId); | |
| 120 | 122 | AiResponseDTO voiceText = xlyErpService.erpUserInput(userInput, sUserId, sUserName, sBrandsId, sSubsidiaryId, sUserType, authorization); |
| 121 | 123 | return synthesizeStreamAi(request, voiceText); |
| 122 | 124 | } |
| 123 | 125 | |
| 126 | + | |
| 127 | + // 4. 在 AI 回复后清理 session | |
| 128 | + public void cleanupAfterExecution(String memoryId) { | |
| 129 | + UserSceneSession session = UserSceneSessionService.USER_SCENE_SESSION_CACHE.get(memoryId); | |
| 130 | + if (session != null) { | |
| 131 | + session.setToolExecuted(false); // 重置状态 | |
| 132 | + } | |
| 133 | + } | |
| 134 | + | |
| 124 | 135 | /** |
| 125 | 136 | * 流式ERP + 流式TTS合成 |
| 126 | 137 | */ | ... | ... |
src/main/resources/templates/chat.html
| ... | ... | @@ -466,7 +466,7 @@ |
| 466 | 466 | let brandsid= "1111111111"; |
| 467 | 467 | let subsidiaryid= "1111111111"; |
| 468 | 468 | let usertype= "sysadmin"; |
| 469 | - let authorization="CE444885A9BCFDDE1FD793F8A0931301E9D7DE6CEDD9DE4B83ECE2219C7829A8F3419238942A93E9AD666629E18D159A8BB22EBE26EF12CD9A1EEDB89DC6FB3386549BD9F3EBBD954D17D31CED5EED2E9C9A98822AD3F0E3100F8DBBB5963377538155B7ADAEE71E899235DC1122F426"; | |
| 469 | + let authorization="CE444885A9BCFDDE1FD793F8A0931301E9D7DE6CEDD9DE4B83ECE2219C7829A8F3419238942A93E9AD666629E18D159A8BB22EBE26EF12CD9A1EEDB89DC6FB33178153C379FB82F53B4B689DA1BE7060687D4EF8281542FFC87C4EB776974C6A538155B7ADAEE71E899235DC1122F426"; | |
| 470 | 470 | let hrefLock = window.location.origin+"/xlyAi"; |
| 471 | 471 | |
| 472 | 472 | const CONFIG = { | ... | ... |