You need to sign in before continuing.

Commit 38cc822b35c666ea38d7b0c780706318f05c47db

Authored by qianbao
1 parent e7d66b07

添加未清选择 改成动态引导语

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 = {
... ...