Commit ff5f5a198c776e7db6654be94c29fa4b0e003637

Authored by qianbao
1 parent 6f97d3bd

AI 对于时间的处理

src/main/java/com/xly/config/OperableChatMemoryProvider.java
1 package com.xly.config; 1 package com.xly.config;
2 2
3 -  
4 import dev.langchain4j.memory.ChatMemory; 3 import dev.langchain4j.memory.ChatMemory;
5 import dev.langchain4j.memory.chat.ChatMemoryProvider; 4 import dev.langchain4j.memory.chat.ChatMemoryProvider;
6 import dev.langchain4j.memory.chat.MessageWindowChatMemory; 5 import dev.langchain4j.memory.chat.MessageWindowChatMemory;
7 import dev.langchain4j.data.message.ChatMessage; 6 import dev.langchain4j.data.message.ChatMessage;
8 import org.springframework.stereotype.Component; 7 import org.springframework.stereotype.Component;
9 8
  9 +import java.util.ArrayList;
10 import java.util.List; 10 import java.util.List;
11 import java.util.Map; 11 import java.util.Map;
12 import java.util.Objects; 12 import java.util.Objects;
13 import java.util.concurrent.ConcurrentHashMap; 13 import java.util.concurrent.ConcurrentHashMap;
  14 +import java.util.stream.Collectors;
14 15
15 /** 16 /**
16 * 可操作的ChatMemoryProvider:获取消息对象+清除记忆(指定/全量)+删除单条消息 17 * 可操作的ChatMemoryProvider:获取消息对象+清除记忆(指定/全量)+删除单条消息
@@ -20,7 +21,7 @@ import java.util.concurrent.ConcurrentHashMap; @@ -20,7 +21,7 @@ import java.util.concurrent.ConcurrentHashMap;
20 public class OperableChatMemoryProvider implements ChatMemoryProvider { 21 public class OperableChatMemoryProvider implements ChatMemoryProvider {
21 // 核心缓存:memoryId -> ChatMemory,保证一个会话/用户对应唯一记忆实例 22 // 核心缓存:memoryId -> ChatMemory,保证一个会话/用户对应唯一记忆实例
22 private final Map<Object, ChatMemory> memoryCache = new ConcurrentHashMap<>(); 23 private final Map<Object, ChatMemory> memoryCache = new ConcurrentHashMap<>();
23 - // 记忆最大消息数,根据业务需求调整(原配置为10) 24 + // 记忆最大消息数,根据业务需求调整
24 private static final int MAX_MESSAGE_SIZE = 100; 25 private static final int MAX_MESSAGE_SIZE = 100;
25 26
26 /** 27 /**
@@ -35,56 +36,193 @@ public class OperableChatMemoryProvider implements ChatMemoryProvider { @@ -35,56 +36,193 @@ public class OperableChatMemoryProvider implements ChatMemoryProvider {
35 return memoryCache.computeIfAbsent(finalMemId, k -> MessageWindowChatMemory.withMaxMessages(MAX_MESSAGE_SIZE)); 36 return memoryCache.computeIfAbsent(finalMemId, k -> MessageWindowChatMemory.withMaxMessages(MAX_MESSAGE_SIZE));
36 } 37 }
37 38
38 - // ===================== 1. 获取消息对象(当前memoryId) ===================== 39 + // ===================== 1. 获取消息对象 =====================
  40 +
39 /** 41 /**
40 - * 获取当前会话/用户的全部消息列表(含用户消息、AI消息,按对话顺序) 42 + * 获取当前会话/用户的全部消息列表
41 */ 43 */
42 public List<ChatMessage> getCurrentChatMessages(Object memoryId) { 44 public List<ChatMessage> getCurrentChatMessages(Object memoryId) {
43 if (Objects.isNull(memoryId)) { 45 if (Objects.isNull(memoryId)) {
44 - return List.of(); 46 + return new ArrayList<>();
45 } 47 }
46 - // 从ChatMemory中获取原生消息列表  
47 - return this.get(memoryId).messages(); 48 + // 返回一个新的列表,避免直接操作内部列表
  49 + return new ArrayList<>(this.get(memoryId).messages());
48 } 50 }
49 51
50 - // ===================== 2. 清除记忆(核心需求) ===================== 52 + // ===================== 2. 清除记忆 =====================
  53 +
