diff --git a/src/main/java/com/xly/tool/DynamicToolProvider.java b/src/main/java/com/xly/tool/DynamicToolProvider.java index 7f1e8be..b60dd76 100644 --- a/src/main/java/com/xly/tool/DynamicToolProvider.java +++ b/src/main/java/com/xly/tool/DynamicToolProvider.java @@ -213,6 +213,14 @@ public class DynamicToolProvider implements ToolProvider { // 2.1 【自动补全】应用参数的默认值 List paramRuleData = meta.getParamRuleListAll(); args = applyDefaultValues(args, paramRuleData); + //客户选择行号转sSLaveId + if(ObjectUtil.isNotEmpty(args) + && args.containsKey("rowNumbers") + && ObjectUtil.isNotEmpty(args.get("rowNumbers")) + && ObjectUtil.isNotEmpty(session.getCurrentRowData()) + ){ + doSetSlaveIdToArgs( args, session); + } session.setArgs(args); // 3. 【自动校验】检查必填项 List missing = checkRequiredParams(args, paramRuleData); @@ -229,6 +237,20 @@ public class DynamicToolProvider implements ToolProvider { }; } + private void doSetSlaveIdToArgs(Map args,UserSceneSession session){ + Map> data = session.getCurrentRowData(); + List rowNumbers = (List) args.get("rowNumbers"); + List sSlaveIds = new ArrayList<>(); + rowNumbers.forEach(one->{ + try{ + sSlaveIds.add(data.get(one-1).get("sSlaveId").toString()); + }catch (Exception e){ + } + }); + args.put("sSlaveId",String.join(",",sSlaveIds)); + args.remove("rowNumbers"); + } + private void doSetToolAIshowfieldShow(ToolMeta meta){ String sToolId = meta.getSId(); List paramRuleData = getParamRuleDataAll(); @@ -824,6 +846,10 @@ public class DynamicToolProvider implements ToolProvider { if(ObjectUtil.isEmpty(args.get("sSlaveId"))){ //插入AI记忆 String sMsg = "请选择操作数据"; + Map sessA = session.getArgs(); + sessA.remove("sSlaveId"); + sessA.remove("operateType"); + session.setArgs(sessA); addSystemMessage(session, sMsg); throw new BusinessException(-1,sMsg); } @@ -831,6 +857,10 @@ public class DynamicToolProvider implements ToolProvider { if(ObjectUtil.isEmpty(sRowData)){ String sMsg = "选择的数据ID:"+args.get("sSlaveId")+"不存在,请重新选择。"; session.setSFunPrompts(sMsg); + Map sessA = session.getArgs(); + sessA.remove("sSlaveId"); + sessA.remove("operateType"); + session.setArgs(sessA); //插入AI记忆 addSystemMessage(session, sMsg); throw new BusinessException(-1,sMsg); @@ -1131,37 +1161,74 @@ public class DynamicToolProvider implements ToolProvider { } public String buildDynamicSystemPrompt(UserSceneSession session) { + // 获取当前工具编号(用于 JSON 的 name 字段) String methodNo = session.getCurrentTool().getSMethodNo(); - String rowJson = JSONUtil.toJsonPrettyStr(session.getCurrentRowData()); - return """ - 【极强约束·必须执行】 - 1. 禁止说话!禁止解释! - 2. 必须调用工具! - 3. 只输出标准工具调用JSON! - - 表格数据(key是行号): - %s - - 【规则】 - 用户输入如"第N条数据确认",N为行号。 - 在表格中查找 key = N 的数据,取出 sSlaveId。 - - 【输出格式】 - {"name": "%s", "parameters": {"operateType": "单行确认", "sSlaveId": "取出的ID"}} - - 【输出格式·严格执行】 - 你必须分两步输出: - 1. **思考步骤**:明确写出“用户要求第N行,我在JSON中找到Key为N的数据,其sSlaveId是[完整复制ID]”。 - 2. **JSON步骤**:换行后输出标准的工具调用JSON。 - - 【输出示例】 - 思考:用户要求第3行,我在JSON中找到Key为"3"的数据,其sSlaveId是17782251520001103406038478326300。 - {"name": "queryUnstockedProducts", "parameters": {"operateType": "单行确认", "sSlaveId": "17782251520001103406038478326300"}} - 【警告】 - 思考步骤中的ID必须与JSON中的ID完全一致!禁止编造!必须从表格中提取! - """.formatted(rowJson, methodNo); + 【极强约束·必须执行】 + 1. 禁止说话!禁止解释! + 2. 必须调用工具! + 3. 只输出标准工具调用JSON! + + ### 任务背景 ### + 用户会输入自然语言指令(如“第1行确认”、“全部合并”等)。 + 你的任务是:解析出【操作类型】和【目标行号】。 + + ### 解析规则(必须严格遵守) ### + + 1. **操作类型 (operateType)**: + - 如果用户说“全部确认”、“生成多个单据”,识别为:"全部确认" + - 如果用户说“合并确认”、“生成一个单据”,识别为:"合并确认" + - 其他情况,默认为:"单行确认" + + 2. **行号提取 (rowNumbers)**: + - 单选:如“第5行”,提取为 [5] + - 多选:如“第1、3、5行”,提取为 [1, 3, 5] + - 范围:如“第2到4行”,提取为 [2, 3, 4] + - 全选:如“全部”、“所有”,提取为 ["ALL"] + + ### 输出格式规范 ### + 请直接输出以下 JSON(不要任何 Markdown 格式,不要 ```json): + {"name": "%s", "parameters": {"operateType": "解析出的类型", "rowNumbers": [行号数组或"ALL"]}} + + """.formatted(methodNo); } +// public String buildDynamicSystemPrompt(UserSceneSession session) { +// // 获取当前工具编号 +// String methodNo = session.getCurrentTool().getSMethodNo(); +// // 格式化表格数据(保持缩进,方便模型阅读) +// String rowJson = JSONUtil.toJsonPrettyStr(session.getCurrentRowData()); +// +// return """ +// 【极强约束·必须执行】 +// 1. 禁止说话!禁止解释! +// 2. 必须调用工具! +// 3. 只输出标准工具调用JSON! +// +// ### 任务背景 ### +// 用户会输入类似“第5行确认”或“确认第3条”的指令。 +// 你的任务是:解析行号 -> 在下方表格中找到对应行 -> 提取 sSlaveId -> 调用工具。 +// +// ### 数据源(表格 key 是行号) ### +// %s +// +// ### 防错黄金法则(必须严格遵守) ### +// 1. **查找阶段**:不要凭空编造 ID。必须先在“思考步骤”中明确写出: +// “用户输入是[xx],提取行号[N] -> 查找表格 Key=[N] -> 对应的 sSlaveId 是 [这里填入表格里的完整数字]” +// 2. **复制阶段**:sSlaveId 是一长串数字,请务必**直接复制**表格中的原始值,不要加省略号(...),不要改变数字。 +// 3. **输出阶段**:只有确认复制无误后,才在 JSON 的 sSlaveId 字段中填入该值。 +// +// ### 输出格式规范 ### +// {"name": "%s", "parameters": {"operateType": "单行确认", "sSlaveId": "在这里填入你从表格中复制的ID"}} +// +// ### 执行流程(一步一步来) ### +// 1. **解析**:阅读用户输入,确定他想操作的是第几行(N)。 +// 2. **思考**:在回复的第一行,写出你的查找过程(例如:用户要求第5行...)。 +// 3. **JSON**:换行后,输出最终的工具调用 JSON。 +// +// 【警告】 +// 如果用户要求的行号在表格中不存在,请返回错误信息,不要调用工具。 +// """.formatted(rowJson, methodNo); +// } private List> findFieldNameByChinese(List> sAIshowfieldShow,List> rows){ Map keyMappings = new HashMap<>();