diff --git a/ChatSession.cs b/ChatSession.cs index 58dca26..9d3e518 100644 --- a/ChatSession.cs +++ b/ChatSession.cs @@ -44,6 +44,7 @@ internal sealed class ChatSession 2. After reading, edit the file before verifying the returned fingerprint. 3. Edit from bottom to top so line numbers don't shift. 4. If an anchor fails validation, re-read the relevant range to get fresh anchors. + 5. When making multiple edits to a file, use BatchEdit instead of multiple individual calls to prevent anchor invalidation between operations. Keep responses concise. You have access to the current working directory. You are running on: {{System.Runtime.InteropServices.RuntimeInformation.OSDescription}} diff --git a/Tools/EditTools.cs b/Tools/EditTools.cs index f4dfe25..3b3027e 100644 --- a/Tools/EditTools.cs +++ b/Tools/EditTools.cs @@ -11,7 +11,7 @@ public record BatchOperation( [property: Description("Operation type: 'replace' or 'delete'")] string Type, [property: Description("First line's line:hash anchor (e.g. '5:a3')")] string? StartAnchor, [property: Description("Last line's line:hash anchor (e.g. '8:d4')")] string? EndAnchor, - [property: Description("Raw source code to insert. Required for 'replace' operations.")] string[]? NewLines); + [property: Description("Text content to insert. Required for 'replace' operations.")] string[]? Content); /// /// Mutating file tools exposed to the LLM as AIFunctions. @@ -292,7 +292,7 @@ internal static partial class EditTools } } - [Description("Apply multiple edits atomically. All anchors are validated before any changes are made.")] + [Description("Atomically apply multiple replace/delete operations to a file. All anchors validated upfront against original content. Operations auto-sorted bottom-to-top to prevent line drift. Prefer over individual calls when making multiple edits.")] public static string BatchEdit( [Description("Path to the file.")] string path, [Description("Array of operations to apply. Operations are applied in bottom-to-top order automatically.")] BatchOperation[] operations) @@ -325,8 +325,8 @@ internal static partial class EditTools if (opType != "replace" && opType != "delete") return $"ERROR: Operation {i}: Invalid type '{op.Type}'. Must be 'replace' or 'delete'"; - if (opType == "replace" && op.NewLines == null) - return $"ERROR: Operation {i}: 'replace' requires NewLines"; + if (opType == "replace" && op.Content == null) + return $"ERROR: Operation {i}: 'replace' requires Content"; if (string.IsNullOrEmpty(op.StartAnchor) || string.IsNullOrEmpty(op.EndAnchor)) return $"ERROR: Operation {i}: StartAnchor and EndAnchor are required"; @@ -368,7 +368,7 @@ internal static partial class EditTools // Apply operation var opType = op.Type.ToLowerInvariant(); if (opType == "replace") - result.AddRange(SanitizeNewLines(op.NewLines!)); + result.AddRange(SanitizeNewLines(op.Content!)); // delete: don't add anything (skip the range) nextLineIdx = endIdx + 1;