from langchain.tools import tool import os import subprocess import re @tool def read_file(path: str, start_line: int = 0, end_line: int = None) -> str: """Прочитать содержимое файла. Можно указать диапазон строк (1-индекс).""" if not os.path.exists(path): return f"File not found: {path}" with open(path, 'r', encoding='utf-8') as f: lines = f.readlines() if start_line > 0: lines = lines[start_line-1:] if end_line: lines = lines[:end_line-start_line+1] return ''.join(lines) @tool def write_file(path: str, content: str) -> str: """Создать или перезаписать файл с указанным содержимым.""" # Создаем директорию только если путь содержит директорию dir_name = os.path.dirname(path) if dir_name: os.makedirs(dir_name, exist_ok=True) with open(path, 'w', encoding='utf-8') as f: f.write(content) return f"Файл {path} записан" @tool def delete_lines(path: str, start_line: int, end_line: int) -> str: """Удалить строки из файла (1-индекс, включительно).""" if not os.path.exists(path): return f"File not found: {path}" with open(path, 'r', encoding='utf-8') as f: lines = f.readlines() del lines[start_line-1:end_line] with open(path, 'w', encoding='utf-8') as f: f.writelines(lines) return f"Удалены строки {start_line}-{end_line} из {path}" @tool def replace_text_in_file(path: str, old: str, new: str) -> str: """Заменить все вхождения old на new в файле.""" if not os.path.exists(path): return f"File not found: {path}" with open(path, 'r', encoding='utf-8') as f: content = f.read() new_content = content.replace(old, new) with open(path, 'w', encoding='utf-8') as f: f.write(new_content) return f"Заменено {content.count(old)} вхождений" @tool def search_in_files(directory: str, pattern: str, file_pattern: str = "*.py") -> str: """Найти все файлы, содержащие pattern (grep).""" cmd = f"grep -l --include='{file_pattern}' -r '{pattern}' {directory}" result = subprocess.run(cmd, shell=True, capture_output=True, text=True) return result.stdout.strip() # @tool # def run_command(command: str) -> str: # """Выполнить системную команду и вернуть вывод.""" # result = subprocess.run(command, shell=True, capture_output=True, text=True) # return f"STDOUT:\n{result.stdout}\nSTDERR:\n{result.stderr}" # @tool # def find_class_definition(file_path: str, class_name: str) -> str: # """Найти в файле определение класса (простой поиск по regex).""" # with open(file_path, 'r') as f: # content = f.read() # pattern = rf'^\s*class\s+{class_name}\s*[:\(]' # match = re.search(pattern, content, re.MULTILINE) # if match: # # найти конец класса по отступам (упрощённо) # lines = content.splitlines() # start_line = content[:match.start()].count('\n') + 1 # # грубо ищем до следующего class или def на том же уровне # # для простоты вернём 20 строк после # end_line = start_line + 20 # return f"Класс {class_name} найден в {file_path} (строки {start_line}-{end_line})" # return f"Класс {class_name} не найден в {file_path}"