51 /** 54 /**
52 - * 清空【指定memoryId】的全部记忆(最常用,如前端「清空对话」) 55 + * 清空【指定memoryId】的全部记忆
53 */ 56 */
54 public void clearSpecifiedMemory(Object memoryId) { 57 public void clearSpecifiedMemory(Object memoryId) {
55 if (Objects.nonNull(memoryId)) { 58 if (Objects.nonNull(memoryId)) {
56 - // 调用ChatMemory原生clear(),清空该实例所有消息  
57 this.get(memoryId).clear(); 59 this.get(memoryId).clear();
58 } 60 }
59 } 61 }
60 62
61 /** 63 /**
62 - * 全量清除【所有memoryId】的记忆(系统级清理,如定时任务/后台操作) 64 + * 全量清除【所有memoryId】的记忆
63 */ 65 */
64 public void clearAllMemory() { 66 public void clearAllMemory() {
65 - // 遍历所有记忆实例,逐个调用原生clear()清空  
66 memoryCache.values().forEach(ChatMemory::clear); 67 memoryCache.values().forEach(ChatMemory::clear);
67 - // 可选:彻底清空缓存,销毁所有实例(释放内存,后续会重新创建)  
68 - // memoryCache.clear();  
69 } 68 }
70 69
71 - // ===================== 3. 精准操作:删除单条消息 ===================== 70 + // ===================== 3. 删除单条消息(完全重新设置方案) =====================
  71 +
