Patch#
Single-file patches use the same staged replacement as Save: failed writes leave the original intact, permission bits and symlink targets are kept, and hard-linked destinations are refused. The parent directory must be writable. POSIX staging also requires that parent to be owned by the current user with no group or other write bits, including sticky shared directories, so another user cannot substitute the staging name. Same-user writers and hostile ancestor changes remain outside this guarantee. Replacement creates a new inode. As with save, extended metadata, inherited default ACLs and ownership that cannot be retained cause a safe refusal instead of silent metadata loss. On Windows, existing-file replacement is refused before staging because its security descriptor cannot be retained safely. macOS also refuses existing-file replacement because its ACLs cannot be reliably inspected through extended-attribute listings. Platforms without extended-attribute inspection fail closed too. Linux filesystems that report unsupported extended attributes remain supported; other metadata inspection errors still refuse the write. No power-loss durability or concurrent-writer guarantee is implied.
Gives the LLM agent the ability to patch text files, by using a adapted version git conflict markers.
- Environment Variables:
- GPTME_PATCH_RECOVERY: If set to “true” or “1”, returns the file content in error messages
when patches don’t match. This helps the assistant recover faster by seeing the actual file contents.
Instructions
To patch/modify files, we use an adapted version of git conflict markers.
Keep patches small. ORIGINAL must match the file exactly, including ellipsis
comments (`# ...`): these are literal, not wildcards. Use separate
ORIGINAL/UPDATED blocks to skip unchanged code. ORIGINAL must have exactly one
match, including overlapping occurrences; add surrounding context to disambiguate.
### When to use patch vs save
Use `patch` for targeted edits to existing files.
Use `save` for new files, full rewrites, or changes too large for patch markers.
Note: When patching markdown, avoid replacing partial codeblocks (just the opening
or closing backticks). The parser needs complete codeblocks. For simple
codeblock-boundary changes (like a language tag), use `sed` or `perl` instead.
Examples
| User |
patch `src/hello.py` to ask for the name of the user |
| Assistant |
|
| System |
Patch applied |
- class gptme.tools.patch.Patch
Patch(original: str, updated: str)
- diff_minimal(strip_context=False) str
Show a minimal diff of the patch. Note that a minimal diff isn’t necessarily a unique diff.
- gptme.tools.patch.apply(codeblock: str, content: str) str
Applies multiple patches in
codeblocktocontent. Provides detailed error messages when patches fail.
- gptme.tools.patch.execute_patch(code: str | None, args: list[str] | None, kwargs: dict[str, str] | None) Generator[Message, None, None]
Applies the patch.