Replies: 3 comments 1 reply
-
Speaking for myself: my priorities for gptel presently are to (i) make tool-use plumbing more robust (#626), (ii) draft a new release, (iii) improve the chat buffer+context handling and (iv) write a detailed manual, so I have my hands full. Writing a robust buffer editing suite is essentially one half of the work of implementing aider, and I'm afraid it's beyond my current time budget. If something needs to change in gptel's control flow to support it, I can work on facilitating that. (About the manual: besides the usual reasons, the manual is necessary to document various internal interfaces so users can extend gptel with confidence. It should also function as a lookup-source for a gptel tool so users can get the LLM to answer questions about gptel and take some of the tech support load off my shoulders.) |
Beta Was this translation helpful? Give feedback.
-
I guess I can share my attempt-(not-yet-really-)in-progress: https://github.com/ultronozm/modify-buffer.el. Feel free to try it out, or try to improve it. |
Beta Was this translation helpful? Give feedback.
-
@RomeoV I've found that with Sonnet 3.7, direct search and replace works quite well, giving a much simpler solution than in my earlier comment. I've been using something like the following: (defun codel-edit-buffer (buffer-name old-string new-string)
"In BUFFER-NAME, replace OLD-STRING with NEW-STRING."
(with-current-buffer buffer-name
(let ((case-fold-search nil)) ;; Case-sensitive search
(save-excursion
(goto-char (point-min))
(let ((count 0))
(while (search-forward old-string nil t)
(setq count (1+ count)))
(if (= count 0)
(format "Error: Could not find text to replace in buffer %s" buffer-name)
(if (> count 1)
(format "Error: Found %d matches for the text to replace in buffer %s" count buffer-name)
(goto-char (point-min))
(search-forward old-string)
(replace-match new-string t t)
(format "Successfully edited buffer %s" buffer-name))))))))
(defun codel-replace-buffer (buffer-name content)
"Completely replace contents of BUFFER-NAME with CONTENT."
(with-current-buffer buffer-name
(erase-buffer)
(insert content)
(format "Buffer replaced: %s" buffer-name)))
(defun gptel-register-tool (tool)
"Register TOOL, making it available for use in gptel chat.
If a tool with the same name already exists, it is replaced.
TOOL must be a `gptel-tool' struct."
(unless (gptel-tool-p tool)
(error "TOOL must be a gptel-tool struct"))
(setq gptel-tools
(cons tool (seq-remove
(lambda (existing)
(string= (gptel-tool-name existing)
(gptel-tool-name tool)))
gptel-tools))))
(mapcar
(lambda (spec)
(let ((tool (apply #'gptel-make-tool spec)))
(gptel-register-tool tool)
(setq gptel-tools
(cons tool (seq-remove
(lambda (existing)
(string= (gptel-tool-name existing)
(gptel-tool-name tool)))
gptel-tools)))))
`((:name "EditBuffer"
:function ,#'codel-edit-buffer
:description "Edits Emacs buffers"
:args ((:name "buffer_name"
:type string
:description "Name of the buffer to modify"
:required t)
(:name "old_string"
:type string
:description "Text to replace (must match exactly)"
:required t)
(:name "new_string"
:type string
:description "Text to replace old_string with"
:required t)))
(:name "ReplaceBuffer"
:function ,#'codel-replace-buffer
:description "Completely overwrites buffer contents"
:args ((:name "buffer_name"
:type string
:description "Name of the buffer to overwrite"
:required t)
(:name "content"
:type string
:description "Content to write to the buffer"
:required t))))) |
Beta Was this translation helpful? Give feedback.
-
Hello, I wanted to ask what's the status on tool use for editing buffers. I know it has been discussed a bit in the thread on testing tool-use, for instance here.
Does someone have a copy-pastable tool that works reasonably well? For inspiration, I think it can also be useful to consider the implementation that
aider
is using, where the file editing is done through git patches (which are checked through multiple passes for syntactical correctness before applying).Beta Was this translation helpful? Give feedback.
All reactions