UNPKG

contaigents

Version:

Modular AI Content Ecosystem with Audio Generation

151 lines (146 loc) 5.67 kB
import { BaseTool } from './BaseTool.js'; import { FileService } from '../fileService.js'; export class FileReadLinesTool extends BaseTool { constructor(baseDir) { super(); this.fileService = new FileService(baseDir); } getName() { return 'file_read_lines'; } getDescription() { return 'Read specific lines or line ranges from a file. More efficient than reading entire files when you only need specific sections. Supports single lines, ranges, and multiple line selections.'; } getAgentGuidance() { return ` ## 📖 FILE READ LINES BEST PRACTICES ### 🎯 WHEN TO USE: - **Precise reading**: Read specific functions, classes, or code blocks - **Context-aware editing**: Read around areas you plan to modify - **Large file handling**: Avoid loading entire large files into memory - **Follow-up to search**: Read specific lines found by file_search tool ### 📝 LINE SPECIFICATION: - **Single line**: line_start=10, line_end=10 (or just line_start=10) - **Range**: line_start=10, line_end=20 - **From line to end**: line_start=10, line_end=-1 - **First N lines**: line_start=1, line_end=N ### 💡 OPTIMIZATION TIPS: - Use after file_search to read specific areas - Combine with file_write_lines for precise editing - Use line ranges for reading entire functions or classes - Check total_lines to understand file size ### 🚀 COMMON PATTERNS: - Read function: Use search to find, then read_lines for full function - Read imports: line_start=1, line_end=20 (typically at top) - Read specific error: Use search result line numbers `; } getParameters() { return [ { name: 'file_path', type: 'string', description: 'Path to the file to read (relative to project root)', required: true }, { name: 'line_start', type: 'number', description: 'Starting line number (1-based, inclusive)', required: true }, { name: 'line_end', type: 'number', description: 'Ending line number (1-based, inclusive). Use -1 for end of file. If omitted, reads only line_start.', required: false }, { name: 'include_line_numbers', type: 'boolean', description: 'Whether to include line numbers in the output (default: true)', required: false, default: true } ]; } async execute(parameters) { // Validate parameters const validationError = this.validateParameters(parameters); if (validationError) { return validationError; } const { file_path, line_start, line_end, include_line_numbers = true } = parameters; try { // Validate line numbers if (line_start < 1) { return { success: false, error: 'line_start must be >= 1' }; } if (line_end !== undefined && line_end !== -1 && line_end < line_start) { return { success: false, error: 'line_end must be >= line_start or -1 for end of file' }; } // Read file content const fileContent = await this.fileService.readFile(file_path); // Split content into lines const lines = fileContent.split('\n'); const totalLines = lines.length; // Validate line ranges against file size if (line_start > totalLines) { return { success: false, error: `line_start (${line_start}) exceeds file length (${totalLines} lines)` }; } // Determine actual end line let actualLineEnd = line_end; if (actualLineEnd === undefined) { actualLineEnd = line_start; // Read single line } else if (actualLineEnd === -1) { actualLineEnd = totalLines; // Read to end of file } else if (actualLineEnd > totalLines) { actualLineEnd = totalLines; // Cap at file length } // Extract requested lines (convert to 0-based indexing) const startIndex = line_start - 1; const endIndex = actualLineEnd - 1; const selectedLines = lines.slice(startIndex, endIndex + 1); // Format output let content; if (include_line_numbers) { content = selectedLines .map((line, index) => `${line_start + index}: ${line}`) .join('\n'); } else { content = selectedLines.join('\n'); } return { success: true, data: { file_path, line_start, line_end: actualLineEnd, lines_read: selectedLines.length, total_lines: totalLines, content, raw_lines: selectedLines }, message: `Read lines ${line_start}-${actualLineEnd} from ${file_path} (${selectedLines.length} lines)` }; } catch (error) { return { success: false, error: `Failed to read lines: ${error.message}` }; } } }