@saber2pr/ai-agent 0.0.68 → 0.0.69

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,10 +4,44 @@ exports.batchRunTools = void 0;
4
4
  const zod_1 = require("zod");
5
5
  const createTool_1 = require("../../utils/createTool");
6
6
  const kit_1 = require("../../utils/kit");
7
+ const formatOutput = (output) => {
8
+ // 1. 处理空值
9
+ if (output === null || output === undefined)
10
+ return String(output);
11
+ // 2. 处理数组 (MCP 常见返回格式)
12
+ if (Array.isArray(output)) {
13
+ // 尝试提取所有 text 类型的 content 并合并,如果不是 MCP 格式则递归处理
14
+ const isMcpStyle = output.every(item => item && typeof item === 'object' && 'type' in item);
15
+ if (isMcpStyle) {
16
+ return output
17
+ .map(item => {
18
+ if (item.type === 'text')
19
+ return item.text;
20
+ if (item.type === 'resource')
21
+ return `[Resource: ${item.resource?.uri}]`;
22
+ return JSON.stringify(item); // 无法识别的 MCP 类型(如 image)保持 JSON
23
+ })
24
+ .join('\n');
25
+ }
26
+ // 普通数组递归处理
27
+ return output.map(item => formatOutput(item)).join('\n');
28
+ }
29
+ // 3. 处理单个对象
30
+ if (typeof output === 'object') {
31
+ // 处理单个 MCP 文本对象
32
+ if (output.type === 'text' && typeof output.text === 'string') {
33
+ return output.text;
34
+ }
35
+ // 其他对象转为格式化 JSON
36
+ return JSON.stringify(output, null, 2);
37
+ }
38
+ // 4. 基本类型直接转 String
39
+ return String(output);
40
+ };
7
41
  exports.batchRunTools = (0, createTool_1.createTool)({
8
42
  name: 'batch_run_tools',
9
43
  // 使用更具指令性的英文描述
10
- description: `Execute multiple tools in parallel. Use this for independent tasks such as reading multiple files, applying unrelated edits to different files, or fetching diagnostics simultaneously. CRITICAL: DO NOT apply multiple edits to the same file within a single batch to avoid write conflicts.`,
44
+ description: `Execute multiple read-only tools in parallel. Such as reading multiple files or fetching diagnostics simultaneously.`,
11
45
  parameters: zod_1.z.object({
12
46
  actions: zod_1.z.array(zod_1.z.object({
13
47
  // 字段名和描述对齐 AI 习惯
@@ -18,6 +52,11 @@ exports.batchRunTools = (0, createTool_1.createTool)({
18
52
  handler: async ({ actions }, context) => {
19
53
  // 1. 获取所有可用工具的映射
20
54
  const toolMap = (0, kit_1.getArray)(context?.allTools).reduce((acc, tool) => ({ ...acc, [tool.function.name]: tool }), {});
55
+ // 2. 预检:拦截并发写入行为
56
+ const writeTools = actions.filter(action => /edit|write|replace|delete/i.test(action.tool_name));
57
+ if (writeTools.length > 0) {
58
+ return `Error: Parallel write operations detected (${writeTools.map(t => t.tool_name).join(', ')}). Batching is ONLY allowed for READ-ONLY operations.`;
59
+ }
21
60
  if (Object.keys(toolMap).length === 0) {
22
61
  return 'Error: Failed to retrieve tool execution context.';
23
62
  }
@@ -49,8 +88,6 @@ exports.batchRunTools = (0, createTool_1.createTool)({
49
88
  };
50
89
  }
51
90
  }));
52
- // 3. 格式化输出结果
53
- // 虽然参数改成了英文,但返回给 AI 的结果标题可以保留清晰的结构
54
- return results.map(res => `### Tool: ${res.tool_name} (${res.status})\n${res.output}\n---`).join('\n');
91
+ return results.map(res => `### Tool: ${res.tool_name} (${res.status})\n${formatOutput(res.output)}\n---`).join('\n');
55
92
  }
56
93
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@saber2pr/ai-agent",
3
- "version": "0.0.68",
3
+ "version": "0.0.69",
4
4
  "description": "AI Assistant CLI.",
5
5
  "author": "saber2pr",
6
6
  "license": "ISC",