Commit 1b14dc87d2f4dfee2c2e292385a93f01dada515b
1 parent
834944fa
添加未清选择 改成动态引导语
Showing
7 changed files
with
331 additions
and
38 deletions
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("操作?请回复:  ").append("**<a href=\"#\" data-action=\"reset\" data-text=\"确认\">确认</a>**").append(" ") | 833 | markdown.append("请确认是否执行").append(sName).append("操作?请回复:  ").append("**<a href=\"#\" data-action=\"reset\" data-text=\"确认\">确认</a>**").append(" ") |
| 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); |