Commit 1b14dc87d2f4dfee2c2e292385a93f01dada515b

Authored by qianbao
1 parent 834944fa

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

src/main/java/com/xly/agent/SystemPromptGenerator.java 0 → 100644
  1 +package com.xly.agent;
  2 +
  3 +import cn.hutool.core.util.ObjectUtil;
  4 +import cn.hutool.json.JSONConfig;
  5 +import cn.hutool.json.JSONUtil;
  6 +import com.alibaba.fastjson2.JSON;
  7 +import com.alibaba.fastjson2.JSONObject;
  8 +import com.alibaba.fastjson2.JSONWriter;
  9 +import com.xly.entity.ParamRule;
  10 +import com.xly.entity.UserSceneSession;
  11 +
  12 +import java.util.List;
  13 +
  14 +public class SystemPromptGenerator {
  15 +
  16 + public static String generate(String toolName, UserSceneSession session) {
  17 + StringBuilder sb = new StringBuilder();
  18 +
  19 + sb.append("你是一个无情的参数提取器,不是聊天助手。\n\n");
  20 + sb.append("【核心任务】\n");
  21 + sb.append("从用户输入中提取参数,并立即调用工具 ").append(toolName).append("。\n\n");
  22 + sb.append("【绝对指令】\n");
  23 + sb.append("1. 严禁与用户对话,严禁输出任何纯文本回复。\n");
  24 + sb.append("2. 无论参数缺失多么严重,都必须直接调用工具,缺失字段填空字符串或0。\n");
  25 + sb.append("3. 不要引导用户,后端程序会处理引导逻辑。\n\n");
  26 + sb.append("【参数提取规则】\n");
  27 + sb.append("用户输入格式为 \"参数名: 值\" 或 \"参数名 值\",你必须识别参数名并提取对应的值。\n\n");
  28 + sb.append("【可提取的参数列表】\n");
  29 + List<ParamRule> dynamicParamRuleAll = session.getCurrentTool().getParamRuleListAll();
  30 + // 从参数定义中提取
  31 + for (ParamRule paramRule : dynamicParamRuleAll) {
  32 + sb.append("- ").append(paramRule.getSParam()).append("\n");
  33 + }
  34 + sb.append("\n【提取示例】\n");
  35 + // 动态生成示例(取前3个参数作为示例)
  36 + int count = 0;
  37 + for (ParamRule paramRule : dynamicParamRuleAll) {
  38 + if (count++ >= 3) break;
  39 + sb.append("- 用户输入 \"").append(paramRule.getSParam()).append(": {值}\" → 提取 ").append(paramRule.getSParam()).append("\n");
  40 + }
  41 +
  42 + if(ObjectUtil.isNotEmpty(session.getArgs())){
  43 + sb.append("【已提取参数】\n");
  44 + sb.append(JSON.toJSONString(session.getArgs(), JSONWriter.Feature.PrettyFormat));
  45 + }
  46 + sb.append("\n【工具调用规则】\n");
  47 + sb.append("1. 每次只调用一次工具\n");
  48 + sb.append("2. 调用后立即停止,不要重复调用\n");
  49 + sb.append("3. 不要总结,不要回复用户,只调用工具");
  50 +
  51 + return sb.toString();
  52 + }
  53 +}
