@amical/aiagent-sdk 0.1.9 → 0.1.10
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/dist/index.d.mts +30 -6
- package/dist/index.d.ts +30 -6
- package/dist/index.js +182 -14
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +182 -14
- package/dist/index.mjs.map +1 -1
- package/dist/runtime/nodeRuntime.js +182 -14
- package/dist/runtime/nodeRuntime.js.map +1 -1
- package/dist/runtime/nodeRuntime.mjs +182 -14
- package/dist/runtime/nodeRuntime.mjs.map +1 -1
- package/dist/runtime/webRuntime.js +182 -14
- package/dist/runtime/webRuntime.js.map +1 -1
- package/dist/runtime/webRuntime.mjs +182 -14
- package/dist/runtime/webRuntime.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -21,7 +21,8 @@ interface IAgentRuntime {
|
|
|
21
21
|
* @param filePattern (可选) 文件名匹配模式,比如 '*.ts'
|
|
22
22
|
* @returns 返回格式化后的包含上下文的搜索结果字符串
|
|
23
23
|
*/
|
|
24
|
-
searchFiles?(path: string, regex: string, filePattern?: string): Promise<string>;
|
|
24
|
+
searchFiles?(path: string, regex: string, filePattern?: string, includeNodeModules?: boolean): Promise<string>;
|
|
25
|
+
searchFileContent?(path: string, regex: string, filePattern?: string, includeNodeModules?: boolean): Promise<string>;
|
|
25
26
|
};
|
|
26
27
|
path: {
|
|
27
28
|
join(...paths: string[]): string;
|
|
@@ -59,6 +60,7 @@ declare enum AgentDefaultTool {
|
|
|
59
60
|
FILE_DELETE = "agent_delete_file",
|
|
60
61
|
DIR_DELETE = "agent_delete_directory",
|
|
61
62
|
SEARCH = "agent_search_files",
|
|
63
|
+
SEARCH_CONTENT = "agent_search_file_content",
|
|
62
64
|
LIST_FILES = "agent_list_files",
|
|
63
65
|
LIST_CODE_DEF = "agent_list_code_definition_names",
|
|
64
66
|
BROWSER = "agent_browser_action",
|
|
@@ -137,11 +139,21 @@ declare const defaultTools: readonly [{
|
|
|
137
139
|
};
|
|
138
140
|
}, {
|
|
139
141
|
readonly name: AgentDefaultTool.SEARCH;
|
|
140
|
-
readonly description: "Search for files in a directory
|
|
142
|
+
readonly description: "Search for files or directories by name in a directory tree, matching the name against a regex (and optionally a glob). Directories are traversed level by level: all matches in the current level are returned before descending into deeper levels. Use this tool only to locate files/directories by name.";
|
|
141
143
|
readonly params: {
|
|
142
144
|
readonly path: "(required) The absolute or relative directory path to search.";
|
|
143
|
-
readonly regex: "(required) The regex pattern to match
|
|
145
|
+
readonly regex: "(required) The regex pattern to match file or directory names against.";
|
|
144
146
|
readonly file_pattern: "(optional) glob pattern like *.ts.";
|
|
147
|
+
readonly include_node_modules: "(optional) set to true to include node_modules in the search. Defaults to false, so node_modules is skipped.";
|
|
148
|
+
};
|
|
149
|
+
}, {
|
|
150
|
+
readonly name: AgentDefaultTool.SEARCH_CONTENT;
|
|
151
|
+
readonly description: "Search the contents of files in a directory tree for a regex pattern. Use this tool when you need to find text or code inside files rather than matching file or directory names.";
|
|
152
|
+
readonly params: {
|
|
153
|
+
readonly path: "(required) The absolute or relative directory path to search.";
|
|
154
|
+
readonly regex: "(required) The regex pattern to match file content against.";
|
|
155
|
+
readonly file_pattern: "(optional) glob pattern like *.ts to limit which files are searched.";
|
|
156
|
+
readonly include_node_modules: "(optional) set to true to include node_modules in the search. Defaults to false, so node_modules is skipped.";
|
|
145
157
|
};
|
|
146
158
|
}, {
|
|
147
159
|
readonly name: AgentDefaultTool.LIST_FILES;
|
|
@@ -166,7 +178,7 @@ declare const defaultTools: readonly [{
|
|
|
166
178
|
declare const toolUseNames: AgentDefaultTool[];
|
|
167
179
|
declare function setDynamicToolUseNames(namespace: string, names: string[]): void;
|
|
168
180
|
declare function getToolUseNames(): string[];
|
|
169
|
-
declare const READ_ONLY_TOOLS: readonly [AgentDefaultTool.LIST_FILES, AgentDefaultTool.FILE_READ, AgentDefaultTool.SEARCH, AgentDefaultTool.LIST_CODE_DEF, AgentDefaultTool.BROWSER, AgentDefaultTool.ASK, AgentDefaultTool.WEB_SEARCH, AgentDefaultTool.WEB_FETCH, AgentDefaultTool.LOAD_SKILL, AgentDefaultTool.USE_SUBAGENTS];
|
|
181
|
+
declare const READ_ONLY_TOOLS: readonly [AgentDefaultTool.LIST_FILES, AgentDefaultTool.FILE_READ, AgentDefaultTool.SEARCH, AgentDefaultTool.SEARCH_CONTENT, AgentDefaultTool.LIST_CODE_DEF, AgentDefaultTool.BROWSER, AgentDefaultTool.ASK, AgentDefaultTool.WEB_SEARCH, AgentDefaultTool.WEB_FETCH, AgentDefaultTool.LOAD_SKILL, AgentDefaultTool.USE_SUBAGENTS];
|
|
170
182
|
|
|
171
183
|
/**
|
|
172
184
|
* @description **Version 2**
|
|
@@ -198,7 +210,7 @@ interface TextStreamContent {
|
|
|
198
210
|
content: string;
|
|
199
211
|
partial: boolean;
|
|
200
212
|
}
|
|
201
|
-
declare const toolParamNames: readonly ["command", "requires_approval", "path", "absolutePath", "content", "diff", "regex", "file_pattern", "recursive", "action", "url", "coordinate", "text", "query", "allowed_domains", "blocked_domains", "prompt", "server_name", "tool_name", "arguments", "uri", "question", "options", "response", "result", "context", "title", "what_happened", "steps_to_reproduce", "api_request_output", "additional_context", "needs_more_exploration", "task_progress", "timeout", "input", "from_ref", "to_ref", "skill_name", "prompt_1", "prompt_2", "prompt_3", "prompt_4", "prompt_5", "start_line", "end_line"];
|
|
213
|
+
declare const toolParamNames: readonly ["command", "requires_approval", "path", "absolutePath", "content", "diff", "regex", "file_pattern", "include_node_modules", "recursive", "action", "url", "coordinate", "text", "query", "allowed_domains", "blocked_domains", "prompt", "server_name", "tool_name", "arguments", "uri", "question", "options", "response", "result", "context", "title", "what_happened", "steps_to_reproduce", "api_request_output", "additional_context", "needs_more_exploration", "task_progress", "timeout", "input", "from_ref", "to_ref", "skill_name", "prompt_1", "prompt_2", "prompt_3", "prompt_4", "prompt_5", "start_line", "end_line"];
|
|
202
214
|
type ToolParamName = (typeof toolParamNames)[number];
|
|
203
215
|
interface ToolUse {
|
|
204
216
|
type: "tool_use";
|
|
@@ -484,7 +496,19 @@ declare class ClineAgent {
|
|
|
484
496
|
resume(userInput?: string): Promise<void>;
|
|
485
497
|
appendHistory(history: AgentMessage[]): Promise<void>;
|
|
486
498
|
getHistory(): Promise<AgentMessage[]>;
|
|
487
|
-
|
|
499
|
+
/**
|
|
500
|
+
* 判断文件是否为可进行内容搜索的文本类文件
|
|
501
|
+
*/
|
|
502
|
+
private isTextFile;
|
|
503
|
+
/**
|
|
504
|
+
* 按文件名/目录名搜索,层级优先(BFS):
|
|
505
|
+
* 每一层先匹配完当前层级的所有条目,再进入更深的子目录。
|
|
506
|
+
*/
|
|
507
|
+
searchFiles(dirpath: string, regex: string, filePattern?: string, includeNodeModules?: boolean): Promise<string>;
|
|
508
|
+
/**
|
|
509
|
+
* 按文件内容搜索:正则匹配文件内容,返回匹配文件路径。
|
|
510
|
+
*/
|
|
511
|
+
searchFileContent(dirpath: string, regex: string, filePattern?: string, includeNodeModules?: boolean): Promise<string>;
|
|
488
512
|
}
|
|
489
513
|
|
|
490
514
|
declare const VERSION = "0.1.0";
|
package/dist/index.d.ts
CHANGED
|
@@ -21,7 +21,8 @@ interface IAgentRuntime {
|
|
|
21
21
|
* @param filePattern (可选) 文件名匹配模式,比如 '*.ts'
|
|
22
22
|
* @returns 返回格式化后的包含上下文的搜索结果字符串
|
|
23
23
|
*/
|
|
24
|
-
searchFiles?(path: string, regex: string, filePattern?: string): Promise<string>;
|
|
24
|
+
searchFiles?(path: string, regex: string, filePattern?: string, includeNodeModules?: boolean): Promise<string>;
|
|
25
|
+
searchFileContent?(path: string, regex: string, filePattern?: string, includeNodeModules?: boolean): Promise<string>;
|
|
25
26
|
};
|
|
26
27
|
path: {
|
|
27
28
|
join(...paths: string[]): string;
|
|
@@ -59,6 +60,7 @@ declare enum AgentDefaultTool {
|
|
|
59
60
|
FILE_DELETE = "agent_delete_file",
|
|
60
61
|
DIR_DELETE = "agent_delete_directory",
|
|
61
62
|
SEARCH = "agent_search_files",
|
|
63
|
+
SEARCH_CONTENT = "agent_search_file_content",
|
|
62
64
|
LIST_FILES = "agent_list_files",
|
|
63
65
|
LIST_CODE_DEF = "agent_list_code_definition_names",
|
|
64
66
|
BROWSER = "agent_browser_action",
|
|
@@ -137,11 +139,21 @@ declare const defaultTools: readonly [{
|
|
|
137
139
|
};
|
|
138
140
|
}, {
|
|
139
141
|
readonly name: AgentDefaultTool.SEARCH;
|
|
140
|
-
readonly description: "Search for files in a directory
|
|
142
|
+
readonly description: "Search for files or directories by name in a directory tree, matching the name against a regex (and optionally a glob). Directories are traversed level by level: all matches in the current level are returned before descending into deeper levels. Use this tool only to locate files/directories by name.";
|
|
141
143
|
readonly params: {
|
|
142
144
|
readonly path: "(required) The absolute or relative directory path to search.";
|
|
143
|
-
readonly regex: "(required) The regex pattern to match
|
|
145
|
+
readonly regex: "(required) The regex pattern to match file or directory names against.";
|
|
144
146
|
readonly file_pattern: "(optional) glob pattern like *.ts.";
|
|
147
|
+
readonly include_node_modules: "(optional) set to true to include node_modules in the search. Defaults to false, so node_modules is skipped.";
|
|
148
|
+
};
|
|
149
|
+
}, {
|
|
150
|
+
readonly name: AgentDefaultTool.SEARCH_CONTENT;
|
|
151
|
+
readonly description: "Search the contents of files in a directory tree for a regex pattern. Use this tool when you need to find text or code inside files rather than matching file or directory names.";
|
|
152
|
+
readonly params: {
|
|
153
|
+
readonly path: "(required) The absolute or relative directory path to search.";
|
|
154
|
+
readonly regex: "(required) The regex pattern to match file content against.";
|
|
155
|
+
readonly file_pattern: "(optional) glob pattern like *.ts to limit which files are searched.";
|
|
156
|
+
readonly include_node_modules: "(optional) set to true to include node_modules in the search. Defaults to false, so node_modules is skipped.";
|
|
145
157
|
};
|
|
146
158
|
}, {
|
|
147
159
|
readonly name: AgentDefaultTool.LIST_FILES;
|
|
@@ -166,7 +178,7 @@ declare const defaultTools: readonly [{
|
|
|
166
178
|
declare const toolUseNames: AgentDefaultTool[];
|
|
167
179
|
declare function setDynamicToolUseNames(namespace: string, names: string[]): void;
|
|
168
180
|
declare function getToolUseNames(): string[];
|
|
169
|
-
declare const READ_ONLY_TOOLS: readonly [AgentDefaultTool.LIST_FILES, AgentDefaultTool.FILE_READ, AgentDefaultTool.SEARCH, AgentDefaultTool.LIST_CODE_DEF, AgentDefaultTool.BROWSER, AgentDefaultTool.ASK, AgentDefaultTool.WEB_SEARCH, AgentDefaultTool.WEB_FETCH, AgentDefaultTool.LOAD_SKILL, AgentDefaultTool.USE_SUBAGENTS];
|
|
181
|
+
declare const READ_ONLY_TOOLS: readonly [AgentDefaultTool.LIST_FILES, AgentDefaultTool.FILE_READ, AgentDefaultTool.SEARCH, AgentDefaultTool.SEARCH_CONTENT, AgentDefaultTool.LIST_CODE_DEF, AgentDefaultTool.BROWSER, AgentDefaultTool.ASK, AgentDefaultTool.WEB_SEARCH, AgentDefaultTool.WEB_FETCH, AgentDefaultTool.LOAD_SKILL, AgentDefaultTool.USE_SUBAGENTS];
|
|
170
182
|
|
|
171
183
|
/**
|
|
172
184
|
* @description **Version 2**
|
|
@@ -198,7 +210,7 @@ interface TextStreamContent {
|
|
|
198
210
|
content: string;
|
|
199
211
|
partial: boolean;
|
|
200
212
|
}
|
|
201
|
-
declare const toolParamNames: readonly ["command", "requires_approval", "path", "absolutePath", "content", "diff", "regex", "file_pattern", "recursive", "action", "url", "coordinate", "text", "query", "allowed_domains", "blocked_domains", "prompt", "server_name", "tool_name", "arguments", "uri", "question", "options", "response", "result", "context", "title", "what_happened", "steps_to_reproduce", "api_request_output", "additional_context", "needs_more_exploration", "task_progress", "timeout", "input", "from_ref", "to_ref", "skill_name", "prompt_1", "prompt_2", "prompt_3", "prompt_4", "prompt_5", "start_line", "end_line"];
|
|
213
|
+
declare const toolParamNames: readonly ["command", "requires_approval", "path", "absolutePath", "content", "diff", "regex", "file_pattern", "include_node_modules", "recursive", "action", "url", "coordinate", "text", "query", "allowed_domains", "blocked_domains", "prompt", "server_name", "tool_name", "arguments", "uri", "question", "options", "response", "result", "context", "title", "what_happened", "steps_to_reproduce", "api_request_output", "additional_context", "needs_more_exploration", "task_progress", "timeout", "input", "from_ref", "to_ref", "skill_name", "prompt_1", "prompt_2", "prompt_3", "prompt_4", "prompt_5", "start_line", "end_line"];
|
|
202
214
|
type ToolParamName = (typeof toolParamNames)[number];
|
|
203
215
|
interface ToolUse {
|
|
204
216
|
type: "tool_use";
|
|
@@ -484,7 +496,19 @@ declare class ClineAgent {
|
|
|
484
496
|
resume(userInput?: string): Promise<void>;
|
|
485
497
|
appendHistory(history: AgentMessage[]): Promise<void>;
|
|
486
498
|
getHistory(): Promise<AgentMessage[]>;
|
|
487
|
-
|
|
499
|
+
/**
|
|
500
|
+
* 判断文件是否为可进行内容搜索的文本类文件
|
|
501
|
+
*/
|
|
502
|
+
private isTextFile;
|
|
503
|
+
/**
|
|
504
|
+
* 按文件名/目录名搜索,层级优先(BFS):
|
|
505
|
+
* 每一层先匹配完当前层级的所有条目,再进入更深的子目录。
|
|
506
|
+
*/
|
|
507
|
+
searchFiles(dirpath: string, regex: string, filePattern?: string, includeNodeModules?: boolean): Promise<string>;
|
|
508
|
+
/**
|
|
509
|
+
* 按文件内容搜索:正则匹配文件内容,返回匹配文件路径。
|
|
510
|
+
*/
|
|
511
|
+
searchFileContent(dirpath: string, regex: string, filePattern?: string, includeNodeModules?: boolean): Promise<string>;
|
|
488
512
|
}
|
|
489
513
|
|
|
490
514
|
declare const VERSION = "0.1.0";
|
package/dist/index.js
CHANGED
|
@@ -18,6 +18,7 @@ var AgentDefaultTool = /* @__PURE__ */ ((AgentDefaultTool2) => {
|
|
|
18
18
|
AgentDefaultTool2["FILE_DELETE"] = "agent_delete_file";
|
|
19
19
|
AgentDefaultTool2["DIR_DELETE"] = "agent_delete_directory";
|
|
20
20
|
AgentDefaultTool2["SEARCH"] = "agent_search_files";
|
|
21
|
+
AgentDefaultTool2["SEARCH_CONTENT"] = "agent_search_file_content";
|
|
21
22
|
AgentDefaultTool2["LIST_FILES"] = "agent_list_files";
|
|
22
23
|
AgentDefaultTool2["LIST_CODE_DEF"] = "agent_list_code_definition_names";
|
|
23
24
|
AgentDefaultTool2["BROWSER"] = "agent_browser_action";
|
|
@@ -191,11 +192,22 @@ return (
|
|
|
191
192
|
},
|
|
192
193
|
{
|
|
193
194
|
name: "agent_search_files" /* SEARCH */,
|
|
194
|
-
description: "Search for files in a directory
|
|
195
|
+
description: "Search for files or directories by name in a directory tree, matching the name against a regex (and optionally a glob). Directories are traversed level by level: all matches in the current level are returned before descending into deeper levels. Use this tool only to locate files/directories by name.",
|
|
195
196
|
params: {
|
|
196
197
|
path: "(required) The absolute or relative directory path to search.",
|
|
197
|
-
regex: "(required) The regex pattern to match
|
|
198
|
-
file_pattern: "(optional) glob pattern like *.ts."
|
|
198
|
+
regex: "(required) The regex pattern to match file or directory names against.",
|
|
199
|
+
file_pattern: "(optional) glob pattern like *.ts.",
|
|
200
|
+
include_node_modules: "(optional) set to true to include node_modules in the search. Defaults to false, so node_modules is skipped."
|
|
201
|
+
}
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
name: "agent_search_file_content" /* SEARCH_CONTENT */,
|
|
205
|
+
description: "Search the contents of files in a directory tree for a regex pattern. Use this tool when you need to find text or code inside files rather than matching file or directory names.",
|
|
206
|
+
params: {
|
|
207
|
+
path: "(required) The absolute or relative directory path to search.",
|
|
208
|
+
regex: "(required) The regex pattern to match file content against.",
|
|
209
|
+
file_pattern: "(optional) glob pattern like *.ts to limit which files are searched.",
|
|
210
|
+
include_node_modules: "(optional) set to true to include node_modules in the search. Defaults to false, so node_modules is skipped."
|
|
199
211
|
}
|
|
200
212
|
},
|
|
201
213
|
{
|
|
@@ -264,6 +276,7 @@ var READ_ONLY_TOOLS = [
|
|
|
264
276
|
"agent_list_files" /* LIST_FILES */,
|
|
265
277
|
"agent_read_file" /* FILE_READ */,
|
|
266
278
|
"agent_search_files" /* SEARCH */,
|
|
279
|
+
"agent_search_file_content" /* SEARCH_CONTENT */,
|
|
267
280
|
"agent_list_code_definition_names" /* LIST_CODE_DEF */,
|
|
268
281
|
"agent_browser_action" /* BROWSER */,
|
|
269
282
|
"agent_ask_followup_question" /* ASK */,
|
|
@@ -433,6 +446,7 @@ var toolParamNames = [
|
|
|
433
446
|
"diff",
|
|
434
447
|
"regex",
|
|
435
448
|
"file_pattern",
|
|
449
|
+
"include_node_modules",
|
|
436
450
|
"recursive",
|
|
437
451
|
"action",
|
|
438
452
|
"url",
|
|
@@ -471,6 +485,66 @@ var toolParamNames = [
|
|
|
471
485
|
"start_line",
|
|
472
486
|
"end_line"
|
|
473
487
|
];
|
|
488
|
+
var TEXT_FILE_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
489
|
+
"txt",
|
|
490
|
+
"md",
|
|
491
|
+
"markdown",
|
|
492
|
+
"json",
|
|
493
|
+
"js",
|
|
494
|
+
"mjs",
|
|
495
|
+
"cjs",
|
|
496
|
+
"ts",
|
|
497
|
+
"tsx",
|
|
498
|
+
"jsx",
|
|
499
|
+
"html",
|
|
500
|
+
"htm",
|
|
501
|
+
"css",
|
|
502
|
+
"scss",
|
|
503
|
+
"sass",
|
|
504
|
+
"less",
|
|
505
|
+
"py",
|
|
506
|
+
"java",
|
|
507
|
+
"c",
|
|
508
|
+
"cpp",
|
|
509
|
+
"cc",
|
|
510
|
+
"cxx",
|
|
511
|
+
"h",
|
|
512
|
+
"hpp",
|
|
513
|
+
"cs",
|
|
514
|
+
"go",
|
|
515
|
+
"rs",
|
|
516
|
+
"rb",
|
|
517
|
+
"php",
|
|
518
|
+
"sh",
|
|
519
|
+
"bash",
|
|
520
|
+
"zsh",
|
|
521
|
+
"bat",
|
|
522
|
+
"cmd",
|
|
523
|
+
"ps1",
|
|
524
|
+
"yaml",
|
|
525
|
+
"yml",
|
|
526
|
+
"toml",
|
|
527
|
+
"ini",
|
|
528
|
+
"cfg",
|
|
529
|
+
"conf",
|
|
530
|
+
"xml",
|
|
531
|
+
"svg",
|
|
532
|
+
"csv",
|
|
533
|
+
"log",
|
|
534
|
+
"sql",
|
|
535
|
+
"vue",
|
|
536
|
+
"svelte",
|
|
537
|
+
"astro",
|
|
538
|
+
"graphql",
|
|
539
|
+
"gql",
|
|
540
|
+
"prisma",
|
|
541
|
+
"env",
|
|
542
|
+
"gitignore",
|
|
543
|
+
"dockerfile",
|
|
544
|
+
"makefile",
|
|
545
|
+
"properties",
|
|
546
|
+
"lock"
|
|
547
|
+
]);
|
|
474
548
|
var AgentState = /* @__PURE__ */ ((AgentState2) => {
|
|
475
549
|
AgentState2["IDLE"] = "idle";
|
|
476
550
|
AgentState2["THINKING"] = "thinking";
|
|
@@ -826,15 +900,36 @@ STDERR: ${result.stderr}` });
|
|
|
826
900
|
const path = tool.params.path || this.runtime.env.cwd();
|
|
827
901
|
const regexStr = tool.params.regex;
|
|
828
902
|
const filePattern = tool.params.file_pattern;
|
|
903
|
+
const includeNodeModules = tool.params.include_node_modules === "true";
|
|
829
904
|
if (regexStr && path) {
|
|
830
905
|
try {
|
|
831
906
|
let result;
|
|
832
907
|
if (typeof this.runtime.fs.searchFiles === "function") {
|
|
833
908
|
result = await this.runtime.fs.searchFiles(path, regexStr, filePattern);
|
|
834
909
|
} else {
|
|
835
|
-
result = await this.searchFiles(path, regexStr, filePattern);
|
|
910
|
+
result = await this.searchFiles(path, regexStr, filePattern, includeNodeModules);
|
|
911
|
+
}
|
|
912
|
+
toolResults.push({ tool, result });
|
|
913
|
+
} catch (e) {
|
|
914
|
+
toolResults.push({ tool, result: `Error: ${e.message}` });
|
|
915
|
+
}
|
|
916
|
+
} else {
|
|
917
|
+
toolResults.push({ tool, result: `Error: miss path or regex params` });
|
|
918
|
+
}
|
|
919
|
+
} else if (tool.name === "agent_search_file_content" /* SEARCH_CONTENT */) {
|
|
920
|
+
const path = tool.params.path || this.runtime.env.cwd();
|
|
921
|
+
const regexStr = tool.params.regex;
|
|
922
|
+
const filePattern = tool.params.file_pattern;
|
|
923
|
+
const includeNodeModules = tool.params.include_node_modules === "true";
|
|
924
|
+
if (regexStr && path) {
|
|
925
|
+
try {
|
|
926
|
+
let result;
|
|
927
|
+
if (typeof this.runtime.fs.searchFileContent === "function") {
|
|
928
|
+
result = await this.runtime.fs.searchFileContent(path, regexStr, filePattern);
|
|
929
|
+
} else {
|
|
930
|
+
result = await this.searchFileContent(path, regexStr, filePattern, includeNodeModules);
|
|
836
931
|
}
|
|
837
|
-
toolResults.push({ tool, result
|
|
932
|
+
toolResults.push({ tool, result });
|
|
838
933
|
} catch (e) {
|
|
839
934
|
toolResults.push({ tool, result: `Error: ${e.message}` });
|
|
840
935
|
}
|
|
@@ -1009,13 +1104,80 @@ ${searchBlock.substring(0, 100)}...`);
|
|
|
1009
1104
|
async getHistory() {
|
|
1010
1105
|
return this.memory.getHistory();
|
|
1011
1106
|
}
|
|
1012
|
-
|
|
1107
|
+
/**
|
|
1108
|
+
* 判断文件是否为可进行内容搜索的文本类文件
|
|
1109
|
+
*/
|
|
1110
|
+
isTextFile(name) {
|
|
1111
|
+
const ext = name.includes(".") ? String(name.split(".").pop()).toLowerCase() : "";
|
|
1112
|
+
if (!ext) {
|
|
1113
|
+
return true;
|
|
1114
|
+
}
|
|
1115
|
+
return TEXT_FILE_EXTENSIONS.has(ext);
|
|
1116
|
+
}
|
|
1117
|
+
/**
|
|
1118
|
+
* 按文件名/目录名搜索,层级优先(BFS):
|
|
1119
|
+
* 每一层先匹配完当前层级的所有条目,再进入更深的子目录。
|
|
1120
|
+
*/
|
|
1121
|
+
async searchFiles(dirpath, regex, filePattern, includeNodeModules = false) {
|
|
1013
1122
|
const matches = [];
|
|
1014
|
-
const
|
|
1015
|
-
const
|
|
1123
|
+
const MAX_RESULTS = 100;
|
|
1124
|
+
const MAX_DEPTH = 8;
|
|
1016
1125
|
const SKIP_DIRS = /* @__PURE__ */ new Set([".git", "dist", ".agent", ".turbopack"]);
|
|
1126
|
+
const shouldSkipDir = (name) => SKIP_DIRS.has(name) || name === "node_modules" && !includeNodeModules;
|
|
1127
|
+
const nameRe = new RegExp(regex);
|
|
1128
|
+
const globRe = filePattern ? new RegExp(filePattern.replace(/\./g, "\\.").replace(/\*/g, ".*")) : null;
|
|
1129
|
+
const queue = [{ dir: dirpath, depth: 0 }];
|
|
1130
|
+
while (queue.length > 0 && matches.length < MAX_RESULTS) {
|
|
1131
|
+
const { dir, depth } = queue.shift();
|
|
1132
|
+
if (depth > MAX_DEPTH) {
|
|
1133
|
+
continue;
|
|
1134
|
+
}
|
|
1135
|
+
let entries;
|
|
1136
|
+
try {
|
|
1137
|
+
entries = await this.runtime.fs.readDir(dir, { recursive: false });
|
|
1138
|
+
} catch {
|
|
1139
|
+
continue;
|
|
1140
|
+
}
|
|
1141
|
+
for (const entry of entries) {
|
|
1142
|
+
if (matches.length >= MAX_RESULTS) {
|
|
1143
|
+
break;
|
|
1144
|
+
}
|
|
1145
|
+
const child = dir === "." ? entry.name : `${dir}/${entry.name}`;
|
|
1146
|
+
if (entry.isDirectory()) {
|
|
1147
|
+
if (!shouldSkipDir(entry.name)) {
|
|
1148
|
+
if (nameRe.test(entry.name)) {
|
|
1149
|
+
matches.push(`${child}/`);
|
|
1150
|
+
}
|
|
1151
|
+
queue.push({ dir: child, depth: depth + 1 });
|
|
1152
|
+
}
|
|
1153
|
+
} else if (entry.isFile()) {
|
|
1154
|
+
if (globRe && !globRe.test(entry.name)) {
|
|
1155
|
+
continue;
|
|
1156
|
+
}
|
|
1157
|
+
if (nameRe.test(entry.name)) {
|
|
1158
|
+
matches.push(child);
|
|
1159
|
+
}
|
|
1160
|
+
}
|
|
1161
|
+
}
|
|
1162
|
+
}
|
|
1163
|
+
if (matches.length === 0) {
|
|
1164
|
+
return "No files found.";
|
|
1165
|
+
}
|
|
1166
|
+
return matches.join("\n");
|
|
1167
|
+
}
|
|
1168
|
+
/**
|
|
1169
|
+
* 按文件内容搜索:正则匹配文件内容,返回匹配文件路径。
|
|
1170
|
+
*/
|
|
1171
|
+
async searchFileContent(dirpath, regex, filePattern, includeNodeModules = false) {
|
|
1172
|
+
const matches = [];
|
|
1173
|
+
const MAX_RESULTS = 100;
|
|
1174
|
+
const MAX_DEPTH = 8;
|
|
1175
|
+
const SKIP_DIRS = /* @__PURE__ */ new Set([".git", "dist", ".agent", ".turbopack"]);
|
|
1176
|
+
const shouldSkipDir = (name) => SKIP_DIRS.has(name) || name === "node_modules" && !includeNodeModules;
|
|
1177
|
+
const contentRe = new RegExp(regex);
|
|
1178
|
+
const globRe = filePattern ? new RegExp(filePattern.replace(/\./g, "\\.").replace(/\*/g, ".*")) : null;
|
|
1017
1179
|
const walk = async (dir, depth) => {
|
|
1018
|
-
if (depth >
|
|
1180
|
+
if (depth > MAX_DEPTH || matches.length >= MAX_RESULTS) {
|
|
1019
1181
|
return;
|
|
1020
1182
|
}
|
|
1021
1183
|
let entries;
|
|
@@ -1025,21 +1187,24 @@ ${searchBlock.substring(0, 100)}...`);
|
|
|
1025
1187
|
return;
|
|
1026
1188
|
}
|
|
1027
1189
|
for (const entry of entries) {
|
|
1028
|
-
if (matches.length >=
|
|
1190
|
+
if (matches.length >= MAX_RESULTS) {
|
|
1029
1191
|
break;
|
|
1030
1192
|
}
|
|
1031
1193
|
const child = dir === "." ? entry.name : `${dir}/${entry.name}`;
|
|
1032
1194
|
if (entry.isDirectory()) {
|
|
1033
|
-
if (!
|
|
1195
|
+
if (!shouldSkipDir(entry.name)) {
|
|
1034
1196
|
await walk(child, depth + 1);
|
|
1035
1197
|
}
|
|
1036
1198
|
} else if (entry.isFile()) {
|
|
1037
|
-
if (
|
|
1199
|
+
if (!this.isTextFile(entry.name)) {
|
|
1200
|
+
continue;
|
|
1201
|
+
}
|
|
1202
|
+
if (globRe && !globRe.test(entry.name)) {
|
|
1038
1203
|
continue;
|
|
1039
1204
|
}
|
|
1040
1205
|
try {
|
|
1041
|
-
const content =
|
|
1042
|
-
if (contentRe.test(content)) {
|
|
1206
|
+
const content = await this.runtime.fs.readFile(child);
|
|
1207
|
+
if (typeof content === "string" && contentRe.test(content)) {
|
|
1043
1208
|
matches.push(child);
|
|
1044
1209
|
}
|
|
1045
1210
|
} catch {
|
|
@@ -1048,6 +1213,9 @@ ${searchBlock.substring(0, 100)}...`);
|
|
|
1048
1213
|
}
|
|
1049
1214
|
};
|
|
1050
1215
|
await walk(dirpath, 0);
|
|
1216
|
+
if (matches.length === 0) {
|
|
1217
|
+
return "No files found with matching content.";
|
|
1218
|
+
}
|
|
1051
1219
|
return matches.join("\n");
|
|
1052
1220
|
}
|
|
1053
1221
|
};
|