llm-diff-patcher
Version:
A library for applying fuzzy diffs generated by LLMs, especially useful for AI-generated code modifications
129 lines (95 loc) • 3.74 kB
Markdown
for applying "fuzzy" diffs, particularly designed for LLM-generated code modifications where line numbers may not be accurate.
```bash
npm install llm-diff-patcher
```
```typescript
import { applyPatchToFiles } from 'llm-diff-patcher';
// Original source code
const sourceText = `function hello() {
console.log("Hello, world!");
return true;
}`;
// A diff to apply (in unified diff format)
const diffText = `@@ -1,4 +1,4 @@
function hello() {
- console.log("Hello, world!");
+ console.log("Hello, universe!");
return true;
}`;
// Apply the fuzzy diff
const result = applyDiff(sourceText, diffText);
console.log(result);
// Output:
// function hello() {
// console.log("Hello, universe!");
// return true;
// }
// For applying to files in a directory:
const patchResult = applyPatchToFiles(diffText, {
basePath: '/path/to/project',
dryRun: false
});
console.log(`Files: ${patchResult.successfulFiles}/${patchResult.totalFiles}, Hunks: ${patchResult.appliedHunks}/${patchResult.totalHunks}`);
```
You can customize the behavior with options:
```typescript
// When applying to files
const result = applyPatchToFiles(diffText, {
// Base directory for resolving file paths
basePath: '/path/to/project',
// If true, doesn't actually write to files (default: false)
dryRun: true,
// Minimum number of context lines required for a match
minContextLines: 2,
// Options passed to the underlying diff library
jsDiffApplyPatchOptions: {
// Maximum Levenshtein distance between context in patch and actual file lines
// Higher values allow more fuzzy matches (default: 0)
fuzzFactor: 2,
// Automatically handle different line endings between patch and source file
// (default: true)
autoConvertLineEndings: true,
// Custom function to compare lines for equality when patching
// Allows for very flexible fuzzy matching
compareLine: (lineNumber, line, operation, patchContent) => {
// Custom comparison logic here
// Return true if lines should be considered equal, false otherwise
return line.trim() === patchContent.trim(); // Example: ignore whitespace
}
}
});
```
Unlike traditional diff tools that require exact line numbers to match, `llm-diff-patcher` is designed to handle the imprecise nature of diffs generated by Large Language Models (LLMs).
Key benefits:
1. **Fuzzy Matching**: Applies changes based on context even when line numbers are incorrect
2. **Robust Error Handling**: Provides detailed information about successful and failed patches
3. **Flexible Configuration**: Adjust matching strictness to your needs
4. **Dry Run Mode**: Test patches without modifying files
## Use Cases
- Applying code changes suggested by AI assistants like GPT, Claude, or other LLMs
- Implementing code modifications across slightly different versions of files
- Working with diffs that may not have perfect context or line numbers
- Automated code refactoring with LLM-generated patches
## API
The library provides several key functions:
- `applyPatchToFiles`: Apply patch to multiple files in a directory
- `applyDiff`: Apply a single diff to a string
- `parsePatch`: Parse a patch string into a structured format
- `cleanPatch`: Clean up and normalize patch text
## Error Handling
The library provides detailed error information to help you understand what went wrong:
```typescript
if (!patchResult.success) {
console.error(`Failed to apply patch. Errors:`);
patchResult.errors.forEach(error => {
console.error(`- ${error.message} (${error.context})`);
});
}
```
MIT
A TypeScript library