0 \ No newline at end of file 54 \ No newline at end of file
src/main/java/com/xly/entity/ParamRule.java
@@ -14,6 +14,7 @@ import java.time.LocalDateTime; @@ -14,6 +14,7 @@ import java.time.LocalDateTime;
14 @Data 14 @Data
15 public class ParamRule { 15 public class ParamRule {
16 private Integer iOrder; 16 private Integer iOrder;
  17 + private String sId;
17 private String sParamValue; 18 private String sParamValue;
18 private String sParentId; 19 private String sParentId;
19 private String sParam; 20 private String sParam;
@@ -28,5 +29,9 @@ public class ParamRule { @@ -28,5 +29,9 @@ public class ParamRule {
28 private Boolean bTipModel; 29 private Boolean bTipModel;
29 private Boolean bEmpty; 30 private Boolean bEmpty;
30 private Boolean bConfirmAfter; 31 private Boolean bConfirmAfter;
  32 + private String sDynamicParamRuleSql;
  33 + private String sDynamicParam;
  34 + private String sDynamicParamName;
  35 + private Boolean bDynamicParam = false;
31 36
32 } 37 }
src/main/java/com/xly/entity/ToolMeta.java
@@ -46,6 +46,7 @@ public class ToolMeta { @@ -46,6 +46,7 @@ public class ToolMeta {
46 private List<ParamRule> paramRuleList;//模型 46 private List<ParamRule> paramRuleList;//模型
47 private List<ParamRule> paramRuleListCheck;//需要校验 47 private List<ParamRule> paramRuleListCheck;//需要校验
48 private List<ParamRule> paramRuleListAll;//所有的 48 private List<ParamRule> paramRuleListAll;//所有的
  49 + private List<ParamRule> dynamicParamRule;//动态参数
49 private LocalDateTime tMakeDate; 50 private LocalDateTime tMakeDate;
50 private String sVectorfiled; 51 private String sVectorfiled;
51 private String sVectorjson; 52 private String sVectorjson;
src/main/java/com/xly/mapper/ToolMetaMapper.java
@@ -15,5 +15,4 @@ public interface ToolMetaMapper { @@ -15,5 +15,4 @@ public interface ToolMetaMapper {
15 // XML配置方式 15 // XML配置方式
16 @Select("SELECT A.* FROM ai_tool AS A order by iOrder") 16 @Select("SELECT A.* FROM ai_tool AS A order by iOrder")
17 List<ToolMeta> findAll(); 17 List<ToolMeta> findAll();
18 -  
19 } 18 }
20 \ No newline at end of file 19 \ No newline at end of file
src/main/java/com/xly/service/XlyErpService.java
@@ -362,6 +362,11 @@ public class XlyErpService { @@ -362,6 +362,11 @@ public class XlyErpService {
362 //重新生成新的aiAgent拿新的aiAgent 做选择 362 //重新生成新的aiAgent拿新的aiAgent 做选择
363 aiAgent = createConfirmeAgent(session); 363 aiAgent = createConfirmeAgent(session);
364 } 364 }
  365 + //存在动态参数需要重新定义引导语
  366 + if(ObjectUtil.isNotEmpty(session.getCurrentTool())&&ObjectUtil.isNotEmpty(session.getCurrentTool().getDynamicParamRule())){
  367 + sSystemPrompt = SystemPromptGenerator.generate(session.getCurrentTool().getSMethodName(),session);
  368 + aiAgent = createConfirmeAgent(session);
  369 + }
365 Result<String> rs = aiAgent.chat(userId, input,sSystemPrompt); 370 Result<String> rs = aiAgent.chat(userId, input,sSystemPrompt);
366 sResponMessage = rs.content(); 371 sResponMessage = rs.content();
367 } 372 }
@@ -954,7 +959,7 @@ public class XlyErpService { @@ -954,7 +959,7 @@ public class XlyErpService {
954 executors.put(one.getToolSpecification(),one.getToolExecutor()); 959 executors.put(one.getToolSpecification(),one.getToolExecutor());
955 }); 960 });
956 } 961 }
957 - 962 +// operableChatMemoryProvider.clearSpecifiedMemory(session.getUserId());
958 aiAgent = AiServices.builder(ErpAiAgent.class) 963 aiAgent = AiServices.builder(ErpAiAgent.class)
959 .chatModel(chatModel) 964 .chatModel(chatModel)
960 .chatMemoryProvider(operableChatMemoryProvider) 965 .chatMemoryProvider(operableChatMemoryProvider)
@@ -974,13 +979,18 @@ public class XlyErpService { @@ -974,13 +979,18 @@ public class XlyErpService {
974 if(ObjectUtil.isNotEmpty(dataList)){ 979 if(ObjectUtil.isNotEmpty(dataList)){
975 dataList.forEach(one->{ 980 dataList.forEach(one->{
976 immediateReturnToolNames.add(one.getsName()); 981 immediateReturnToolNames.add(one.getsName());
977 - executors.put(one.getToolSpecification(),one.getToolExecutor()); 982 + if(ObjectUtil.isNotEmpty(session.getCurrentTool()) && ObjectUtil.isNotEmpty(session.getCurrentTool().getDynamicParamRule())){
  983 + ToolSpecification spec = dynamicToolProvider.buildToolSpecification(session.getCurrentTool());
  984 + session.getCurrentTool().setDynamicParamRule(new ArrayList<>());
  985 + executors.put(spec,one.getToolExecutor());
  986 + }else{
  987 + executors.put(one.getToolSpecification(),one.getToolExecutor());
  988 + }
978 }); 989 });
979 } 990 }
980 - ChatMemory chatMemory = operableChatMemoryProvider.get(session.getUserId()); 991 + operableChatMemoryProvider.clearSpecifiedMemory(session.getUserId());
981 ErpAiAgent aiAgent = AiServices.builder(ErpAiAgent.class) 992 ErpAiAgent aiAgent = AiServices.builder(ErpAiAgent.class)
982 .chatModel(chatModel) 993 .chatModel(chatModel)
983 - .chatMemory(chatMemory)  
984 .chatMemoryProvider(operableChatMemoryProvider) 994 .chatMemoryProvider(operableChatMemoryProvider)
985 .tools(executors,immediateReturnToolNames) 995 .tools(executors,immediateReturnToolNames)
986 .build(); 996 .build();
src/main/java/com/xly/tool/DynamicToolProvider.java
1 package com.xly.tool; 1 package com.xly.tool;
2 2
3 3
  4 +import cn.hutool.core.bean.BeanUtil;
4 import cn.hutool.core.date.DateUtil; 5 import cn.hutool.core.date.DateUtil;
5 import cn.hutool.core.util.BooleanUtil; 6 import cn.hutool.core.util.BooleanUtil;
6 import cn.hutool.core.util.ObjectUtil; 7 import cn.hutool.core.util.ObjectUtil;
7 import cn.hutool.core.util.StrUtil; 8 import cn.hutool.core.util.StrUtil;
  9 +import cn.hutool.json.JSONArray;
8 import cn.hutool.json.JSONUtil; 10 import cn.hutool.json.JSONUtil;
9 import com.alibaba.fastjson2.JSONObject; 11 import com.alibaba.fastjson2.JSONObject;
10 import com.fasterxml.jackson.core.type.TypeReference; 12 import com.fasterxml.jackson.core.type.TypeReference;
11 13
12 import com.fasterxml.jackson.databind.ObjectMapper; 14 import com.fasterxml.jackson.databind.ObjectMapper;
13 15
14 -import com.xly.agent.AgentSystemPrompt;  
15 import com.xly.config.OperableChatMemoryProvider; 16 import com.xly.config.OperableChatMemoryProvider;
16 import com.xly.constant.*; 17 import com.xly.constant.*;
17 import com.xly.entity.*; 18 import com.xly.entity.*;
18 import com.xly.exception.dto.BusinessException; 19 import com.xly.exception.dto.BusinessException;
19 -import com.xly.exception.dto.DataException;  
20 import com.xly.mapper.ParamRuleMapper; 20 import com.xly.mapper.ParamRuleMapper;
21 import com.xly.mapper.ToolMetaMapper; 21 import com.xly.mapper.ToolMetaMapper;
22 import com.xly.service.DynamicExeDbService; 22 import com.xly.service.DynamicExeDbService;
@@ -25,27 +25,22 @@ import com.xly.util.*; @@ -25,27 +25,22 @@ import com.xly.util.*;
25 import dev.langchain4j.agent.tool.*; 25 import dev.langchain4j.agent.tool.*;
26 26
27 import dev.langchain4j.data.message.*; 27 import dev.langchain4j.data.message.*;
28 -  
29 -import dev.langchain4j.memory.ChatMemory;  
30 -  
31 import dev.langchain4j.model.chat.request.json.JsonObjectSchema; 28 import dev.langchain4j.model.chat.request.json.JsonObjectSchema;
32 -import dev.langchain4j.model.chat.request.json.JsonSchema;  
33 import dev.langchain4j.service.tool.*; 29 import dev.langchain4j.service.tool.*;
34 30
35 31
36 -import lombok.Getter;  
37 import lombok.RequiredArgsConstructor; 32 import lombok.RequiredArgsConstructor;
38 33
39 -import lombok.Setter;  
40 import lombok.extern.slf4j.Slf4j; 34 import lombok.extern.slf4j.Slf4j;
41 35
42 -import org.apache.ibatis.javassist.expr.NewArray;  
43 import org.springframework.beans.factory.annotation.Value; 36 import org.springframework.beans.factory.annotation.Value;
44 import org.springframework.stereotype.Service; 37 import org.springframework.stereotype.Service;
45 38
46 import java.util.*; 39 import java.util.*;
47 40
48 import java.util.concurrent.ConcurrentHashMap; 41 import java.util.concurrent.ConcurrentHashMap;
  42 +import java.util.concurrent.atomic.AtomicReference;
  43 +import java.util.function.Function;
49 import java.util.stream.Collectors; 44 import java.util.stream.Collectors;
50 import java.util.stream.IntStream; 45 import java.util.stream.IntStream;
51 46
@@ -188,8 +183,13 @@ public class DynamicToolProvider implements ToolProvider { @@ -188,8 +183,13 @@ public class DynamicToolProvider implements ToolProvider {
188 if(ObjectUtil.isEmpty(args)) args = new HashMap<>(); 183 if(ObjectUtil.isEmpty(args)) args = new HashMap<>();
189 Map<String, Object> finalArgs = args; 184 Map<String, Object> finalArgs = args;
190 argsNew.forEach((k, v)->{ 185 argsNew.forEach((k, v)->{
191 - //获取对应的英文参数  
192 - List<ParamRule> data = meta.getParamRuleList().stream().filter(one->one.getSParam().equals(k)).collect(Collectors.toUnmodifiableList()); 186 + //需要移除的老的参数
  187 + List<ParamRule> data = meta.getParamRuleList().stream().filter(
  188 + one-> one.getSParam().equals(k)
  189 + && ObjectUtil.isNotEmpty(v)
  190 + && !"0".equals(v)
  191 + && !"\"\"".equals(v)
  192 + ).collect(Collectors.toUnmodifiableList());
193 if(ObjectUtil.isNotEmpty(data) && data.size()>0){ 193 if(ObjectUtil.isNotEmpty(data) && data.size()>0){
194 finalArgs.remove(data.get(0).getSParamValue()); 194 finalArgs.remove(data.get(0).getSParamValue());
195 finalArgs.remove(data.get(0).getSParam()); 195 finalArgs.remove(data.get(0).getSParam());
@@ -198,7 +198,6 @@ public class DynamicToolProvider implements ToolProvider { @@ -198,7 +198,6 @@ public class DynamicToolProvider implements ToolProvider {
198 finalArgs.put(k,v); 198 finalArgs.put(k,v);
199 } 199 }
200 }); 200 });
201 -  
202 // 2 【补全动态参数】动态参数补全 201 // 2 【补全动态参数】动态参数补全
203 try{ 202 try{
204 args = applyValues(args, meta.getParamRuleListCheck()); 203 args = applyValues(args, meta.getParamRuleListCheck());
@@ -213,6 +212,19 @@ public class DynamicToolProvider implements ToolProvider { @@ -213,6 +212,19 @@ public class DynamicToolProvider implements ToolProvider {
213 // 2.1 【自动补全】应用参数的默认值 212 // 2.1 【自动补全】应用参数的默认值
214 List<ParamRule> paramRuleData = meta.getParamRuleListAll(); 213 List<ParamRule> paramRuleData = meta.getParamRuleListAll();
215 args = applyDefaultValues(args, paramRuleData); 214 args = applyDefaultValues(args, paramRuleData);
  215 + //存入已采集参数
  216 + session.setArgs(args);
  217 + // 2.1.1 根据当前获取的新参数判断是否存在有值必填例如动态参数、动态部件
  218 + List<ParamRule> dynamicParamRule = doSetParamgetArgsAfter(args, session);
  219 + if(ObjectUtil.isNotEmpty(dynamicParamRule)){
  220 + String askMsg = hasDynamicParamRule(argsNew, session,dynamicParamRule);
  221 + session.getCurrentTool().setDynamicParamRule(dynamicParamRule);
  222 + //此处修改动态参数
  223 + session.setSFunPrompts(askMsg);
  224 + addSystemMessage(session, askMsg);
  225 + // 需要提问用户 → 抛异常停止循环
  226 + return String.valueOf(successResult(toolExecutionRequest, askMsg));
  227 + }
216 //客户选择行号转sSLaveId 228 //客户选择行号转sSLaveId
217 if(ObjectUtil.isNotEmpty(args) 229 if(ObjectUtil.isNotEmpty(args)
218 &&( 230 &&(
@@ -222,6 +234,7 @@ public class DynamicToolProvider implements ToolProvider { @@ -222,6 +234,7 @@ public class DynamicToolProvider implements ToolProvider {
222 ){ 234 ){
223 doSetSlaveIdToArgs( args, session); 235 doSetSlaveIdToArgs( args, session);
224 } 236 }
  237 + //存入已采集参数
225 session.setArgs(args); 238 session.setArgs(args);
226 // 3. 【自动校验】检查必填项 239 // 3. 【自动校验】检查必填项
227 List<String> missing = checkRequiredParams(args, paramRuleData); 240 List<String> missing = checkRequiredParams(args, paramRuleData);
@@ -238,6 +251,192 @@ public class DynamicToolProvider implements ToolProvider { @@ -238,6 +251,192 @@ public class DynamicToolProvider implements ToolProvider {
238 }; 251 };
239 } 252 }
240 253
  254 + /***
  255 + * @Author 钱豹
  256 + * @Date 22:50 2026/6/28
  257 + * @Param [args, session]
  258 + * @return void
  259 + * @Description 获取动态参数
  260 + **/
  261 + private List<ParamRule> doSetParamgetArgsAfter(Map<String,Object> argsNew,UserSceneSession session){
  262 + //获取当前方法
  263 + ToolMeta tool = session.getCurrentTool();
  264 + Map<String, Object> argsOld = session.getArgs();
  265 + Map<String, Object> args = DeepCopyUtils.deepCopy(argsNew);
  266 + if(ObjectUtil.isEmpty(argsOld)){
  267 + argsOld = new HashMap<>();
  268 + }
  269 + //根据新录入的参数获取规则
  270 + AtomicReference<List<ParamRule>> paramRuleDataAll = new AtomicReference<>(tool.getParamRuleListAll());
  271 + List<ParamRule> paramRuleData = tool.getParamRuleListAll();
  272 + paramRuleData = paramRuleData.stream().filter(one->
  273 + ( ObjectUtil.isNotEmpty(args.get(one.getSParam())) ||ObjectUtil.isNotEmpty(args.get(one.getSParamValue())))
  274 + && ObjectUtil.isNotEmpty(one.getSDynamicParamRuleSql())
  275 + ).collect(Collectors.toUnmodifiableList());
  276 + List<ParamRule> dynamicParamRule = new ArrayList<>();
  277 + //为空的时候需要重新插入 不为空 表示之前已经放过了
  278 + if(ObjectUtil.isNotEmpty(paramRuleData)){
  279 + Map<String, Object> finalArgsOld = argsOld;
  280 + paramRuleData.forEach(one->{
  281 + //根据新参数获取需要填写参数
  282 + Map<String,Object> searMap = new HashMap<>();
  283 + searMap.putAll(args);
  284 + //新参数如果值变了移除掉之前插入的
  285 + List<ParamRule> paramRuleDataAllNew = paramRuleDataAll.get().stream().filter(d->
  286 + !one.getSParam().equals(d.getSDynamicParam())
  287 + ||(one.getSParam().equals(d.getSDynamicParam()) && one.getSParamValue().equals(d.getSParamValue()))
  288 + ).collect(Collectors.toUnmodifiableList());
  289 + List<ParamRule> paramRuleList = tool.getParamRuleList().stream().filter(d->
  290 + !one.getSParam().equals(d.getSDynamicParam())
  291 + ||(one.getSParam().equals(d.getSDynamicParam()) && one.getSParamValue().equals(d.getSParamValue()))
  292 + ).collect(Collectors.toUnmodifiableList());
  293 + List<ParamRule> paramRuleListCheck = tool.getParamRuleListCheck().stream().filter(d->
  294 + !one.getSParam().equals(d.getSDynamicParam())
  295 + ||(one.getSParam().equals(d.getSDynamicParam()) && one.getSParamValue().equals(d.getSParamValue()))
  296 + ).collect(Collectors.toUnmodifiableList());
  297 + paramRuleDataAllNew = deduplicateByParamValue(paramRuleDataAllNew);
  298 + paramRuleList = deduplicateByParamValue(paramRuleList);
  299 + paramRuleListCheck = deduplicateByParamValue(paramRuleListCheck);
  300 + session.getCurrentTool().setParamRuleList(paramRuleList);
  301 + session.getCurrentTool().setParamRuleListAll(paramRuleDataAllNew);
  302 + session.getCurrentTool().setParamRuleListCheck(paramRuleListCheck);
  303 +// paramRuleDataAll.set(paramRuleDataAllNew);
  304 + List<ParamRule> paramRuleDataD = paramRuleDataAll.get().stream().filter(d-> searMap.get(one.getSParam()).equals(d.getSDynamicParam())).collect(Collectors.toUnmodifiableList());
  305 + //如果不存在的加入方法参数中
  306 + if(ObjectUtil.isEmpty(paramRuleDataD)){
  307 + String sValue = searMap.get(one.getSParam()).toString();
  308 + List<String> addValue = new ArrayList<>();
  309 + if(JSONUtil.isTypeJSONArray(sValue)){
  310 + addValue = JSONUtil.toList(sValue,String.class);
  311 + }else{
  312 + addValue.add(sValue);
  313 + }
  314 + for(String sVaule:addValue){
  315 + searMap.put("sRuleId",one.getSId());
  316 + searMap.put("sTooId",one.getSParentId());
  317 + searMap.put("sParam",one.getSParam());
  318 + searMap.put("sParamValue",sVaule);
  319 +// searMap.put("sParamValue",one.getSParamValue());
  320 + searMap.put("sParamName",one.getSParam());
  321 + String sSql = one.getSDynamicParamRuleSql();
  322 + searMap.put("argsNew",JSONObject.toJSONString(args));
  323 + searMap.put("argsAll",JSONObject.toJSONString(finalArgsOld));
  324 + //如果不是SELECT 开头
  325 + List<Map<String,Object>> selectData = new ArrayList<>();
  326 + List<Map<String,Object>> dynamicParamRuleOne = new ArrayList<>();
  327 + if(sSql.replaceAll(" ","").toLowerCase().startsWith("select")
  328 + || sSql.replaceAll(" ","").toLowerCase().startsWith("call")){
  329 + selectData = this.dynamicExeDbService.findSql(searMap, sSql);
  330 + String sData = (ObjectUtil.isNotEmpty(selectData)
  331 + && ObjectUtil.isNotEmpty(selectData.get(0).get("sData")))?selectData.get(0).get("sData").toString():StrUtil.EMPTY;
  332 + if(ObjectUtil.isNotEmpty(sData)){
  333 + dynamicParamRuleOne = JsonUtils.toList(sData,Map.class);
  334 + }
  335 + }else{
  336 + //表示过程走自定义参数
  337 +
  338 + }
  339 + if(ObjectUtil.isNotEmpty(dynamicParamRuleOne)){
  340 + //转换成BEAN
  341 + //添加到方法中去
  342 + List<ParamRule> paramRuleDataAllAdd = tool.getParamRuleListAll().stream().collect(Collectors.toList());
  343 + List<ParamRule> paramRuleListAdd = tool.getParamRuleList().stream().collect(Collectors.toList());
  344 + List<ParamRule> paramRuleListCheckAdd = tool.getParamRuleListCheck().stream().collect(Collectors.toList());
  345 + if(ObjectUtil.isEmpty(paramRuleDataAllAdd)){
  346 + paramRuleDataAllAdd = new ArrayList<>();
  347 + }
  348 + if(ObjectUtil.isEmpty(paramRuleListAdd)){
  349 + paramRuleListAdd = new ArrayList<>();
  350 + }
  351 + if(ObjectUtil.isEmpty(paramRuleListCheckAdd)){
  352 + paramRuleListCheckAdd = new ArrayList<>();
  353 + }
  354 + List<ParamRule> finalParamRuleDataAllAdd = paramRuleDataAllAdd;
  355 + List<ParamRule> finalParamRuleListAdd = paramRuleListAdd;
  356 + List<ParamRule> finalParamRuleListCheckAdd = paramRuleListCheckAdd;
  357 + dynamicParamRuleOne.forEach(dynamicParamRuleData->{
  358 + ParamRule paramRule = BeanUtil.toBean(dynamicParamRuleData,ParamRule.class);
  359 + dynamicParamRule.add(paramRule);
  360 + try{
  361 + finalParamRuleDataAllAdd.add(paramRule);
  362 + finalParamRuleListAdd.add(paramRule);
  363 + if(paramRule.getBEmpty()){
  364 + finalParamRuleListCheckAdd.add(paramRule);
  365 + }
  366 + }catch (Exception e){
  367 + e.printStackTrace();
  368 + }
  369 + });
  370 + if(ObjectUtil.isNotEmpty(paramRuleDataAllAdd)){
  371 + paramRuleDataAllAdd = deduplicateByParamValue(paramRuleDataAllAdd);
  372 + session.getCurrentTool().setParamRuleListAll(paramRuleDataAllAdd);
  373 + }
  374 + if(ObjectUtil.isNotEmpty(paramRuleListAdd)){
  375 + paramRuleListAdd = deduplicateByParamValue(paramRuleListAdd);
  376 + session.getCurrentTool().setParamRuleList(paramRuleListAdd);
  377 + }
  378 + if(ObjectUtil.isNotEmpty(paramRuleListCheckAdd)){
  379 + paramRuleListCheckAdd = deduplicateByParamValue(paramRuleListCheckAdd);
  380 + session.getCurrentTool().setParamRuleListCheck(paramRuleListCheckAdd);
  381 + }
  382 + }
  383 + }
  384 + }
  385 + });
  386 + }
  387 + return dynamicParamRule;
  388 + }
  389 + /***
  390 + * @Author 钱豹
  391 + * @Date 0:58 2026/7/2
  392 + * @Param [source, one]
  393 + * @return java.util.List<com.xly.entity.ParamRule>
  394 + * @Description 去重
  395 + **/
  396 + private List<ParamRule> deduplicateByParamValue(List<ParamRule> source) {
  397 + if (source == null || source.isEmpty()) {
  398 + return new ArrayList<>();
  399 + }
  400 + return source.stream()
  401 + .collect(Collectors.toMap(
  402 + ParamRule::getSParamValue, // 根据 sParamValue 去重
  403 + Function.identity(),
  404 + (existing, replacement) -> existing // 保留第一个
  405 + ))
  406 + .values()
  407 + .stream()
  408 + .collect(Collectors.toList());
  409 + }
  410 + /***
  411 + * @Author 钱豹
  412 + * @Date 23:35 2026/6/28
  413 + * @Param [argsNew, session]
  414 + * @return java.util.List<com.xly.entity.ParamRule>
  415 + * @Description 存在动态参数返回提示
  416 + **/
  417 + private String hasDynamicParamRule(Map<String,Object> argsNew,UserSceneSession session,List<ParamRule> dynamicParamRule){
  418 + //获取当前方法
  419 + ToolMeta meta = session.getCurrentTool();
  420 + meta.setDynamicParamRule(dynamicParamRule);
  421 + session.setCurrentTool(meta);
  422 + Map<String, Object> argsOld = session.getArgs();
  423 + Map<String, Object> args = DeepCopyUtils.deepCopy(argsNew);
  424 + if(ObjectUtil.isEmpty(argsOld)){
  425 + argsOld = new HashMap<>();
  426 + }
  427 + argsOld.putAll(args);
  428 + //根据获取的参数获取数据
  429 + List<String> dynamicParamRuleTs = dynamicParamRule.stream().map(ParamRule::getSParam).toList();
  430 + session.setArgs(argsOld);
  431 + String askMsg = buildAskUserMessage(meta, dynamicParamRuleTs,args);
  432 + session.setSFunPrompts(askMsg);
  433 + String sSystemPrompt = buildMissParamPrompt(session,dynamicParamRule);
  434 + session.setSSystemPrompt(sSystemPrompt);
  435 + addSystemMessage(session, askMsg);
  436 + return askMsg;
  437 + }
  438 +
  439 +
241 private void doSetSlaveIdToArgs(Map<String,Object> args,UserSceneSession session){ 440 private void doSetSlaveIdToArgs(Map<String,Object> args,UserSceneSession session){
242 Map<Integer,Map<String,Object>> data = session.getCurrentRowData(); 441 Map<Integer,Map<String,Object>> data = session.getCurrentRowData();
243 List<String> sSlaveIds = new ArrayList<>(); 442 List<String> sSlaveIds = new ArrayList<>();
@@ -335,7 +534,7 @@ public class DynamicToolProvider implements ToolProvider { @@ -335,7 +534,7 @@ public class DynamicToolProvider implements ToolProvider {
335 } 534 }
336 535
337 536
338 - private ToolSpecification buildToolSpecification(ToolMeta meta) { 537 + public ToolSpecification buildToolSpecification(ToolMeta meta) {
339 ToolSpecification.Builder builder = ToolSpecification.builder() 538 ToolSpecification.Builder builder = ToolSpecification.builder()
340 .name(meta.getSMethodNo()); 539 .name(meta.getSMethodNo());
341 540
@@ -373,7 +572,7 @@ public class DynamicToolProvider implements ToolProvider { @@ -373,7 +572,7 @@ public class DynamicToolProvider implements ToolProvider {
373 if (paramDesc == null || paramDesc.isEmpty()) { 572 if (paramDesc == null || paramDesc.isEmpty()) {
374 continue; 573 continue;
375 } 574 }
376 - String sRuleCost = getConstMeg(paramRule); 575 +// String sRuleCost = getConstMeg(paramRule);
377 switch (paramType.toLowerCase()) { 576 switch (paramType.toLowerCase()) {
378 case "string": 577 case "string":
379 schemaBuilder.addStringProperty(paramDesc, paramDesc); 578 schemaBuilder.addStringProperty(paramDesc, paramDesc);
@@ -522,7 +721,6 @@ public class DynamicToolProvider implements ToolProvider { @@ -522,7 +721,6 @@ public class DynamicToolProvider implements ToolProvider {
522 argsOld = new HashMap<>(); 721 argsOld = new HashMap<>();
523 } 722 }
524 Map<String, Object> args = session.getArgs(); 723 Map<String, Object> args = session.getArgs();
525 -  
526 List<String> missing = checkRequiredParams(args, paramRuleDataCheck); 724 List<String> missing = checkRequiredParams(args, paramRuleDataCheck);
527 if (!missing.isEmpty()) { 725 if (!missing.isEmpty()) {
528 String askMsg = buildAskUserMessage(meta, missing,args); 726 String askMsg = buildAskUserMessage(meta, missing,args);
@@ -635,7 +833,7 @@ public class DynamicToolProvider implements ToolProvider { @@ -635,7 +833,7 @@ public class DynamicToolProvider implements ToolProvider {
635 markdown.append("请确认是否执行").append(sName).append("操作?请回复:&emsp;&emsp;").append("**<a href=\"#\" data-action=\"reset\" data-text=\"确认\">确认</a>**").append("&emsp;") 833 markdown.append("请确认是否执行").append(sName).append("操作?请回复:&emsp;&emsp;").append("**<a href=\"#\" data-action=\"reset\" data-text=\"确认\">确认</a>**").append("&emsp;")
636 .append("**<a href=\"#\" data-action=\"reset\" data-text=\"取消\">取消</a>**"); 834 .append("**<a href=\"#\" data-action=\"reset\" data-text=\"取消\">取消</a>**");
637 } 835 }
638 - 836 + //添加参数 中英文
639 private Map<String, Object> transformationArgs(Map<String, Object> args, List<ParamRule> paramDefs) { 837 private Map<String, Object> transformationArgs(Map<String, Object> args, List<ParamRule> paramDefs) {
640 Map<String, Object> result = new HashMap<>(args); 838 Map<String, Object> result = new HashMap<>(args);
641 paramDefs.forEach(pd->{ 839 paramDefs.forEach(pd->{
@@ -643,7 +841,7 @@ public class DynamicToolProvider implements ToolProvider { @@ -643,7 +841,7 @@ public class DynamicToolProvider implements ToolProvider {
643 String sValue = pd.getSParamValue(); 841 String sValue = pd.getSParamValue();
644 Boolean bCheck = result.containsKey(name) && ObjectUtil.isNotEmpty(result.get(name)); 842 Boolean bCheck = result.containsKey(name) && ObjectUtil.isNotEmpty(result.get(name));
645 Boolean bCheck2 = result.containsKey(sValue) && ObjectUtil.isNotEmpty(result.get(sValue)); 843 Boolean bCheck2 = result.containsKey(sValue) && ObjectUtil.isNotEmpty(result.get(sValue));
646 - if (!bCheck2 && bCheck ) { 844 + if (!bCheck2 && bCheck) {
647 result.put(sValue,args.get(name)); 845 result.put(sValue,args.get(name));
648 } 846 }
649 if(RuleCode.CONST.getCode().equals(pd.getSRule()) && ObjectUtil.isNotEmpty(result.get(sValue))){ 847 if(RuleCode.CONST.getCode().equals(pd.getSRule()) && ObjectUtil.isNotEmpty(result.get(sValue))){
@@ -658,7 +856,6 @@ public class DynamicToolProvider implements ToolProvider { @@ -658,7 +856,6 @@ public class DynamicToolProvider implements ToolProvider {
658 }); 856 });
659 return result; 857 return result;
660 } 858 }
661 -  
662 private Map<String, Object> applyValues(Map<String, Object> args, List<ParamRule> paramDefsCheck) { 859 private Map<String, Object> applyValues(Map<String, Object> args, List<ParamRule> paramDefsCheck) {
663 Map<String, Object> result = new HashMap<>(args); 860 Map<String, Object> result = new HashMap<>(args);
664 result = transformationArgs( result, paramDefsCheck); 861 result = transformationArgs( result, paramDefsCheck);
@@ -762,29 +959,45 @@ public class DynamicToolProvider implements ToolProvider { @@ -762,29 +959,45 @@ public class DynamicToolProvider implements ToolProvider {
762 959
763 private List<String> checkRequiredParams(Map<String, Object> args, List<ParamRule> paramDefs) { 960 private List<String> checkRequiredParams(Map<String, Object> args, List<ParamRule> paramDefs) {
764 Map<String,Object> returnMap = transformationArgs( args, paramDefs); 961 Map<String,Object> returnMap = transformationArgs( args, paramDefs);
765 - return paramDefs.stream()  
766 - .filter(pd -> Boolean.TRUE.equals(pd.getBEmpty()) && pd.getBTipModel())  
767 - .filter(pd -> checkMiss( returnMap, pd))  
768 - .map(ParamRule::getSParam) 962 + List<ParamRule> paramDefsCheck = paramDefs.stream()
  963 + .filter(pd -> !"sDynamicPart".equals(pd.getSParamValue())).collect(Collectors.toUnmodifiableList());
  964 + paramDefsCheck = paramDefsCheck.stream()
  965 + .filter(pd -> Boolean.TRUE.equals(pd.getBEmpty()) && pd.getBTipModel()).collect(Collectors.toUnmodifiableList());
  966 + paramDefsCheck = paramDefsCheck.stream()
  967 + .filter(pd -> checkMiss( returnMap, pd)).collect(Collectors.toUnmodifiableList());
  968 + return paramDefsCheck.stream().map(ParamRule::getSParam)
769 .toList(); 969 .toList();
770 } 970 }
771 971
  972 + /***
  973 + * @Author 钱豹
  974 + * @Date 13:53 2026/7/1
  975 + * @Param [returnMap, pd]
  976 + * @return java.lang.Boolean
  977 + * @Description 校验是否参数缺失
  978 + **/
772 private Boolean checkMiss(Map<String,Object> returnMap,ParamRule pd) { 979 private Boolean checkMiss(Map<String,Object> returnMap,ParamRule pd) {
773 if(ObjectUtil.isEmpty(returnMap)){ 980 if(ObjectUtil.isEmpty(returnMap)){
774 returnMap = new HashMap<>(); 981 returnMap = new HashMap<>();
775 } 982 }
776 - Boolean bBhcs = (ObjectUtil.isEmpty(returnMap.get(pd.getSParam())));  
777 - Boolean bDbZero = false;  
778 - if(pd.getSParamValue().startsWith("d")){  
779 - try{  
780 - String sParam = pd.getSParam().toString();  
781 - Object sParamV = returnMap.get(sParam);  
782 - bDbZero = (ObjectUtil.isEmpty(sParamV) || 0 ==Double.valueOf(sParamV.toString()));  
783 - }catch (Exception e){  
784 - bDbZero = true; 983 + if(pd.getBEmpty()){
  984 + if(pd.getSParamValue().startsWith("d") && returnMap.get(pd.getSParam()) instanceof Number) {
  985 + try {
  986 + String sParam = pd.getSParam().toString();
  987 + Object sParamV = returnMap.get(sParam);
  988 + return (ObjectUtil.isEmpty(sParamV) || 0 == Double.valueOf(sParamV.toString()));
  989 + } catch (Exception e) {
  990 + return true;
  991 + }
  992 + }else{
  993 + try {
  994 + return ObjectUtil.isEmpty(returnMap.get(pd.getSParam())) && ObjectUtil.isEmpty(returnMap.get(pd.getSParamValue()));
  995 + } catch (Exception e) {
  996 + return true;
  997 + }
785 } 998 }
786 } 999 }
787 - return bDbZero || bBhcs || (!returnMap.containsKey(pd.getSParamValue()) || (ObjectUtil.isEmpty(returnMap.get(pd.getSParamValue())))); 1000 + return false;
788 } 1001 }
789 1002
790 /*** 1003 /***
@@ -837,6 +1050,14 @@ public class DynamicToolProvider implements ToolProvider { @@ -837,6 +1050,14 @@ public class DynamicToolProvider implements ToolProvider {
837 return sReturn; 1050 return sReturn;
838 } 1051 }
839 1052
  1053 + //参数进行处理
  1054 + private void doArgs(ToolMeta meta, Map<String, Object> args,List<ParamRule> paramDefs) {
  1055 + List<ParamRule> paramDefsD = paramDefs.stream().filter(one-> ObjectUtil.isNotEmpty(one.getSDynamicParamRuleSql())).collect(Collectors.toUnmodifiableList());
  1056 +
  1057 +
  1058 +
  1059 + }
  1060 +
840 private String executeToolAfter(ToolMeta meta, Map<String, Object> args,List<ParamRule> paramDefs,UserSceneSession session) { 1061 private String executeToolAfter(ToolMeta meta, Map<String, Object> args,List<ParamRule> paramDefs,UserSceneSession session) {
841 String sBizContent = meta.getSBizContent(); 1062 String sBizContent = meta.getSBizContent();
842 Integer iBizType = meta.getIBizType(); 1063 Integer iBizType = meta.getIBizType();
@@ -1297,6 +1518,9 @@ public class DynamicToolProvider implements ToolProvider { @@ -1297,6 +1518,9 @@ public class DynamicToolProvider implements ToolProvider {
1297 StringBuilder sb = new StringBuilder(); 1518 StringBuilder sb = new StringBuilder();
1298 sb.append("缺少参数请补全:\n"); 1519 sb.append("缺少参数请补全:\n");
1299 List<ParamRule> paramRuleData = meta.getParamRuleList(); 1520 List<ParamRule> paramRuleData = meta.getParamRuleList();
  1521 + if(ObjectUtil.isNotEmpty(meta.getDynamicParamRule())){
  1522 + paramRuleData.addAll(meta.getDynamicParamRule());
  1523 + }
1300 for (String name : missing) { 1524 for (String name : missing) {
1301 paramRuleData.stream() 1525 paramRuleData.stream()
1302 .filter(pd -> pd.getSParam().equals(name)) 1526 .filter(pd -> pd.getSParam().equals(name))
src/main/java/com/xly/util/JsonUtils.java
@@ -6,6 +6,7 @@ import com.fasterxml.jackson.databind.type.TypeFactory; @@ -6,6 +6,7 @@ import com.fasterxml.jackson.databind.type.TypeFactory;
6 6
7 import java.io.IOException; 7 import java.io.IOException;
8 import java.util.List; 8 import java.util.List;
  9 +import java.util.Map;
9 10
10 public class JsonUtils { 11 public class JsonUtils {
11 12
@@ -21,7 +22,7 @@ public class JsonUtils { @@ -21,7 +22,7 @@ public class JsonUtils {
21 } 22 }
22 23
23 // JSON字符串转List 24 // JSON字符串转List
24 - public static <T> List<T> toList(String json, Class<T> clazz) { 25 + public static <T> List<T> toList(String json, Class<Map> clazz) {
25 try { 26 try {
26 CollectionType listType = TypeFactory.defaultInstance() 27 CollectionType listType = TypeFactory.defaultInstance()
27 .constructCollectionType(List.class, clazz); 28 .constructCollectionType(List.class, clazz);