mirror of
https://github.com/agent0ai/agent-zero.git
synced 2026-05-17 04:01:13 +00:00
66 lines
1.9 KiB
Python
66 lines
1.9 KiB
Python
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass
|
|
from typing import Any, Literal
|
|
|
|
|
|
PatchMode = Literal["edits", "patch_text", "replace"]
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class PatchRequest:
|
|
mode: PatchMode
|
|
edits: Any = None
|
|
patch_text: str = ""
|
|
old_text: str = ""
|
|
new_text: str = ""
|
|
|
|
|
|
def parse_patch_request(
|
|
edits: Any,
|
|
patch_text: Any,
|
|
old_text: Any = None,
|
|
new_text: Any = None,
|
|
*,
|
|
both_error: str = "provide exactly one patch form: edits, patch_text, or old_text/new_text",
|
|
missing_error: str = "edits, patch_text, or old_text/new_text is required for patch",
|
|
) -> tuple[PatchRequest | None, str]:
|
|
"""Validate the mutually-exclusive patch request shape."""
|
|
has_edits = edits is not None
|
|
has_patch_text = patch_text is not None
|
|
has_replace = old_text is not None or new_text is not None
|
|
if sum([has_edits, has_patch_text, has_replace]) > 1:
|
|
return None, both_error
|
|
|
|
if has_replace:
|
|
old = str(old_text or "")
|
|
if not old:
|
|
return None, "old_text is required for exact replace"
|
|
return PatchRequest(
|
|
mode="replace",
|
|
old_text=old,
|
|
new_text=str(new_text or ""),
|
|
), ""
|
|
|
|
if has_patch_text:
|
|
text = str(patch_text)
|
|
if not text.strip():
|
|
return None, "patch_text must not be empty"
|
|
return PatchRequest(mode="patch_text", patch_text=text), ""
|
|
|
|
if not edits:
|
|
return None, missing_error
|
|
|
|
return PatchRequest(mode="edits", edits=edits), ""
|
|
|
|
|
|
def exact_replace_to_patch_text(path: str, old_text: str, new_text: str) -> str:
|
|
"""Represent one exact text replacement as a context patch."""
|
|
lines = [
|
|
"*** Begin Patch",
|
|
f"*** Update File: {path}",
|
|
]
|
|
lines.extend(f"-{line}" for line in old_text.split("\n"))
|
|
lines.extend(f"+{line}" for line in new_text.split("\n"))
|
|
lines.append("*** End Patch")
|
|
return "\n".join(lines)
|