feat(core): 优化 read_file 工具参数结构
- 将参数 path 重命名为 file_path - 添加 offset 参数支持从指定行开始读取 - 添加 limit 参数控制读取行数(默认 2000 行) - 输出带行号格式(类似 cat -n) - 大文件时显示剩余行数提示
This commit is contained in:
@@ -5,6 +5,8 @@ import type { ToolWithMetadata } from '../types.js';
|
|||||||
import { loadDescription } from '../load_description.js';
|
import { loadDescription } from '../load_description.js';
|
||||||
import { getPermissionManager } from '../../permission/index.js';
|
import { getPermissionManager } from '../../permission/index.js';
|
||||||
|
|
||||||
|
const DEFAULT_LINE_LIMIT = 2000;
|
||||||
|
|
||||||
export const readFileTool: ToolWithMetadata = {
|
export const readFileTool: ToolWithMetadata = {
|
||||||
name: 'read_file',
|
name: 'read_file',
|
||||||
description: loadDescription('read_file'),
|
description: loadDescription('read_file'),
|
||||||
@@ -16,14 +18,26 @@ export const readFileTool: ToolWithMetadata = {
|
|||||||
deferLoading: false, // 核心工具,始终可用
|
deferLoading: false, // 核心工具,始终可用
|
||||||
},
|
},
|
||||||
parameters: {
|
parameters: {
|
||||||
path: {
|
file_path: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
description: '要读取的文件路径(相对或绝对路径)',
|
description: 'The absolute path to the file to read',
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
offset: {
|
||||||
|
type: 'number',
|
||||||
|
description: 'The line number to start reading from. Only provide if the file is too large to read at once',
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
|
limit: {
|
||||||
|
type: 'number',
|
||||||
|
description: 'The number of lines to read. Only provide if the file is too large to read at once.',
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
execute: async (params: Record<string, unknown>): Promise<ToolResult> => {
|
execute: async (params: Record<string, unknown>): Promise<ToolResult> => {
|
||||||
const filePath = params.path as string;
|
const filePath = params.file_path as string;
|
||||||
|
const offset = (params.offset as number | undefined) ?? 0;
|
||||||
|
const limit = (params.limit as number | undefined) ?? DEFAULT_LINE_LIMIT;
|
||||||
const cwd = process.cwd();
|
const cwd = process.cwd();
|
||||||
const absolutePath = path.isAbsolute(filePath)
|
const absolutePath = path.isAbsolute(filePath)
|
||||||
? filePath
|
? filePath
|
||||||
@@ -54,9 +68,40 @@ export const readFileTool: ToolWithMetadata = {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const content = await fs.readFile(absolutePath, 'utf-8');
|
const content = await fs.readFile(absolutePath, 'utf-8');
|
||||||
|
const lines = content.split('\n');
|
||||||
|
const totalLines = lines.length;
|
||||||
|
|
||||||
|
// 应用 offset 和 limit
|
||||||
|
const startLine = Math.max(0, offset);
|
||||||
|
const endLine = Math.min(totalLines, startLine + limit);
|
||||||
|
const selectedLines = lines.slice(startLine, endLine);
|
||||||
|
|
||||||
|
// 格式化输出(带行号,类似 cat -n)
|
||||||
|
const formattedOutput = selectedLines
|
||||||
|
.map((line, index) => {
|
||||||
|
const lineNumber = startLine + index + 1;
|
||||||
|
return `${String(lineNumber).padStart(6, ' ')}\t${line}`;
|
||||||
|
})
|
||||||
|
.join('\n');
|
||||||
|
|
||||||
|
// 构建元数据
|
||||||
|
const metadata: Record<string, unknown> = {
|
||||||
|
totalLines,
|
||||||
|
startLine: startLine + 1,
|
||||||
|
endLine,
|
||||||
|
linesRead: selectedLines.length,
|
||||||
|
};
|
||||||
|
|
||||||
|
// 如果有更多内容未显示,添加提示
|
||||||
|
let output = formattedOutput;
|
||||||
|
if (endLine < totalLines) {
|
||||||
|
output += `\n\n--- 文件共 ${totalLines} 行,当前显示 ${startLine + 1}-${endLine} 行,还有 ${totalLines - endLine} 行未显示 ---`;
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
output: content,
|
output,
|
||||||
|
metadata,
|
||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return {
|
return {
|
||||||
|
|||||||
Reference in New Issue
Block a user