udiffx
Parse and apply an AI-optimized “file changes” envelope that carries multiple file operations in a single block, using unified diff patches for updates.
This crate is designed for LLM output that needs to be machine-parsable and efficient for large files with small edits.
Concept, FILE_CHANGES
A response contains one root container:
<FILE_CHANGES> ... </FILE_CHANGES>
Inside it, you can mix multiple directives:
<FILE_NEW file_path="..."> ... </FILE_NEW><FILE_PATCH file_path="..."> ... </FILE_PATCH>(unified diff content)<FILE_RENAME from_path="..." to_path="..." /><FILE_DELETE file_path="..." />
Notes:
- Tags are XML-like but not intended to be strictly XML-compliant.
- The parser is tag-based. It extracts only the above tags, and content does not need XML escaping.
- Self-closing tags like
<FILE_DELETE ... />are supported.
API overview
The crate exposes two main operations:
- Extract: parse the first
<FILE_CHANGES>block from a string. - Apply: execute the extracted directives against a base directory.
Key public types:
FileChanges, an iterable list of directives.FileDirective, one directive (new, patch, rename, delete, fail).ApplyChangesStatus, per-directive success and error reporting.Error/Result<T>, the crate error type and alias.
Gathering file context
Use load_files_context to gather files matching globs and format them for an LLM context.
use ;
Output format:
... content ...
... content ...
Extracting changes from text
Use extract_file_changes to parse a model response or any input string.
use ;
extract_content parameter:
extract_content = falseparses tags and returnsextruded = None.extract_content = truealso returns the input with the extracted<FILE_CHANGES>block removed asSome(String).
Applying changes to disk
Use apply_file_changes to execute directives relative to a base directory.
- All file paths are treated as relative to
base_dir. - The crate performs basic path safety checks to ensure operations stay within
base_dir. - Patch application uses
diffy(unified diff parsing and application).
use SPath;
use ;
Directive behavior
FILE_NEW: creates or overwrites a file. Parent directories are created.FILE_PATCH: reads the target file, applies a unified diff, and writes the result back.FILE_RENAME: renames or movesfrom_pathtoto_path.FILE_DELETE: removes a file or directory recursively.
If extraction fails for a directive (unknown tag, missing attribute, etc.), the directive is represented as:
FileDirective::Fail { kind, file_path, error_msg }
When applying, Fail directives always yield an error for that directive and are reported via ApplyChangesInfo.
Format tips for LLM output
- Always emit exactly one
<FILE_CHANGES>block when you intend to apply changes. - Prefer
FILE_PATCHfor small edits to large files. - Use self-closing tags for rename and delete when convenient:
<FILE_RENAME from_path="a" to_path="b" /><FILE_DELETE file_path="path" />
System prompt (optional)
The crate includes the recommended system instructions for LLMs to ensure they output the correct format. This is available via the prompt feature.
[]
= { = "0.1", = ["prompt"] }
use prompt;
let instructions = prompt;
// Pass this to your LLM system message.
License
MIT OR Apache-2.0