commit 2c76620e87779b0dcb0e8d9b704e72bb1e152376
parent b96542641a8740092c5f365f121d8aed1b5b8411
Author: Vineet Kumar <git@vineetk.net>
Date: Thu, 22 Oct 2026 16:10:48 +0200
add tail functionality to read_file
Diffstat:
2 files changed, 15 insertions(+), 5 deletions(-)
diff --git a/llm-tools-edit.el b/llm-tools-edit.el
@@ -41,12 +41,16 @@ With optional BEG and END (inclusive, 1-based), return the lines between that ra
(cl-subseq lines (1- beg) end)
lines))))
-(defun llm-tools--edit-file-read (file &optional beg end as-list?)
+(defun llm-tools--edit-file-read (file &optional beg end as-list? tail)
"Return FILE contents.
With optional BEG and END (inclusive, 1-based), return lines BEG to END.
If AS-LIST? is non-nil, return a list of strings instead of a single
-string."
+string.
+TAIL reads the last N lines and cannot be combined with BEG or END."
+ (when (and tail (or beg end (not (and (integerp tail) (> tail 0)))))
+ (error "tail must be positive and cannot be combined with beg or end"))
(let* ((lines (llm-tools--edit-file-lines file beg end))
+ (lines (if tail (last lines tail) lines))
(formatted (string-join lines "\n")))
(if as-list?
lines
diff --git a/llm-tools.el b/llm-tools.el
@@ -41,10 +41,12 @@
;; read_file
(gptel-make-tool
:name "read_file"
- :function (lambda (file &optional beg end as-list?)
- (llm-tools--edit-file-read file beg end as-list?))
- :description "Read a file as plain text. Call this before editing to obtain the current text.
+ :function (lambda (file &optional beg end as-list? tail)
+ (llm-tools--edit-file-read file beg end as-list? tail))
+ :description "Read file contents, including build logs. Use instead of cat, head, tail, or sed.
+Call this before editing to obtain the current text.
Optional beg and end select an inclusive, 1-based line range.
+Use tail to read the last N lines without knowing the file length.
Set as_list to return a list of lines instead of a newline-delimited string."
:args '((:name "file"
:type string
@@ -60,6 +62,10 @@ Set as_list to return a list of lines instead of a newline-delimited string."
(:name "as_list"
:type boolean
:description "Return a list of lines instead of a string."
+ :optional t)
+ (:name "tail"
+ :type integer
+ :description "Read the last N lines (positive integer); omit beg and end."
:optional t))
:async nil
:confirm nil