Skip to content

Commit

Permalink
.
Browse files Browse the repository at this point in the history
  • Loading branch information
addisonbeck committed Feb 25, 2025
1 parent bc177d9 commit d4c57c4
Show file tree
Hide file tree
Showing 4 changed files with 1,280 additions and 68 deletions.
48 changes: 44 additions & 4 deletions system/with/user/with/program/git.nix
Original file line number Diff line number Diff line change
@@ -1,7 +1,47 @@
{...}: {
programs.git.enable = true;
programs.git.delta.enable = true;
programs.git.extraConfig = {
github.user = "addisonbeck";
programs.git = {
enable = true;
extraConfig = {
pull.rebase = true;
column.ui = "auto";
branch.sort = "-committerdate";
tag.sort = "version:refname";
init.defaultBranch = "main";
diff = {
algorithm = "histogram";
colorMoved = "plain";
mnemonixPrefix = true;
};
push = {
default = "simple";
autoSetupRemote = true;
followTags = true;
};
fetch = {
prune = true;
pruneTags = true;
all = true;
};
help = {
autocorrect = "prompt";
};
commit = {
verbose = true;
};
rerere = {
enabled = true;
autoupdate = true;
};
core = {
excludesfile = "~/.gitignore";
fsmonitor = true;
untrackedCache = true;
};
rebase = {
autoSquash = true;
autoStash = true;
updateRefs = true;
};
};
};
}
147 changes: 84 additions & 63 deletions system/with/user/with/program/init.org
Original file line number Diff line number Diff line change
Expand Up @@ -954,6 +954,9 @@ Some notes:

1. All tools _must_ have an arguement. This can be just a dummy arguement like `read_gptel_tools_section`.

** General Tools Setup
This block contains helper functions and variables used by multiple tools. These are not tools themselves but support the tool infrastructure.

#+begin_src emacs-lisp
(setq gptel-use-tools t
gptel-tools nil)
Expand Down Expand Up @@ -1006,70 +1009,88 @@ This tool hooks in to my file reading function and bookmarks list to enable LLMs
This tool hooks in to my file writing function and bookmarks list to enable LLMs to edit specific files at will and all files behind a warning.

#+begin_src emacs-lisp
(defun my/parse-search-replace-blocks (content)
"Extract list of changes from content with search/replace blocks."
(with-temp-buffer
(insert content)
(let (changes)
(goto-char (point-min))
(while (re-search-forward "<<<<<<< SEARCH\n\\([^=]*?\\)\n=======\n\\([^>]*?\\)\n>>>>>>> REPLACE" nil t)
(push (list :search (match-string 1)
:replace (match-string 2))
changes))
(nreverse changes))))

(defun my/apply-changes (original-content changes)
"Apply changes specified in search/replace block format to ORIGINAL-CONTENT."
(with-temp-buffer
(insert original-content)
(dolist (change changes)
(let ((search (plist-get change :search))
(replace (plist-get change :replace)))
(defun my/parse-search-replace-blocks (content)
"Extract list of changes from content with search/replace blocks."
(with-temp-buffer
(insert content)
(let (changes)
(goto-char (point-min))
(while (search-forward search nil t)
(replace-match replace t t))))
(buffer-string)))

(defun my/write-file (file-id content)
"Write file with changes in search/replace block format.
FILE-ID can be a bookmark name or full path.
CONTENT must contain search/replace blocks showing what to change."
(let* ((bookmark (alist-get file-id my/file-bookmarks nil nil #'equal))
(file-path (expand-file-name
(if bookmark
(plist-get bookmark :path)
file-id)))
(original (my/read-file file-id))
(changes (my/parse-search-replace-blocks content))
(new-content (my/apply-changes original changes)))
;; Validate content preservation
(when (< (length new-content) (* 0.95 (length original)))
(error "Error: New content is significantly smaller than original"))
;; Write the new content
(write-region new-content nil file-path)
(format "Updated %s" file-path)))

(gptel-make-tool
:name "write_file"
:function #'my/write-file
:description "Modify specific sections of a file while preserving all other content.
REQUIRED FORMAT:
<<<<<<< SEARCH
text to find and replace
=======
new text to insert
>>>>>>> REPLACE

You can include multiple search/replace blocks to make multiple changes.
The search text must match exactly what's in the file."
:args '((:name "file-id"
:type string
:description "bookmark name or full file path")
(:name "content"
:type string
:description "search/replace blocks showing what to change")))

(register-gptel-tool "write_file")
(while (re-search-forward "<<<<<<< SEARCH\n\\([^=]*?\\)\n=======\n\\([^>]*?\\)\n>>>>>>> REPLACE" nil t)
(push (list :search (match-string 1)
:replace (match-string 2))
changes))
(nreverse changes))))

(defun my/apply-changes (original-content changes)
"Apply changes specified in search/replace block format to ORIGINAL-CONTENT."
(with-temp-buffer
(insert original-content)
(dolist (change changes)
(let ((search (plist-get change :search))
(replace (plist-get change :replace)))
(goto-char (point-min))
(while (search-forward search nil t)
(replace-match replace t t))))
(buffer-string)))

(defun my/write-file (file-id content)
"Write file with changes in search/replace block format.
FILE-ID can be a bookmark name or full path.
CONTENT must contain search/replace blocks showing what to change."
(let* ((bookmark (alist-get file-id my/file-bookmarks nil nil #'equal))
(file-path (expand-file-name
(if bookmark
(plist-get bookmark :path)
file-id)))
(original (my/read-file file-id))
(changes (my/parse-search-replace-blocks content))
(new-content (my/apply-changes original changes)))
;; Validate content preservation
(when (< (length new-content) (* 0.95 (length original)))
(error "Error: New content is significantly smaller than original"))
;; Show diff and confirm
(let* ((diff-buffer (generate-new-buffer "*File Changes Preview*"))
(confirm-changes nil))
(with-current-buffer diff-buffer
(insert "Proposed changes to " file-path ":\n\n")
(dolist (change changes)
(insert "--- Original:\n" (plist-get change :search) "\n"
"+++ New:\n" (plist-get change :replace) "\n\n"))
(display-buffer diff-buffer)
(setq confirm-changes (yes-or-no-p "Apply these changes? "))
(kill-buffer))
(if confirm-changes
(progn
(write-region new-content nil file-path)
(format "Updated %s" file-path))
(format "Changes cancelled by user")))))

(gptel-make-tool
:name "write_file"
:function #'my/write-file
:description "Modify specific sections of a file while preserving all other content.

The CONTENT arguement _must_ adhere to this format with SEARCH and REPLACE blocks:

```
<<<<<<< SEARCH
text to find and replace
=======
new text to insert
>>>>>>> REPLACE
```

- You can include multiple search/replace blocks to make multiple changes.
- The search text must match exactly what is in the file.
- If a failure occurs do not try again without asking me first."
:args '((:name "file-id"
:type string
:description "bookmark name or full file path")
(:name "content"
:type string
:description "search/replace blocks showing what to change")))

(register-gptel-tool "write_file")
#+end_src

** Fetch_Webpage
Expand Down
Loading

0 comments on commit d4c57c4

Please sign in to comment.