Files
archived-gitea-ai-assistant/src/review/tools/file-read-tool.ts
accelerator 6186210b4e feat: 添加工具注册表和代码搜索工具
ToolRegistry统一管理Agent可用工具并转换为OpenAI Function格式;实现代码搜索、文件读取、函数引用搜索三个工具

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-03-01 03:26:47 +00:00

60 lines
2.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { z } from 'zod';
import { Tool } from './types';
import { readFile, realpath } from 'node:fs/promises';
import path from 'node:path';
export function createFileReadTool(): Tool {
return {
name: 'read_file',
description: '读取指定文件的完整内容,用于深入分析代码逻辑。',
parameters: z.object({
file_path: z.string().describe('相对文件路径'),
start_line: z.number().optional().describe('起始行号(可选)'),
end_line: z.number().optional().describe('结束行号(可选)'),
}),
execute: async (params, context) => {
const { file_path, start_line, end_line } = params;
// 安全性规范化路径并验证是否在workspace内
const normalizedPath = path.normalize(file_path).replace(/^(\.\.[\/\\])+/, '');
const fullPath = path.resolve(context.workspacePath, normalizedPath);
try {
// 使用realpath解析完整路径跟随所有符号链接
const realPath = await realpath(fullPath);
const workspaceRealPath = await realpath(context.workspacePath);
// 验证解析后的真实路径必须在workspace目录下
if (!realPath.startsWith(workspaceRealPath + path.sep) && realPath !== workspaceRealPath) {
return {
error: `安全错误:路径 "${file_path}" 解析到workspace外部 (${realPath})`,
path: file_path,
};
}
const content = await readFile(realPath, 'utf-8');
if (start_line !== undefined && end_line !== undefined) {
const lines = content.split('\n');
return {
path: file_path,
content: lines.slice(start_line - 1, end_line).join('\n'),
lines: `${start_line}-${end_line}`,
};
}
return {
path: file_path,
content,
totalLines: content.split('\n').length,
};
} catch (error) {
return {
error: error instanceof Error ? error.message : String(error),
path: file_path,
};
}
},
};
}