@ai-zen/agents-sdk 0.7.0 → 0.7.1
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.
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.7.1] - 2026-08-25
|
|
4
|
+
|
|
5
|
+
### 🚀 New Features
|
|
6
|
+
|
|
7
|
+
- **`FindTextTool` (findText) gains three-layer output protection** — prevents search results from blowing up the context window:
|
|
8
|
+
- **`maxMatches`** (default 200) — caps the total number of matches; once reached, scanning stops and the result is marked `truncated`
|
|
9
|
+
- **`maxFileSize`** (default 300KB, aligned with `ReadFileTool`) — files larger than this are **skipped** rather than rejected, so an oversized file doesn't block the whole search
|
|
10
|
+
- **`maxLineLength`** (default 200) — each matched line's `content` and the regex `match` substring are truncated (with a trailing `…`)
|
|
11
|
+
- All three are optional parameters that can be overridden by the caller; when truncated the result returns `{ truncated: true, totalMatches, results }`, while non-truncated results keep the original JSON array shape (backward compatible)
|
|
12
|
+
|
|
3
13
|
## [0.7.0] - 2026-08-14
|
|
4
14
|
|
|
5
15
|
### ⚠️ Breaking
|
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
import * as fsp from "fs/promises";
|
|
2
2
|
import * as path from "path";
|
|
3
3
|
import { SdkCallbackTool } from "../../../runtime/SdkCallbackTool.js";
|
|
4
|
+
/** 默认总匹配数上限 */
|
|
5
|
+
const DEFAULT_MAX_MATCHES = 200;
|
|
6
|
+
/** 默认文件大小上限(字节,与 ReadFileTool 的 300KB 口径一致) */
|
|
7
|
+
const DEFAULT_MAX_FILE_SIZE = 300 * 1024;
|
|
8
|
+
/** 默认行内容/匹配子串截断长度 */
|
|
9
|
+
const DEFAULT_MAX_LINE_LENGTH = 200;
|
|
4
10
|
export class FindTextTool extends SdkCallbackTool {
|
|
5
11
|
function = {
|
|
6
12
|
name: "findText",
|
|
7
|
-
description: "
|
|
13
|
+
description: "查找文本出现的位置,支持普通文本或正则匹配,返回文件名及具体行号、行内容。为避免结果撑爆上下文,默认限制总匹配数、单文件大小与行内容长度,超限会截断并标记 truncated。",
|
|
8
14
|
parameters: {
|
|
9
15
|
type: "object",
|
|
10
16
|
properties: {
|
|
@@ -31,6 +37,18 @@ export class FindTextTool extends SdkCallbackTool {
|
|
|
31
37
|
type: "string",
|
|
32
38
|
},
|
|
33
39
|
},
|
|
40
|
+
maxMatches: {
|
|
41
|
+
type: "number",
|
|
42
|
+
description: "总匹配数上限,默认 200",
|
|
43
|
+
},
|
|
44
|
+
maxFileSize: {
|
|
45
|
+
type: "number",
|
|
46
|
+
description: "单文件大小上限(字节),超过则跳过该文件,默认 307200(300KB)",
|
|
47
|
+
},
|
|
48
|
+
maxLineLength: {
|
|
49
|
+
type: "number",
|
|
50
|
+
description: "行内容与匹配子串的截断长度,默认 200",
|
|
51
|
+
},
|
|
34
52
|
},
|
|
35
53
|
required: ["path", "pattern"],
|
|
36
54
|
},
|
|
@@ -49,48 +67,70 @@ export class FindTextTool extends SdkCallbackTool {
|
|
|
49
67
|
return "请提供 text 或 regex 参数";
|
|
50
68
|
}
|
|
51
69
|
const regex = regexStr ? new RegExp(regexStr) : null;
|
|
70
|
+
const maxMatches = input.maxMatches ?? DEFAULT_MAX_MATCHES;
|
|
71
|
+
const maxFileSize = input.maxFileSize ?? DEFAULT_MAX_FILE_SIZE;
|
|
72
|
+
const maxLineLength = input.maxLineLength ?? DEFAULT_MAX_LINE_LENGTH;
|
|
73
|
+
let totalMatches = 0;
|
|
74
|
+
let truncated = false;
|
|
52
75
|
for await (const file of fsp.glob(input.pattern, {
|
|
53
76
|
cwd,
|
|
54
77
|
exclude: input.exclude || ["**/node_modules/**"],
|
|
55
78
|
})) {
|
|
56
79
|
if (signal?.aborted)
|
|
57
80
|
break; // 中断:停止继续遍历/消费
|
|
81
|
+
if (totalMatches >= maxMatches) {
|
|
82
|
+
truncated = true;
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
58
85
|
const fullPath = path.join(cwd, file);
|
|
59
86
|
const stats = await fsp.stat(fullPath);
|
|
60
87
|
if (signal?.aborted)
|
|
61
88
|
break; // 中断:stat 后再次检查
|
|
62
|
-
if (stats.isFile())
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
89
|
+
if (!stats.isFile())
|
|
90
|
+
continue;
|
|
91
|
+
// 文件过大则跳过(避免撑爆上下文;与 ReadFileTool 300KB 口径一致,但此处为跳过而非报错)
|
|
92
|
+
if (stats.size > maxFileSize)
|
|
93
|
+
continue;
|
|
94
|
+
const content = await fsp.readFile(fullPath, "utf-8");
|
|
95
|
+
if (signal?.aborted)
|
|
96
|
+
break; // 中断:readFile 后再次检查
|
|
97
|
+
const lines = content.split("\n");
|
|
98
|
+
const matches = [];
|
|
99
|
+
for (let index = 0; index < lines.length; index++) {
|
|
100
|
+
if (totalMatches >= maxMatches) {
|
|
101
|
+
truncated = true;
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
const lineContent = lines[index];
|
|
105
|
+
if (regex) {
|
|
106
|
+
const matchResult = lineContent.match(regex);
|
|
107
|
+
if (matchResult) {
|
|
80
108
|
matches.push({
|
|
81
109
|
line: index + 1,
|
|
82
|
-
content: lineContent,
|
|
110
|
+
content: truncate(lineContent, maxLineLength),
|
|
111
|
+
match: truncate(matchResult[0], maxLineLength),
|
|
83
112
|
});
|
|
113
|
+
totalMatches++;
|
|
84
114
|
}
|
|
85
|
-
});
|
|
86
|
-
if (matches.length > 0) {
|
|
87
|
-
result.push({ file, matches });
|
|
88
115
|
}
|
|
116
|
+
else if (lineContent.includes(text)) {
|
|
117
|
+
matches.push({
|
|
118
|
+
line: index + 1,
|
|
119
|
+
content: truncate(lineContent, maxLineLength),
|
|
120
|
+
});
|
|
121
|
+
totalMatches++;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
if (matches.length > 0) {
|
|
125
|
+
result.push({ file, matches });
|
|
89
126
|
}
|
|
90
127
|
}
|
|
91
128
|
if (signal?.aborted) {
|
|
92
129
|
return JSON.stringify({ aborted: true, results: result });
|
|
93
130
|
}
|
|
131
|
+
if (truncated) {
|
|
132
|
+
return JSON.stringify({ truncated: true, totalMatches, results: result });
|
|
133
|
+
}
|
|
94
134
|
return JSON.stringify(result);
|
|
95
135
|
}
|
|
96
136
|
catch (error) {
|
|
@@ -98,3 +138,9 @@ export class FindTextTool extends SdkCallbackTool {
|
|
|
98
138
|
}
|
|
99
139
|
}
|
|
100
140
|
}
|
|
141
|
+
/** 截断字符串到指定长度,超出部分以 "…" 结尾标记 */
|
|
142
|
+
function truncate(s, max) {
|
|
143
|
+
if (s.length <= max)
|
|
144
|
+
return s;
|
|
145
|
+
return s.slice(0, max) + "…";
|
|
146
|
+
}
|