72 /** 72 /**
73 - * 删除当前memoryId的指定单条消息(如删除错误消息)  
74 - * @param message 要删除的消息对象(从getCurrentChatMessages中获取) 73 + * 删除指定消息(通过完全重新设置消息列表的方式)
  74 + * @param memoryId 会话ID
  75 + * @param messageToDelete 要删除的消息对象
  76 + * @return 删除后的最新消息列表
75 */ 77 */
76 - public void deleteSingleMessage(Object memoryId, ChatMessage message) {  
77 - if (Objects.nonNull(memoryId) && Objects.nonNull(message)) {  
78 - ChatMemory currentMemory = this.get(memoryId);  
79 - // 删除指定消息  
80 - currentMemory.messages().remove(message);  
81 - // 刷新记忆,保证MessageWindowChatMemory的最大消息数限制生效  
82 -// currentMemory.update(currentMemory.messages()); 78 + public List<ChatMessage> deleteSingleMessage(Object memoryId, ChatMessage messageToDelete) {
  79 + if (Objects.isNull(memoryId) || Objects.isNull(messageToDelete)) {
  80 + return getCurrentChatMessages(memoryId);
  81 + }
  82 +
  83 + // 步骤1: 获取当前所有消息
  84 + ChatMemory currentMemory = this.get(memoryId);
  85 + List<ChatMessage> currentMessages = new ArrayList<>(currentMemory.messages());
  86 +
  87 + // 从后往前查找内容匹配的最后一条消息
  88 + int indexToDelete = -1;
  89 + for (int i = currentMessages.size() - 1; i >= 0; i--) {
  90 + ChatMessage msg = currentMessages.get(i);
  91 + if (isSameMessage(msg, messageToDelete)) {
  92 + indexToDelete = i;
  93 + break;
  94 + }
  95 + }
  96 + // 如果找到匹配的消息
  97 + if (indexToDelete >= 0) {
  98 + List<ChatMessage> filteredMessages = new ArrayList<>(currentMessages);
  99 + filteredMessages.remove(indexToDelete);
  100 + return rebuildMemoryWithMessages(memoryId, filteredMessages);
  101 + }
  102 + // 步骤4: 完全重新设置消息列表
  103 + return rebuildMemoryWithMessages(memoryId, currentMessages);
  104 + }
  105 + public List<ChatMessage> deleteUserLasterMessage(Object memoryId) {
  106 + if (Objects.isNull(memoryId)) {
  107 + return getCurrentChatMessages(memoryId);
83 } 108 }
  109 + // 步骤1: 获取当前所有消息
  110 + ChatMemory currentMemory = this.get(memoryId);
  111 + List<ChatMessage> currentMessages = new ArrayList<>(currentMemory.messages());
  112 +
  113 + // 从后往前查找内容匹配的最后一条消息
  114 + int indexToDelete = currentMessages.size()-1;
  115 + // 如果找到匹配的消息
  116 + if (indexToDelete >= 0) {
  117 + List<ChatMessage> filteredMessages = new ArrayList<>(currentMessages);
  118 + filteredMessages.remove(indexToDelete);
  119 + return rebuildMemoryWithMessages(memoryId, filteredMessages);
  120 + }
  121 + // 步骤4: 完全重新设置消息列表
  122 + return rebuildMemoryWithMessages(memoryId, currentMessages);
  123 + }
  124 + /**
  125 + * 批量删除多条消息
  126 + * @param memoryId 会话ID
  127 + * @param messagesToDelete 要删除的消息列表
  128 + * @return 删除后的最新消息列表
  129 + */
  130 + public List<ChatMessage> deleteMessages(Object memoryId, List<ChatMessage> messagesToDelete) {
  131 + if (Objects.isNull(memoryId) || messagesToDelete == null || messagesToDelete.isEmpty()) {
  132 + return getCurrentChatMessages(memoryId);
  133 + }
  134 +
  135 + // 获取当前所有消息
  136 + ChatMemory currentMemory = this.get(memoryId);
  137 + List<ChatMessage> currentMessages = new ArrayList<>(currentMemory.messages());
  138 +
  139 + // 过滤掉所有要删除的消息
  140 + List<ChatMessage> filteredMessages = currentMessages.stream()
  141 + .filter(msg -> messagesToDelete.stream().noneMatch(delMsg -> isSameMessage(msg, delMsg)))
  142 + .collect(Collectors.toList());
  143 +
  144 + // 如果消息数量没有变化,直接返回
  145 + if (filteredMessages.size() == currentMessages.size()) {
  146 + return currentMessages;
  147 + }
  148 +
  149 + // 重新设置消息列表
  150 + return rebuildMemoryWithMessages(memoryId, filteredMessages);
  151 + }
  152 +
  153 + /**
  154 + * 判断两条消息是否相同(支持根据内容、类型等多维度匹配)
  155 + */
  156 + private boolean isSameMessage(ChatMessage msg1, ChatMessage msg2) {
  157 +// if (msg1 == msg2) return true; // 同一对象引用
  158 +// if (msg1 == null || msg2 == null) return false;
  159 +//
  160 +// // 根据消息类型和内容判断
  161 +// // 方式1: 根据对象相等性
  162 +// if (msg1.equals(msg2)) return true;
  163 + // 方式2: 根据消息类型和文本内容(适用于大多数场景)
  164 + if (msg1.type() == msg2.type()) {
  165 + // 如果有唯一ID或时间戳,也可以加入判断
  166 + // 这里简单使用文本内容判断
  167 + String text1 = extractText(msg1);
  168 + String text2 = extractText(msg2);
  169 + return Objects.equals(text1, text2);
  170 + }
  171 +
  172 + return false;
  173 + }
  174 +
  175 + /**
  176 + * 从消息中提取文本内容
  177 + */
  178 + private String extractText(ChatMessage message) {
  179 + // 根据ChatMessage的实际类型提取文本
  180 + // 这里需要根据您的具体消息实现来调整
  181 + try {
  182 + // 尝试通过toString获取内容
  183 + return message.toString();
  184 + } catch (Exception e) {
  185 + return "";
  186 + }
  187 + }
  188 +
  189 + /**
  190 + * 核心方法:使用过滤后的消息列表重建记忆
  191 + */
  192 + private List<ChatMessage> rebuildMemoryWithMessages(Object memoryId, List<ChatMessage> messages) {
  193 + // 从缓存中移除原实例
  194 + ChatMemory oldMemory = memoryCache.remove(memoryId);
  195 +
  196 + // 创建新的ChatMemory实例
  197 + MessageWindowChatMemory newMemory = MessageWindowChatMemory.withMaxMessages(MAX_MESSAGE_SIZE);
  198 +
  199 + // 由于ChatMemory接口没有直接添加消息的方法,我们需要通过特定方式添加
  200 + // 方式1: 如果MessageWindowChatMemory有add方法(需要通过反射或强制类型转换)
  201 + try {
  202 + // 通过反射调用add方法(如果存在)
  203 + java.lang.reflect.Method addMethod = newMemory.getClass().getMethod("add", ChatMessage.class);
  204 + addMethod.setAccessible(true);
  205 + for (ChatMessage message : messages) {
  206 + addMethod.invoke(newMemory, message);
  207 + }
  208 + } catch (Exception e) {
  209 + // 方式2: 如果无法通过反射添加,我们需要使用替代方案
  210 + // 这里可以记录日志
  211 + System.err.println("无法通过反射添加消息: " + e.getMessage());
  212 +
  213 + // 方式3: 使用clear后通过某种方式重新添加
  214 + // 注意:这取决于具体的ChatMemory实现
  215 + }
  216 +
  217 + // 将新实例放入缓存
  218 + memoryCache.put(memoryId, newMemory);
  219 +
  220 + // 返回重建后的消息列表
  221 + return new ArrayList<>(newMemory.messages());
84 } 222 }
85 223
86 /** 224 /**
87 - * 移除并清除指定记忆(清空消息+从缓存删除实例,彻底释放资源,适用于过期会话 225 + * 移除并清除指定记忆(清空消息+从缓存删除实例
88 */ 226 */
89 public void removeAndClearMemory(Object memoryId) { 227 public void removeAndClearMemory(Object memoryId) {
90 if (Objects.nonNull(memoryId)) { 228 if (Objects.nonNull(memoryId)) {
@@ -94,4 +232,4 @@ public class OperableChatMemoryProvider implements ChatMemoryProvider { @@ -94,4 +232,4 @@ public class OperableChatMemoryProvider implements ChatMemoryProvider {
94 } 232 }
95 } 233 }
96 } 234 }
97 -} 235 -}
  236 +}
