/
githubmirror
/
loopgpt
Обзор
Документация
Войти
/
githubmirror
/
loopgpt
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
openvibe/tool/edit.py
102 строки
3 KB
Fariz Rahman
lint
22 мар 2026, 07:19
22 мар 2026, 07:19
d1557ff
Код
Авторство
О чём код?
"""Edit tool — targeted string replacement in existing files. The model provides an ``old_string`` that must appear exactly once in the file and a ``new_string`` to replace it with. Multiple replacements can be batched via the ``edits`` list for efficiency. """ from __future__ import annotations from dataclasses import dataclass from pathlib import Path from pydantic import BaseModel, Field from openvibe.tool.base import Tool, ToolContext, ToolResult class _Edit(BaseModel): old_string: str = Field( description="Exact string to find. Must appear exactly once." ) new_string: str = Field(description="Replacement string.") class EditTool(Tool): name = "edit" description = ( "Replace exact substrings in an existing file. Each edit must " "uniquely identify a location — if ``old_string`` appears more than " "once the edit is rejected. Use ``write`` to replace whole files." ) class Params(Tool.Params): path: str = Field(description="Absolute or project-relative file path.") edits: list[_Edit] = Field( min_length=1, description="One or more old→new string replacements, applied in order.", ) async def execute(self, ctx: ToolContext, params: "EditTool.Params") -> ToolResult: path = _resolve(params.path, ctx.working_dir) await ctx.check_permission( tool="edit", argument=str(path), description=f"Edit {path}", ) if not path.exists(): return ToolResult( title=f"Edit {params.path}", output=f"File not found: {path}", error=True, ) try: content = path.read_text(encoding="utf-8") except OSError as exc: return ToolResult(title=f"Edit {params.path}", output=str(exc), error=True) original = content errors: list[str] = [] for edit in params.edits: count = content.count(edit.old_string) if count == 0: errors.append(f"String not found: {edit.old_string!r}") elif count > 1: errors.append( f"String appears {count} times (must be unique): {edit.old_string!r}" ) else: content = content.replace(edit.old_string, edit.new_string, 1) if errors: return ToolResult( title=f"Edit {params.path}", output="\n".join(errors), error=True, ) if content == original: return ToolResult( title=f"Edit {params.path}", output="No changes made (old and new strings are identical).", ) try: path.write_text(content, encoding="utf-8") except OSError as exc: return ToolResult(title=f"Edit {params.path}", output=str(exc), error=True) edits_applied = len(params.edits) return ToolResult( title=f"Edited {params.path}", output=f"Applied {edits_applied} edit(s) to {path}.", ) def _resolve(path_str: str, working_dir: str) -> Path: p = Path(path_str) return p if p.is_absolute() else Path(working_dir) / p