summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVineet Kumar <git@vineetk.net>2026-05-25 23:46:24 -0400
committerVineet Kumar <git@vineetk.net>2026-05-25 23:46:24 -0400
commit62336cfba249c9bdd781d0789cc041f02f2aef0b (patch)
tree5fa29458bce4d770f3cf255b2f9e87f181fc7eb9
parentb4464b16c87f3b4a39584aa5faf66f2f9fee8be2 (diff)
final tool, edit_file, added
this took way too long.
-rw-r--r--llm-tools.el144
1 files changed, 143 insertions, 1 deletions
diff --git a/llm-tools.el b/llm-tools.el
index 56aeddd..efb8865 100644
--- a/llm-tools.el
+++ b/llm-tools.el
@@ -91,7 +91,149 @@ final file."))
91 :confirm t 91 :confirm t
92 :include t) 92 :include t)
93 93
94;; TODO edit_file (hashline + patch apply) 94;; edit_file (hl-edit)
95(gptel-make-tool
96 :name "edit_file"
97 :function #'llm-tools--hl-edit
98 :description "\
99Edit an existing file surgically using the hashline patch
100format. Call `read_file` first to obtain current content and valid
101line anchors. Use `write_file` instead for creating new files or
102completely replacing content. Returns a success message if the patch
103applied, or an error string describing what went wrong (structural
104issues or stale anchors)."
105 :args '((:name "patch"
106 :type string
107 :description "\
108A hashline patch string containing one or more file sections. Each
109section begins with `@@ PATH` on its own line, followed by operations
110that reference lines by their anchor (line number + 2-character hash,
111e.g. `5ff`). Copy anchors verbatim from `read_file` output; never
112fabricate or modify them.
113
114CRITICAL: This is NOT a unified diff. Do NOT use `---`, `+++`, `@@ -1,3
115+1,4 @@`, `-old`, `+new`, or any unified diff syntax. The header is
116`@@ PATH`; operations use `<`, `+`, `-`, `=`. This format is purely
117textual -- the tool has NO awareness of language, indentation,
118brackets, fences, or table widths. You must emit valid syntax in
119replacements and insertions.
120
121Operations:
122 + ANCHOR Insert lines AFTER the anchored line (or `EOF` to append)
123 < ANCHOR Insert lines BEFORE the anchored line (or `BOF` to prepend)
124 - A..B Delete the inclusive line range A through B
125 = A..B Replace the inclusive range A through B with payload lines
126
127Payload lines follow the operation line and must start with `~`
128immediately followed by content -- no space after `~`. Every character
129after `~` is verbatim file content. Op lines carry no content:
130
131WRONG: + 5pg some code
132RIGHT:
133+ 5pg
134~some code
135
136One operation can have many payload lines. To insert N consecutive
137lines, write ONE op followed by N `~` lines:
138
139WRONG (one op per line, with fabricated anchors):
140 + 5pg
141 ~first new line
142 + 6xx <- FABRICATED
143 ~second new line
144
145RIGHT (one op, many payload lines):
146 + 5pg
147 ~first new line
148 ~second new line
149
150Rules:
151- Payload is ONLY what is NEW relative to your range. Do not repeat
152 existing lines or duplicate nearby content.
153- Anchors reference the file as last read via `read_file`. Do not shift
154 line numbers for prior operations in the same patch.
155- Prefer narrow operations (`+`, `-`) over wide replacements (`=`).
156 Two narrow ops beat one wide `=`.
157- When editing a multiline construct, widen to the whole construct
158 rather than bisecting it.
159- `= A..B` deletes the range; payload is what is written. Before using
160 `=`, mentally delete A..B. If that splits an unclosed brace or
161 orphans a closer, you are bisecting a construct -- widen the range.
162- Every payload line must start with `~`. Raw content without `~` is
163 invalid.
164- Comments (lines starting with `#`) and blank lines are ignored.
165
166Examples:
167
168Replace a single line:
169@@ greeting.el
170= 2in..2in
171~(defconst greeting-title \"Mrs\")
172
173Replace a multiline block (widen to self-contained boundary):
174@@ greeting.el
175= 4ei..7be
176~ (concat
177~ greeting-title
178~ (or (string-trim name) \"guest\"))
179~ )
180
181Insert after:
182@@ greeting.el
183+ 4ei
184~ greeting-title
185
186Insert before:
187@@ greeting.el
188< 5ff
189~ greeting-title
190
191Append to end of file:
192@@ greeting.el
193+ EOF
194~(provide 'greeting)
195
196Prepend to beginning of file:
197@@ greeting.el
198< BOF
199~;; greeting.el -- utilities
200
201Delete a single line:
202@@ greeting.el
203- 5ff..5ff
204
205Blank a line (replace with empty):
206@@ greeting.el
207= 5ff..5ff
208
209Multiple operations in one section:
210@@ greeting.el
211+ 1vx
212~(defconst DEBUG nil)
213- 5ff..5ff
214
215Multiple files in one patch:
216@@ a.el
217+ 1vx
218~(require 'b)
219@@ b.el
220= 2in..2in
221~(defconst VALUE 42)
222
223Insert multiple lines with one op:
224@@ greeting.el
225+ 1vx
226~(defconst GREETING \"Hello\")
227~(defconst FAREWELL \"Goodbye\")
228
229Replace one line with multiple lines:
230@@ greeting.el
231= 1vx..1vx
232~(defconst TITLE \"Dr\")
233~(defconst SUBTITLE \"Assistant\")"))
234 :async nil
235 :confirm t
236 :include t)
95 237
96;; bash (make-process, taken from gptel-agent) 238;; bash (make-process, taken from gptel-agent)
97(defun llm-tools--execute-bash (callback command) 239(defun llm-tools--execute-bash (callback command)