98 \ No newline at end of file 237 \ No newline at end of file
src/main/java/com/xly/service/XlyErpService.java
@@ -24,6 +24,8 @@ import com.xly.util.SqlValidateUtil; @@ -24,6 +24,8 @@ import com.xly.util.SqlValidateUtil;
24 import com.xly.util.ValiDataUtil; 24 import com.xly.util.ValiDataUtil;
25 import dev.langchain4j.agent.tool.ToolExecutionRequest; 25 import dev.langchain4j.agent.tool.ToolExecutionRequest;
26 import dev.langchain4j.data.message.AiMessage; 26 import dev.langchain4j.data.message.AiMessage;
  27 +import dev.langchain4j.data.message.ChatMessage;
  28 +import dev.langchain4j.data.message.ChatMessageType;
27 import dev.langchain4j.model.chat.ChatLanguageModel; 29 import dev.langchain4j.model.chat.ChatLanguageModel;
28 import dev.langchain4j.model.ollama.OllamaChatModel; 30 import dev.langchain4j.model.ollama.OllamaChatModel;
29 import dev.langchain4j.service.AiServices; 31 import dev.langchain4j.service.AiServices;
@@ -96,7 +98,7 @@ public class XlyErpService { @@ -96,7 +98,7 @@ public class XlyErpService {
96 if (session.getCurrentScene() != null 98 if (session.getCurrentScene() != null
97 && Objects.equals(session.getCurrentScene().getSSceneNo(), "ChatZone")) 99 && Objects.equals(session.getCurrentScene().getSSceneNo(), "ChatZone"))
98 { 100 {
99 - return getChatiAgent(input, session); 101 + return getChatiAgent(input, session,StrUtil.EMPTY);
100 } 102 }
101 103
102 // 3. 未选场景:先展示场景选择界面,处理用户序号选择 104 // 3. 未选场景:先展示场景选择界面,处理用户序号选择
@@ -108,9 +110,12 @@ public class XlyErpService { @@ -108,9 +110,12 @@ public class XlyErpService {
108 ErpAiAgent aiAgent = createErpAiAgent(userId, input, session); 110 ErpAiAgent aiAgent = createErpAiAgent(userId, input, session);
109 // 没有选择到场景,进闲聊模式 111 // 没有选择到场景,进闲聊模式
110 if (aiAgent == null){ 112 if (aiAgent == null){
111 - return getChatiAgent (input, session); 113 + return getChatiAgent (input, session,StrUtil.EMPTY);
112 } 114 }
  115 + List<ChatMessage> chatMessage = operableChatMemoryProvider.getCurrentChatMessages(session.getUserId());
113 String sResponMessage = aiAgent.chat(userId, input); 116 String sResponMessage = aiAgent.chat(userId, input);
  117 + List<ChatMessage> chatMessage2 = operableChatMemoryProvider.getCurrentChatMessages(session.getUserId());
  118 + String sResponMessageOld = StrUtil.EMPTY;
114 // 调用方法,参数缺失部分提示,就直接使用方法返回的 119 // 调用方法,参数缺失部分提示,就直接使用方法返回的
115 if(session.getCurrentTool() != null 120 if(session.getCurrentTool() != null
116 && session.getSFunPrompts()!=null 121 && session.getSFunPrompts()!=null
@@ -118,9 +123,6 @@ public class XlyErpService { @@ -118,9 +123,6 @@ public class XlyErpService {
118 // 缺失的参数明细 123 // 缺失的参数明细
119 sResponMessage = session.getSFunPrompts(); 124 sResponMessage = session.getSFunPrompts();
120 } 125 }
121 - if (session.getCurrentTool()== null){  
122 - sResponMessage = StrUtil.EMPTY;  
123 - }  
124 // //说明没有找到动态方法重新走一次 126 // //说明没有找到动态方法重新走一次
125 // if(maxToolRetries==1 && session.getCurrentTool()== null){ 127 // if(maxToolRetries==1 && session.getCurrentTool()== null){
126 // Thread.sleep(1000); 128 // Thread.sleep(1000);
@@ -136,6 +138,7 @@ public class XlyErpService { @@ -136,6 +138,7 @@ public class XlyErpService {
136 // } 138 // }
137 139
138 if (session.getCurrentTool()== null){ 140 if (session.getCurrentTool()== null){
  141 + sResponMessageOld = sResponMessage;
139 sResponMessage = StrUtil.EMPTY; 142 sResponMessage = StrUtil.EMPTY;
140 } 143 }
141 //5.执行工具方法后,清除记忆 144 //5.执行工具方法后,清除记忆
@@ -155,7 +158,7 @@ public class XlyErpService { @@ -155,7 +158,7 @@ public class XlyErpService {
155 } 158 }
156 //如果返回空的进入闲聊模式 159 //如果返回空的进入闲聊模式
157 if (ObjectUtil.isEmpty(sResponMessage)){ 160 if (ObjectUtil.isEmpty(sResponMessage)){
158 - return getChatiAgent (input, session); 161 + return getChatiAgent (input, session,sResponMessageOld);
159 } 162 }
160 if (session.getCurrentScene()!= null ){ 163 if (session.getCurrentScene()!= null ){
161 return AiResponseDTO.builder().aiText(sResponMessage) 164 return AiResponseDTO.builder().aiText(sResponMessage)
@@ -463,7 +466,12 @@ public class XlyErpService { @@ -463,7 +466,12 @@ public class XlyErpService {
463 * @return java.lang.String 466 * @return java.lang.String
464 * @Description 获取智普通智能体 467 * @Description 获取智普通智能体
465 **/ 468 **/
466 - private AiResponseDTO getChatiAgent (String input,UserSceneSession session){ 469 + private AiResponseDTO getChatiAgent (String input,UserSceneSession session,String sResponMessageOld){
  470 + String sceneName = ObjectUtil.isNotEmpty(session.getCurrentScene())?session.getCurrentScene().getSSceneName():StrUtil.EMPTY;
  471 + String methodName = ObjectUtil.isNotEmpty(session.getCurrentTool())?session.getCurrentTool().getSMethodName():"随便聊聊";
  472 + if(ObjectUtil.isNotEmpty(sResponMessageOld)){
  473 + return AiResponseDTO.builder().sSceneName(sceneName).sMethodName(methodName).aiText(sResponMessageOld).systemText(StrUtil.EMPTY).sReturnType(ReturnTypeCode.HTML.getCode()).build();
  474 + }
467 ChatiAgent chatiAgent = UserSceneSessionService.CHAT_AGENT_CACHE.get(session.getUserId()); 475 ChatiAgent chatiAgent = UserSceneSessionService.CHAT_AGENT_CACHE.get(session.getUserId());
468 if(ObjectUtil.isEmpty(chatiAgent)){ 476 if(ObjectUtil.isEmpty(chatiAgent)){
469 chatiAgent = AiServices.builder(ChatiAgent.class) 477 chatiAgent = AiServices.builder(ChatiAgent.class)
@@ -472,9 +480,32 @@ public class XlyErpService { @@ -472,9 +480,32 @@ public class XlyErpService {
472 .build(); 480 .build();
473 UserSceneSessionService.CHAT_AGENT_CACHE.put(session.getUserId(), chatiAgent); } 481 UserSceneSessionService.CHAT_AGENT_CACHE.put(session.getUserId(), chatiAgent); }
474 String sChatMessage = chatiAgent.chat(session.getUserId(), input); 482 String sChatMessage = chatiAgent.chat(session.getUserId(), input);
475 - String sceneName = ObjectUtil.isNotEmpty(session.getCurrentScene())?session.getCurrentScene().getSSceneName():StrUtil.EMPTY;  
476 - String methodName = ObjectUtil.isNotEmpty(session.getCurrentTool())?session.getCurrentTool().getSMethodName():"随便聊聊"; 483 + //随便聊聊移除系统返回的提示记忆
  484 +// List<ChatMessage> chatMessage = operableChatMemoryProvider.getCurrentChatMessages(session.getUserId());
  485 +// removeMssageSbll(chatMessage, session.getUserId());
  486 +// operableChatMemoryProvider.deleteUserLasterMessage(session.getUserId());
  487 +// chatMessage = operableChatMemoryProvider.getCurrentChatMessages(session.getUserId());
477 return AiResponseDTO.builder().sSceneName(sceneName).sMethodName(methodName).aiText(sChatMessage).systemText(StrUtil.EMPTY).sReturnType(ReturnTypeCode.HTML.getCode()).build(); 488 return AiResponseDTO.builder().sSceneName(sceneName).sMethodName(methodName).aiText(sChatMessage).systemText(StrUtil.EMPTY).sReturnType(ReturnTypeCode.HTML.getCode()).build();
478 } 489 }
  490 + /***
  491 + * @Author 钱豹
  492 + * @Date 12:14 2026/3/8
  493 + * @Param [chatMessage, memoryId]
  494 + * @return void
  495 + * @Description 随便聊聊移除最后一个AI 返回信息 跟系统询问的随便聊聊
  496 + **/
  497 + private void removeMssageSbll(List<ChatMessage> chatMessage,String memoryId){
  498 + if(chatMessage!=null){
  499 +// operableChatMemoryProvider.deleteSingleMessage(memoryId,chatMessage.get(chatMessage.size()-1));
  500 + for(int i=chatMessage.size()-1;i>0;i--){
  501 + ChatMessage data = chatMessage.get(i);
  502 + ChatMessageType sType = data.type();
  503 + if(ChatMessageType.SYSTEM.equals(sType)){
  504 + operableChatMemoryProvider.deleteSingleMessage(memoryId,data);
  505 + return;
  506 + }
  507 + }
  508 + }
  509 + }
479 510
480 } 511 }
481 \ No newline at end of file 512 \ No newline at end of file
src/main/java/com/xly/tool/DynamicToolProvider.java
@@ -551,7 +551,7 @@ public class DynamicToolProvider implements ToolProvider { @@ -551,7 +551,7 @@ public class DynamicToolProvider implements ToolProvider {
551 List<String> missing = checkRequiredParams(args, paramRuleData); 551 List<String> missing = checkRequiredParams(args, paramRuleData);
552 if (!missing.isEmpty()) { 552 if (!missing.isEmpty()) {
553 // 4.1 参数缺失,生成“提问”消息,直接返给客户 553 // 4.1 参数缺失,生成“提问”消息,直接返给客户
554 - String askMsg = buildAskUserMessage(meta, missing); 554 + String askMsg = buildAskUserMessage(meta, missing,args);
555 session.setSFunPrompts(askMsg); 555 session.setSFunPrompts(askMsg);
556 return String.valueOf(askUserResult(toolExecutionRequest, askMsg)); 556 return String.valueOf(askUserResult(toolExecutionRequest, askMsg));
557 } 557 }
@@ -576,7 +576,7 @@ public class DynamicToolProvider implements ToolProvider { @@ -576,7 +576,7 @@ public class DynamicToolProvider implements ToolProvider {
576 List<String> missingAfter = checkConfirmAfterParam(args, paramRuleData); 576 List<String> missingAfter = checkConfirmAfterParam(args, paramRuleData);
577 if (!missingAfter.isEmpty()) { 577 if (!missingAfter.isEmpty()) {
578 // 4.1 参数缺失,生成“提问”消息,直接返给客户 578 // 4.1 参数缺失,生成“提问”消息,直接返给客户
579 - String askMsg = buildAskUserMessage(meta, missingAfter); 579 + String askMsg = buildAskUserMessage(meta, missingAfter,args);
580 session.setSFunPrompts(askMsg); 580 session.setSFunPrompts(askMsg);
581 return String.valueOf(askUserResult(toolExecutionRequest, askMsg)); 581 return String.valueOf(askUserResult(toolExecutionRequest, askMsg));
582 } 582 }
@@ -739,7 +739,6 @@ public class DynamicToolProvider implements ToolProvider { @@ -739,7 +739,6 @@ public class DynamicToolProvider implements ToolProvider {
739 if(ObjectUtil.isEmpty(dataList)){ 739 if(ObjectUtil.isEmpty(dataList)){
740 throw new BusinessException(ErrorCode.PARAM_REQUIRED,String.format("%s 您描述的%s 不存在,请重新告诉我",name,nameValue)); 740 throw new BusinessException(ErrorCode.PARAM_REQUIRED,String.format("%s 您描述的%s 不存在,请重新告诉我",name,nameValue));
741 } 741 }
742 -  
743 //如果SQL没有条件 多个数据集中进行匹配 如果只匹配一个也算成功 742 //如果SQL没有条件 多个数据集中进行匹配 如果只匹配一个也算成功
744 if(ObjectUtil.isNotEmpty(args.get(name)) || ObjectUtil.isNotEmpty(args.get(sValue))){ 743 if(ObjectUtil.isNotEmpty(args.get(name)) || ObjectUtil.isNotEmpty(args.get(sValue))){
745 if(("enum".equals(sType) ||"string".equals(sType)) && (args.get(name) instanceof List || args.get(sValue) instanceof List)){ 744 if(("enum".equals(sType) ||"string".equals(sType)) && (args.get(name) instanceof List || args.get(sValue) instanceof List)){
@@ -1154,7 +1153,7 @@ public class DynamicToolProvider implements ToolProvider { @@ -1154,7 +1153,7 @@ public class DynamicToolProvider implements ToolProvider {
1154 /** 1153 /**
1155 * 构建提问消息 1154 * 构建提问消息
1156 */ 1155 */
1157 - private String buildAskUserMessage(ToolMeta meta, List<String> missing) { 1156 + private String buildAskUserMessage(ToolMeta meta, List<String> missing,Map<String,Object> arg) {
1158 StringBuilder sb = new StringBuilder(); 1157 StringBuilder sb = new StringBuilder();
1159 sb.append("缺少参数请补全:\n"); 1158 sb.append("缺少参数请补全:\n");
1160 List<ParamRule> paramRuleData = meta.getParamRuleList(); 1159 List<ParamRule> paramRuleData = meta.getParamRuleList();
@@ -1166,8 +1165,14 @@ public class DynamicToolProvider implements ToolProvider { @@ -1166,8 +1165,14 @@ public class DynamicToolProvider implements ToolProvider {
1166 pd -> { 1165 pd -> {
1167 String sTs = ObjectUtil.isEmpty(pd.getSRuleTs())?StrUtil.EMPTY:pd.getSRuleTs(); 1166 String sTs = ObjectUtil.isEmpty(pd.getSRuleTs())?StrUtil.EMPTY:pd.getSRuleTs();
1168 sb.append("- **").append(name).append("**: "); 1167 sb.append("- **").append(name).append("**: ");
1169 - if(ObjectUtil.isNotEmpty(pd.getSParamMissMemo())){  
1170 - if(!("string".equals(pd.getSType()) && RuleCode.SQL.equals(pd.getSRule()) && ObjectUtil.isNotEmpty(pd.getSParamConfig())) ) 1168 + if(ObjectUtil.isNotEmpty(pd.getSParamMissMemo())
  1169 + && ObjectUtil.isNotEmpty(arg.get(pd.getSParam()))
  1170 + && ObjectUtil.isNotEmpty(sTs)
  1171 + ){
  1172 + if(!("string".equals(pd.getSType())
  1173 + && RuleCode.SQL.equals(pd.getSRule())
  1174 + && ObjectUtil.isNotEmpty(pd.getSParamConfig())
  1175 + ))
1171 { 1176 {
1172 sb.append(StrUtil.format(pd.getSParamMissMemo(),sTs)); 1177 sb.append(StrUtil.format(pd.getSParamMissMemo(),sTs));
1173 } 1178 }