commit 137bec6d0706cfc341f99b12da52bb6932508580
parent 4c1f5482333f0c8c3d0ce3279f59a6037c98c9b1
Author: Vineet Kumar <git@vineetk.net>
Date: Sun, 24 May 2026 15:06:03 -0400
add grep tool
Diffstat:
| M | llm-tools.el | | | 50 | ++++++++++++++++++++++++++++++++++++++++++++++---- |
1 file changed, 46 insertions(+), 4 deletions(-)
diff --git a/llm-tools.el b/llm-tools.el
@@ -60,11 +60,11 @@ final file."))
;; TODO edit_file (hashline + patch apply)
;; TODO bash_readonly (shell-command-to-string, whitelisted commands)
-;; TODO compile command (calls build system, doesn't neenfirmation, whitelisted commands)
+;; TODO compile command (calls build system, doesn't need confirmation, whitelisted commands)
;; bash (make-process, taken from gptel-agent)
-;; TODO refuse destructive operations like rm and dd, and refuse
-;; operations that have dedicated tool definitions like grep and compile
+;; TODO refuse destructive operations like rm and dd
+;; TODO refuse operations that have dedicated tool definitions like grep and compile
(defun llm-tools--execute-bash (callback command)
"Execute COMMAND asynchronously in bash and call CALLBACK with output.
@@ -150,6 +150,48 @@ or editing them."
:confirm nil
:include t)
-;; TODO grep (just grep :D)
+;; grep (just grep (or git grep) :D)
+(gptel-make-tool
+ :name "grep"
+ :function (lambda (regex &optional path)
+ (with-temp-buffer
+ (if (magit-gitdir)
+ (call-process "git" nil t nil
+ "--no-pager"
+ "grep"
+ "-rnEH"
+ regex
+ (or path "."))
+ (call-process "grep" nil t nil
+ "-rnEH"
+ regex
+ (or path ".")))
+ (buffer-string)))
+ :description "\
+Recursively search for lines matching a regex pattern in files under a
+given path. Uses `git grep` when inside a Git repository, otherwise falls
+back to GNU grep. Both are invoked with flags -rnEH (recursive, line
+numbers, extended regex, always show filename). When using `git grep`,
+only tracked files are searched. Returns raw output with one match per
+line in the format FILE:LINE:CONTENT. Use this tool to find code
+patterns, locate function definitions, search for strings, or identify
+files containing specific text before reading them. For simple file name
+discovery, use `find_files` instead. For reading file contents, use
+`read_file`. The path argument is relative to the working directory;
+omit it to search from the current directory."
+ :args '((:name "regex"
+ :type string
+ :description "\
+Regular expression pattern to search for. Uses GNU grep extended syntax.")
+ (:name "path"
+ :type string
+ :description "\
+Optional file or directory path to search within, relative to the
+working directory. Defaults to current directory if omitted."
+ :optional t))
+ :async nil
+ :confirm nil
+ :include t)
+
;; TODO fetch_url (use gptel-agent's one as a base, but needs mime handling like PDFs and images)
;; TODO web_search (use gptel-agent's eww/shr method as a base)