Update date
This commit is contained in:
parent
3d39685afa
commit
cbf784b1a7
2 changed files with 107 additions and 86 deletions
106
README.org
106
README.org
|
@ -134,7 +134,7 @@ To that end, the stop-gap solution is to implement a hard limit on the amount of
|
|||
I don't think there's much reason to ever allow partial results, which leads me to this:
|
||||
|
||||
#+begin_src elisp :results none
|
||||
(defvar gptel-org-tools-result-limit 20000)
|
||||
(defvar gptel-org-tools-result-limit 40000)
|
||||
|
||||
(defun gptel-org-tools--result-limit (result)
|
||||
(if (>= (length (format "%s" result)) gptel-org-tools-result-limit)
|
||||
|
@ -147,12 +147,12 @@ I don't think there's much reason to ever allow partial results, which leads me
|
|||
Use ~setq~ in your configuration, e.g.:
|
||||
|
||||
#+begin_src elisp :tangle no :results none
|
||||
(setq gptel-org-tools-result-limit 12000)
|
||||
(setq gptel-org-tools-result-limit 40000)
|
||||
#+end_src
|
||||
|
||||
This will *prevent* tools from returning results longer than 12,000 characters. Instead, the LLM will receive a message saying it should be much more specific in its queries, which will hopefully guide it to be more specific.
|
||||
This will *prevent* tools from returning results longer than 40,000 characters. Instead, the LLM will receive a message saying it should be much more specific in its queries, which will hopefully guide it to be more specific.
|
||||
|
||||
By default the limit is 20k, but for my use 12k seems like a reasonable middle-ground (24GB RAM and long query chains.)
|
||||
By default the limit is 40k, as that's just over the longest months I've kept my journal through.
|
||||
|
||||
The functionality for withholding results is only applied to select functions that are known to cause issues.
|
||||
** Helper Functions
|
||||
|
@ -161,6 +161,7 @@ These abstract away some of the tool definitions. They're called from each funct
|
|||
*** Return heading (line)
|
||||
#+begin_src elisp
|
||||
(defun gptel-org-tools--heading ()
|
||||
"Return the org-mode heading."
|
||||
(concat
|
||||
(buffer-substring-no-properties
|
||||
(line-beginning-position)
|
||||
|
@ -170,6 +171,7 @@ These abstract away some of the tool definitions. They're called from each funct
|
|||
*** Return heading and body (without subheadings)
|
||||
#+begin_src elisp
|
||||
(defun gptel-org-tools--heading-body ()
|
||||
"Return the org-mode heading and body text."
|
||||
(concat
|
||||
(buffer-substring-no-properties
|
||||
(line-beginning-position)
|
||||
|
@ -181,6 +183,7 @@ These abstract away some of the tool definitions. They're called from each funct
|
|||
*** Return heading and subheadings (until next same-level heading)
|
||||
#+begin_src elisp
|
||||
(defun gptel-org-tools--heading-subtree ()
|
||||
"Return the org-mode heading and all subheadings, with their body text."
|
||||
(concat
|
||||
(buffer-substring-no-properties
|
||||
(line-beginning-position)
|
||||
|
@ -208,12 +211,12 @@ Highly not recommended, but sometimes an LLM can pull a rabbit out of pure entro
|
|||
(gptel-make-tool
|
||||
:function #'gptel-org-tools--eval
|
||||
:name "gptel-org-tools--eval"
|
||||
:description "Execute Emacs Lisp code"
|
||||
:args (list '(:name "eval"
|
||||
:type string
|
||||
:description "The Emacs Lisp code to evaluate."))
|
||||
:category "emacs"
|
||||
:confirm t))
|
||||
:confirm t
|
||||
:description "Execute Emacs Lisp code"))
|
||||
#+end_src
|
||||
|
||||
**** list-buffers
|
||||
|
@ -230,12 +233,12 @@ Not using ~ibuffer~ to avoid customization differences between users. Argument r
|
|||
(gptel-make-tool
|
||||
:function #'gptel-org-tool--list-buffers
|
||||
:name "gptel-org-tool--list-buffers"
|
||||
:description "Access the list of buffers open in Emacs, including file names and full paths."
|
||||
:args (list '(:name "arg"
|
||||
:type string
|
||||
:description "Does nothing."
|
||||
:optional t))
|
||||
:category "emacs"))
|
||||
:category "emacs"
|
||||
:description "List buffers open in Emacs, including file names and full paths. After using this, evaluate which files are most likely to be relevant to the user's request."))
|
||||
#+end_src
|
||||
|
||||
**** dired
|
||||
|
@ -258,7 +261,7 @@ You can customize the function to point to your org directory, if you wish. I'm
|
|||
(gptel-make-tool
|
||||
:function #'gptel-org-tools--dir
|
||||
:name "gptel-org-tools--dir"
|
||||
:description "List directory contents"
|
||||
:description "List directory contents."
|
||||
:args (list '(:name "dir"
|
||||
:type string
|
||||
:description "Directory path"
|
||||
|
@ -321,7 +324,7 @@ Opens a file into an inactive (background) buffer for processing.
|
|||
(gptel-make-tool
|
||||
:function #'gptel-org-tools--read-file-contents
|
||||
:name "gptel-org-tools--read-file-contents"
|
||||
:description "Read and return the contents of a specified file."
|
||||
:description "Reads and return the contents of a specified file."
|
||||
:args (list '(:name "filename"
|
||||
:type string
|
||||
:description "The filename to read."))
|
||||
|
@ -335,13 +338,13 @@ Opens a file into an inactive (background) buffer for processing.
|
|||
(let ((symbol (intern var)))
|
||||
(if (boundp symbol)
|
||||
(prin1-to-string (symbol-value symbol))
|
||||
(format "Variable %s is not bound." var))))
|
||||
(format "Variable %s is not bound. This means the variable doesn't exist. Reassess what you're trying to do, examine the situation, and continue. " var))))
|
||||
|
||||
(add-to-list 'gptel-org-tools
|
||||
(gptel-make-tool
|
||||
:function #'gptel-org-tools--describe-variable
|
||||
:name "gptel-org-tools--describe-variable"
|
||||
:description "See variable contents"
|
||||
:description "Returns variable contents."
|
||||
:args (list '(:name "var"
|
||||
:type string
|
||||
:description "Variable name"))
|
||||
|
@ -361,7 +364,7 @@ Opens a file into an inactive (background) buffer for processing.
|
|||
(gptel-make-tool
|
||||
:function #'gptel-org-tools--describe-function
|
||||
:name "gptel-org-tools--describe-function"
|
||||
:description "See function description"
|
||||
:description "Returns function description"
|
||||
:args (list '(:name "fun"
|
||||
:type string
|
||||
:description "Function name"
|
||||
|
@ -401,18 +404,18 @@ LLMs are not intelligent, despite claims to the contrary.
|
|||
(gptel-make-tool
|
||||
:function #'gptel-org-tools--org-extract-tags
|
||||
:name "gptel-org-tools--org-extract-tags"
|
||||
:description "Extract all unique tags from an org-mode buffer"
|
||||
:args (list '(:name "buffer"
|
||||
:type string
|
||||
:description "The Org buffer to extract tags from."))
|
||||
:category "org-mode"))
|
||||
:category "org-mode"
|
||||
:description "Returns all tags from an org-mode buffer. When using this, evaluate the relevance of each tag to the user's request."))
|
||||
#+end_src
|
||||
**** org-extract-headings
|
||||
#+begin_src elisp
|
||||
(defun gptel-org-tools--org-extract-headings (buffer)
|
||||
"Return all headings from BUFFER."
|
||||
(if (member buffer gptel-org-tools-skip-heading-extraction)
|
||||
(user-error "Buffer %s has too many headings, use org-extract-tags or org-ql-select-rifle." buffer)
|
||||
(user-error "Buffer %s has been blocked from this function by the user with reason: headings contain timestamps, no useful information. Use a different tool." buffer)
|
||||
(with-current-buffer buffer
|
||||
(org-map-entries
|
||||
#'gptel-org-tools--heading
|
||||
|
@ -423,7 +426,7 @@ LLMs are not intelligent, despite claims to the contrary.
|
|||
(gptel-make-tool
|
||||
:function #'gptel-org-tools--org-extract-headings
|
||||
:name "gptel-org-tools--org-extract-headings"
|
||||
:description "Extract all headings from an org-mode buffer"
|
||||
:description "Returns all headings from an org-mode buffer. After using this, evaluate the relevance of the headings to the user's request."
|
||||
:args (list '(:name "buffer"
|
||||
:type string
|
||||
:description "The Org buffer to extract headings from."))
|
||||
|
@ -451,14 +454,15 @@ QUERY can be any valid org-ql-select query."
|
|||
(gptel-make-tool
|
||||
:function #'gptel-org-tools--org-ql-select
|
||||
:name "gptel-org-tools--org-ql-select"
|
||||
:description "Run org-ql-select against buffer with query. Using filename fails."
|
||||
:args (list '(:name "buffer"
|
||||
:type string
|
||||
:description "The name of the buffer. Can be multiple buffers. See the NAME column in `list-buffers`.")
|
||||
;; I'm not actually sure if it can be multiple, haven't tested.
|
||||
'(:name "query"
|
||||
:type string
|
||||
:description "The query to pass into org-ql-select. See org-ql documentation for syntax. Usually `(tags \"tag1\" \"tag2\")` is sufficient. Possible predicates: `tags` (finds both local and inherited tags), `tags-local` (finds only local tags), `rifle` (matches against both heading and body text). This is a sexp, not a string."))
|
||||
:category "org"))
|
||||
:category "org"
|
||||
:description "Return entries matching QUERY from BUFFER.."))
|
||||
#+end_src
|
||||
**** Somewhat working tools
|
||||
***** org-ql-select-by-date
|
||||
|
@ -478,7 +482,7 @@ The reason for this tool existing (it's the same as select-heading), is that it
|
|||
|
||||
|
||||
#+begin_src elisp
|
||||
(defun gptel-org-tools--org-ql-select-by-date (buf date)
|
||||
(defun gptel-org-tools--org-ql-select-date (buf date)
|
||||
"Returns all timestamped headings matching the specified date or date range.
|
||||
The date can be in the format YYYY, YYYY-MM, or YYYY-MM-DD.
|
||||
|
||||
|
@ -489,26 +493,32 @@ DATE is the date or date range to match."
|
|||
(if (bufferp buffer)
|
||||
(if (eq mode 'org-mode)
|
||||
(let ((result
|
||||
(org-ql-select buffer
|
||||
(concat
|
||||
(org-ql-select buffer
|
||||
`(heading ,date)
|
||||
:action #'gptel-org-tools--heading-subtree)))
|
||||
(gptel-org-tools--result-limit result))
|
||||
:action #'gptel-org-tools--heading-subtree)
|
||||
"Results end here. Proceed with the next action.")))
|
||||
(gptel-org-tools--result-limit result))
|
||||
(message "Buffer '%s' isn't an org-mode buffer." buf))
|
||||
(message "Buffer '%s' does not exist." buf))))
|
||||
#+end_src
|
||||
|
||||
|
||||
#+begin_src elisp
|
||||
(add-to-list 'gptel-org-tools
|
||||
(gptel-make-tool
|
||||
:function #'gptel-org-tools--org-ql-select-by-date
|
||||
:name "gptel-org-tools--org-ql-select-by-date"
|
||||
:description "Returns all timestamped headings matching query. Query may be: YYYY, YYYY-MM, YYYY-MM-DD."
|
||||
:function #'gptel-org-tools--org-ql-select-date
|
||||
:name "gptel-org-tools--org-ql-select-date"
|
||||
:args (list '(:name "buffer"
|
||||
:type string
|
||||
:description "Buffer name.")
|
||||
'(:name "date"
|
||||
:type string
|
||||
:description "Date string in YYYY or YYYY-MM format. No <, >, [, ]. Just the numbers and dashes."))
|
||||
:category "org"))
|
||||
:category "org"
|
||||
:description "Returns all timestamped headings and all of their subheadings matching query. Query may be: YYYY, YYYY-MM, YYYY-MM-DD.
|
||||
Examples:
|
||||
- \"YYYY\": gets all entries from year YYYY
|
||||
- \"YYYY-MM\": gets all entries from month MM of year YYYY"))
|
||||
#+end_src
|
||||
|
||||
***** org-agenda-seek
|
||||
|
@ -528,11 +538,11 @@ It works, in principle, but I haven't been able to find a use for it yet. The re
|
|||
(gptel-make-tool
|
||||
:function #'gptel-org-tools--org-agenda-seek
|
||||
:name "gptel-org-tools--org-agenda-seek"
|
||||
:description "Get user's agenda (tasking) spanning X days from now. This can be used to get all agenda tasks that are due or scheduled in the next X days, or in the past X days, depending on whether the days argument is positive or negative. Example: get all agenda tasks due in the next 7 days: \"7\""
|
||||
:args (list '(:name "days"
|
||||
:type integer
|
||||
:description "Days. Positive = future. Negative = past. Default: 14"))
|
||||
:category "org"))
|
||||
:category "org"
|
||||
:description "Return user's agenda (tasking) spanning X days from the current moment. This can be used to get all agenda tasks that are due or scheduled in the next X days, or in the past X days, depending on whether the days argument is positive or negative. Example: get all agenda tasks due in the next 7 days: \"7\""))
|
||||
#+end_src
|
||||
**** Completely WIP tools
|
||||
***** org-ql-select-headings
|
||||
|
@ -559,14 +569,14 @@ Retrieve the headings where the heading matches query. This is very much the sam
|
|||
(gptel-make-tool
|
||||
:function #'gptel-org-tools--org-ql-select-headings
|
||||
:name "gptel-org-tools--org-ql-select-headings"
|
||||
:description "Retreive matching headings from buffer. Matches only a single string. Using filename fails."
|
||||
:args (list '(:name "buffer"
|
||||
:type string
|
||||
:description "The name of the buffer. See the NAME column in ~list-buffers~.")
|
||||
'(:name "query"
|
||||
:type string
|
||||
:description "The string to match entry headings against."))
|
||||
:category "org-ql"))
|
||||
:category "org-ql"
|
||||
:description "Returns entries matching QUERY from BUFFER. Matches only a single string. After using this, evaluate which entries are relevant, and continue with user's request."))
|
||||
#+end_src
|
||||
|
||||
***** org-ql-select-headings-rifle
|
||||
|
@ -586,7 +596,7 @@ Retrieve all the headings where either heading or content matches query.
|
|||
(gptel-make-tool
|
||||
:function #'gptel-org-tools--org-ql-select-headings-rifle
|
||||
:name "gptel-org-tools--org-ql-select-headings-rifle"
|
||||
:description "Retreive headings from buffer using org-ql-select. Matches against both heading and content. Using filename fails."
|
||||
:description "Returns headings matching QUERY from BUFFER. Matches against both heading and content, but only returns headings. After using this, continue completing user's request."
|
||||
:args (list '(:name "buffer"
|
||||
:type string
|
||||
:description "The name of the buffer. See the NAME column in ~list-buffers~.")
|
||||
|
@ -619,14 +629,14 @@ This pulls all the headings (and their contents) when they match tags (without i
|
|||
(gptel-make-tool
|
||||
:function #'gptel-org-tools--org-ql-select-tags-local
|
||||
:name "gptel-org-tools--org-ql-select-tags-local"
|
||||
:description "Run org-ql-select-tags-local against buffer with query. No tag inheritance."
|
||||
:args (list '(:name "buffer"
|
||||
:type string
|
||||
:description "The name of the buffer. See the NAME column in `list-buffers`. Using filename fails.")
|
||||
'(:name "query"
|
||||
:type string
|
||||
:description "The string match entry tags against."))
|
||||
:category "org-ql"))
|
||||
:category "org-ql"
|
||||
:description "Returns entries whose tags match QUERY from BUFFER, without tag inheritance. After using this, evaluate results for relevance, and proceed with completing user's request."))
|
||||
#+end_src
|
||||
|
||||
***** org-ql-select-tags-local-count
|
||||
|
@ -649,14 +659,14 @@ This pulls all the local tags (without inheritance) from buffer, and returns the
|
|||
(gptel-make-tool
|
||||
:function #'gptel-org-tools--org-ql-select-tags-local-count
|
||||
:name "gptel-org-tools--org-ql-select-tags-local"
|
||||
:description "Get count of matching tags from buffer. No tag inheritance."
|
||||
:args (list '(:name "buffer"
|
||||
:type string
|
||||
:description "The name of the buffer. See the NAME column in `list-buffers`. Using filename fails.")
|
||||
'(:name "query"
|
||||
:type string
|
||||
:description "The string match entry tags against."))
|
||||
:category "org-ql"))
|
||||
:category "org-ql"
|
||||
:description "Returns count of entries tagged with tag QUERY from BUFFER, without tag inheritance."))
|
||||
#+end_src
|
||||
|
||||
***** org-ql-select-tags
|
||||
|
@ -681,14 +691,14 @@ This pulls all the headings (and their contents) when they match tags (with inhe
|
|||
(gptel-make-tool
|
||||
:function #'gptel-org-tools--org-ql-select-tags
|
||||
:name "gptel-org-tools--org-ql-select-tags"
|
||||
:description "Run org-ql-select-tags against buffer with query. Supports tag inheritance."
|
||||
:args (list '(:name "buffer"
|
||||
:type string
|
||||
:description "The name of the buffer. See the NAME column in `list-buffers`. Using filename fails.")
|
||||
'(:name "query"
|
||||
:type string
|
||||
:description "The string to match entry headings against."))
|
||||
:category "org-ql"))
|
||||
:category "org-ql"
|
||||
:description "Returns entries tagged QUERY from BUFFER, with tag inheritance."))
|
||||
#+end_src
|
||||
|
||||
***** org-ql-select-rifle
|
||||
|
@ -713,14 +723,14 @@ And, the "grab everything that matches" tool.
|
|||
(gptel-make-tool
|
||||
:function #'gptel-org-tools--org-ql-select-rifle
|
||||
:name "gptel-org-tools--org-ql-select-rifle"
|
||||
:description "Run org-ql-select-rifle against buffer with query."
|
||||
:args (list '(:name "buffer"
|
||||
:type string
|
||||
:description "The name of the buffer. See the NAME column in `list-buffers`. Using filename fails.")
|
||||
'(:name "query"
|
||||
:type string
|
||||
:description "A single string to search for."))
|
||||
:category "org-ql"))
|
||||
:category "org-ql"
|
||||
:description "Returns entries (heading and body) matching QUERY from BUFFER. This may pull too many results, only use if other tools fail."))
|
||||
#+end_src
|
||||
|
||||
***** org-ql-select-all-tags-local
|
||||
|
@ -741,11 +751,11 @@ This pulls all the headings (and their contents) when they match tags (without i
|
|||
(gptel-make-tool
|
||||
:function #'gptel-org-tools--org-ql-select-all-tags-local
|
||||
:name "gptel-org-tools--org-ql-select-all-tags-local"
|
||||
:description "Run single string query against all files in (org-agenda-files). WITHOUT tag inheritance, only directly tagged headings."
|
||||
:args (list '(:name "query"
|
||||
:type string
|
||||
:description "A single word to scan for."))
|
||||
:category "org-ql"))
|
||||
:category "org-ql"
|
||||
:description "Returns entries whose tags match QUERY from all files, without tag inheritance. After using this, evaluate results for relevance, and proceed with completing user's request."))
|
||||
#+end_src
|
||||
|
||||
***** org-ql-select-all-tags
|
||||
|
@ -766,11 +776,11 @@ with inheritance, in org-agenda-files.
|
|||
(gptel-make-tool
|
||||
:function #'gptel-org-tools--org-ql-select-all-tags
|
||||
:name "gptel-org-tools--org-ql-select-all-tags"
|
||||
:description "Run single string query against all files in (org-agenda-files). WITH tag inheritance."
|
||||
:args (list '(:name "query"
|
||||
:type string
|
||||
:description "A simple (single) string to scan for."))
|
||||
:category "org-ql"))
|
||||
:category "org-ql"
|
||||
:description "Returns entries whose tags match QUERY from BUFFER, with tag inheritance. After using this, evaluate results for relevance, and proceed with completing user's request."))
|
||||
#+end_src
|
||||
|
||||
***** org-ql-select-all-rifle
|
||||
|
@ -803,7 +813,8 @@ This means that /every org-mode file I have/ is part of this search. If you're u
|
|||
:args (list '(:name "query"
|
||||
:type string
|
||||
:description "The string to match entry headings and content against."))
|
||||
:category "org-ql"))
|
||||
:category "org-ql"
|
||||
:description "Returns entries matching QUERY from all files. After using this, evaluate results for relevance, and proceed with completing user's request." ))
|
||||
#+end_src
|
||||
|
||||
|
||||
|
@ -827,7 +838,8 @@ This means that /every org-mode file I have/ is part of this search. If you're u
|
|||
:args (list '(:name "query"
|
||||
:type string
|
||||
:description "Regexp, Emacs Lisp format. Automatically wrapped in a word boundary by the tool."))
|
||||
:category "org-ql"))
|
||||
:category "org-ql"
|
||||
:description "Returns entries matching regexp QUERY from BUFFER. After using this, evaluate results for relevance, and proceed with completing user's request. The regexp *must* be in Emacs rx format!" ))
|
||||
#+end_src
|
||||
|
||||
** End
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
|
||||
(defvar gptel-org-tools-skip-heading-extraction '())
|
||||
|
||||
(defvar gptel-org-tools-result-limit 20000)
|
||||
(defvar gptel-org-tools-result-limit 40000)
|
||||
|
||||
(defun gptel-org-tools--result-limit (result)
|
||||
(if (>= (length (format "%s" result)) gptel-org-tools-result-limit)
|
||||
|
@ -46,12 +46,14 @@
|
|||
result))
|
||||
|
||||
(defun gptel-org-tools--heading ()
|
||||
"Return the org-mode heading."
|
||||
(concat
|
||||
(buffer-substring-no-properties
|
||||
(line-beginning-position)
|
||||
(line-end-position))))
|
||||
|
||||
(defun gptel-org-tools--heading-body ()
|
||||
"Return the org-mode heading and body text."
|
||||
(concat
|
||||
(buffer-substring-no-properties
|
||||
(line-beginning-position)
|
||||
|
@ -60,6 +62,7 @@
|
|||
(line-beginning-position)))))
|
||||
|
||||
(defun gptel-org-tools--heading-subtree ()
|
||||
"Return the org-mode heading and all subheadings, with their body text."
|
||||
(concat
|
||||
(buffer-substring-no-properties
|
||||
(line-beginning-position)
|
||||
|
@ -76,12 +79,12 @@
|
|||
(gptel-make-tool
|
||||
:function #'gptel-org-tool--list-buffers
|
||||
:name "gptel-org-tool--list-buffers"
|
||||
:description "Access the list of buffers open in Emacs, including file names and full paths."
|
||||
:args (list '(:name "arg"
|
||||
:type string
|
||||
:description "Does nothing."
|
||||
:optional t))
|
||||
:category "emacs"))
|
||||
:category "emacs"
|
||||
:description "List buffers open in Emacs, including file names and full paths. After using this, evaluate which files are most likely to be relevant to the user's request."))
|
||||
|
||||
(defun gptel-org-tools--dir (dir)
|
||||
"Return directory listing."
|
||||
|
@ -95,7 +98,7 @@
|
|||
(gptel-make-tool
|
||||
:function #'gptel-org-tools--dir
|
||||
:name "gptel-org-tools--dir"
|
||||
:description "List directory contents"
|
||||
:description "List directory contents."
|
||||
:args (list '(:name "dir"
|
||||
:type string
|
||||
:description "Directory path"
|
||||
|
@ -124,13 +127,13 @@
|
|||
(let ((symbol (intern var)))
|
||||
(if (boundp symbol)
|
||||
(prin1-to-string (symbol-value symbol))
|
||||
(format "Variable %s is not bound." var))))
|
||||
(format "Variable %s is not bound. This means the variable doesn't exist. Reassess what you're trying to do, examine the situation, and continue. " var))))
|
||||
|
||||
(add-to-list 'gptel-org-tools
|
||||
(gptel-make-tool
|
||||
:function #'gptel-org-tools--describe-variable
|
||||
:name "gptel-org-tools--describe-variable"
|
||||
:description "See variable contents"
|
||||
:description "Returns variable contents."
|
||||
:args (list '(:name "var"
|
||||
:type string
|
||||
:description "Variable name"))
|
||||
|
@ -147,7 +150,7 @@
|
|||
(gptel-make-tool
|
||||
:function #'gptel-org-tools--describe-function
|
||||
:name "gptel-org-tools--describe-function"
|
||||
:description "See function description"
|
||||
:description "Returns function description"
|
||||
:args (list '(:name "fun"
|
||||
:type string
|
||||
:description "Function name"
|
||||
|
@ -171,16 +174,16 @@
|
|||
(gptel-make-tool
|
||||
:function #'gptel-org-tools--org-extract-tags
|
||||
:name "gptel-org-tools--org-extract-tags"
|
||||
:description "Extract all unique tags from an org-mode buffer"
|
||||
:args (list '(:name "buffer"
|
||||
:type string
|
||||
:description "The Org buffer to extract tags from."))
|
||||
:category "org-mode"))
|
||||
:category "org-mode"
|
||||
:description "Returns all tags from an org-mode buffer. When using this, evaluate the relevance of each tag to the user's request."))
|
||||
|
||||
(defun gptel-org-tools--org-extract-headings (buffer)
|
||||
"Return all headings from BUFFER."
|
||||
(if (member buffer gptel-org-tools-skip-heading-extraction)
|
||||
(user-error "Buffer %s has too many headings, use org-extract-tags or org-ql-select-rifle." buffer)
|
||||
(user-error "Buffer %s has been blocked from this function by the user with reason: headings contain timestamps, no useful information. Use a different tool." buffer)
|
||||
(with-current-buffer buffer
|
||||
(org-map-entries
|
||||
#'gptel-org-tools--heading
|
||||
|
@ -191,13 +194,13 @@
|
|||
(gptel-make-tool
|
||||
:function #'gptel-org-tools--org-extract-headings
|
||||
:name "gptel-org-tools--org-extract-headings"
|
||||
:description "Extract all headings from an org-mode buffer"
|
||||
:description "Returns all headings from an org-mode buffer. After using this, evaluate the relevance of the headings to the user's request."
|
||||
:args (list '(:name "buffer"
|
||||
:type string
|
||||
:description "The Org buffer to extract headings from."))
|
||||
:category "org-mode"))
|
||||
|
||||
(defun gptel-org-tools--org-ql-select-by-date (buf date)
|
||||
(defun gptel-org-tools--org-ql-select-date (buf date)
|
||||
"Returns all timestamped headings matching the specified date or date range.
|
||||
The date can be in the format YYYY, YYYY-MM, or YYYY-MM-DD.
|
||||
|
||||
|
@ -208,26 +211,30 @@ DATE is the date or date range to match."
|
|||
(if (bufferp buffer)
|
||||
(if (eq mode 'org-mode)
|
||||
(let ((result
|
||||
(org-ql-select buffer
|
||||
(concat
|
||||
(org-ql-select buffer
|
||||
`(heading ,date)
|
||||
:action #'gptel-org-tools--heading-subtree)))
|
||||
(gptel-org-tools--result-limit result))
|
||||
:action #'gptel-org-tools--heading-subtree)
|
||||
"Results end here. Proceed with the next action.")))
|
||||
(gptel-org-tools--result-limit result))
|
||||
(message "Buffer '%s' isn't an org-mode buffer." buf))
|
||||
(message "Buffer '%s' does not exist." buf))))
|
||||
|
||||
|
||||
(add-to-list 'gptel-org-tools
|
||||
(gptel-make-tool
|
||||
:function #'gptel-org-tools--org-ql-select-by-date
|
||||
:name "gptel-org-tools--org-ql-select-by-date"
|
||||
:description "Returns all timestamped headings matching query. Query may be: YYYY, YYYY-MM, YYYY-MM-DD."
|
||||
:function #'gptel-org-tools--org-ql-select-date
|
||||
:name "gptel-org-tools--org-ql-select-date"
|
||||
:args (list '(:name "buffer"
|
||||
:type string
|
||||
:description "Buffer name.")
|
||||
'(:name "date"
|
||||
:type string
|
||||
:description "Date string in YYYY or YYYY-MM format. No <, >, [, ]. Just the numbers and dashes."))
|
||||
:category "org"))
|
||||
:category "org"
|
||||
:description "Returns all timestamped headings and all of their subheadings matching query. Query may be: YYYY, YYYY-MM, YYYY-MM-DD.
|
||||
Examples:
|
||||
- \"YYYY\": gets all entries from year YYYY
|
||||
- \"YYYY-MM\": gets all entries from month MM of year YYYY"))
|
||||
|
||||
(defun gptel-org-tools--org-agenda-seek (days)
|
||||
"Return the results of org-agenda-list spanning now to DAYS."
|
||||
|
@ -241,11 +248,11 @@ DATE is the date or date range to match."
|
|||
(gptel-make-tool
|
||||
:function #'gptel-org-tools--org-agenda-seek
|
||||
:name "gptel-org-tools--org-agenda-seek"
|
||||
:description "Get user's agenda (tasking) spanning X days from now. This can be used to get all agenda tasks that are due or scheduled in the next X days, or in the past X days, depending on whether the days argument is positive or negative. Example: get all agenda tasks due in the next 7 days: \"7\""
|
||||
:args (list '(:name "days"
|
||||
:type integer
|
||||
:description "Days. Positive = future. Negative = past. Default: 14"))
|
||||
:category "org"))
|
||||
:category "org"
|
||||
:description "Return user's agenda (tasking) spanning X days from the current moment. This can be used to get all agenda tasks that are due or scheduled in the next X days, or in the past X days, depending on whether the days argument is positive or negative. Example: get all agenda tasks due in the next 7 days: \"7\""))
|
||||
|
||||
(defun gptel-org-tools--org-ql-select-headings (buf query)
|
||||
"Return headings matching QUERY from BUFFER."
|
||||
|
@ -268,14 +275,14 @@ DATE is the date or date range to match."
|
|||
(gptel-make-tool
|
||||
:function #'gptel-org-tools--org-ql-select-headings
|
||||
:name "gptel-org-tools--org-ql-select-headings"
|
||||
:description "Retreive matching headings from buffer. Matches only a single string. Using filename fails."
|
||||
:args (list '(:name "buffer"
|
||||
:type string
|
||||
:description "The name of the buffer. See the NAME column in ~list-buffers~.")
|
||||
'(:name "query"
|
||||
:type string
|
||||
:description "The string to match entry headings against."))
|
||||
:category "org-ql"))
|
||||
:category "org-ql"
|
||||
:description "Returns entries matching QUERY from BUFFER. Matches only a single string. After using this, evaluate which entries are relevant, and continue with user's request."))
|
||||
|
||||
(defun gptel-org-tools--org-ql-select-headings-rifle (buf query)
|
||||
"Return headings of entries (body included) that match keyword QUERY from BUFFER."
|
||||
|
@ -291,7 +298,7 @@ DATE is the date or date range to match."
|
|||
(gptel-make-tool
|
||||
:function #'gptel-org-tools--org-ql-select-headings-rifle
|
||||
:name "gptel-org-tools--org-ql-select-headings-rifle"
|
||||
:description "Retreive headings from buffer using org-ql-select. Matches against both heading and content. Using filename fails."
|
||||
:description "Returns headings matching QUERY from BUFFER. Matches against both heading and content, but only returns headings. After using this, continue completing user's request."
|
||||
:args (list '(:name "buffer"
|
||||
:type string
|
||||
:description "The name of the buffer. See the NAME column in ~list-buffers~.")
|
||||
|
@ -320,14 +327,14 @@ DATE is the date or date range to match."
|
|||
(gptel-make-tool
|
||||
:function #'gptel-org-tools--org-ql-select-tags-local
|
||||
:name "gptel-org-tools--org-ql-select-tags-local"
|
||||
:description "Run org-ql-select-tags-local against buffer with query. No tag inheritance."
|
||||
:args (list '(:name "buffer"
|
||||
:type string
|
||||
:description "The name of the buffer. See the NAME column in `list-buffers`. Using filename fails.")
|
||||
'(:name "query"
|
||||
:type string
|
||||
:description "The string match entry tags against."))
|
||||
:category "org-ql"))
|
||||
:category "org-ql"
|
||||
:description "Returns entries whose tags match QUERY from BUFFER, without tag inheritance. After using this, evaluate results for relevance, and proceed with completing user's request."))
|
||||
|
||||
(defun gptel-org-tools--org-ql-select-tags-local-count (buf query)
|
||||
"Return count of entries tagged QUERY in BUFFER."
|
||||
|
@ -346,14 +353,14 @@ DATE is the date or date range to match."
|
|||
(gptel-make-tool
|
||||
:function #'gptel-org-tools--org-ql-select-tags-local-count
|
||||
:name "gptel-org-tools--org-ql-select-tags-local"
|
||||
:description "Get count of matching tags from buffer. No tag inheritance."
|
||||
:args (list '(:name "buffer"
|
||||
:type string
|
||||
:description "The name of the buffer. See the NAME column in `list-buffers`. Using filename fails.")
|
||||
'(:name "query"
|
||||
:type string
|
||||
:description "The string match entry tags against."))
|
||||
:category "org-ql"))
|
||||
:category "org-ql"
|
||||
:description "Returns count of entries tagged with tag QUERY from BUFFER, without tag inheritance."))
|
||||
|
||||
(defun gptel-org-tools--org-ql-select-tags (buf query)
|
||||
"Return every entry tagged QUERY from BUFFER."
|
||||
|
@ -374,14 +381,14 @@ DATE is the date or date range to match."
|
|||
(gptel-make-tool
|
||||
:function #'gptel-org-tools--org-ql-select-tags
|
||||
:name "gptel-org-tools--org-ql-select-tags"
|
||||
:description "Run org-ql-select-tags against buffer with query. Supports tag inheritance."
|
||||
:args (list '(:name "buffer"
|
||||
:type string
|
||||
:description "The name of the buffer. See the NAME column in `list-buffers`. Using filename fails.")
|
||||
'(:name "query"
|
||||
:type string
|
||||
:description "The string to match entry headings against."))
|
||||
:category "org-ql"))
|
||||
:category "org-ql"
|
||||
:description "Returns entries tagged QUERY from BUFFER, with tag inheritance."))
|
||||
|
||||
(defun gptel-org-tools--org-ql-select-rifle (buf query)
|
||||
"Return every entry matching keyword QUERY from BUFFER."
|
||||
|
@ -402,14 +409,14 @@ DATE is the date or date range to match."
|
|||
(gptel-make-tool
|
||||
:function #'gptel-org-tools--org-ql-select-rifle
|
||||
:name "gptel-org-tools--org-ql-select-rifle"
|
||||
:description "Run org-ql-select-rifle against buffer with query."
|
||||
:args (list '(:name "buffer"
|
||||
:type string
|
||||
:description "The name of the buffer. See the NAME column in `list-buffers`. Using filename fails.")
|
||||
'(:name "query"
|
||||
:type string
|
||||
:description "A single string to search for."))
|
||||
:category "org-ql"))
|
||||
:category "org-ql"
|
||||
:description "Returns entries (heading and body) matching QUERY from BUFFER. This may pull too many results, only use if other tools fail."))
|
||||
|
||||
(defun gptel-org-tools--org-ql-select-all-tags-local (query)
|
||||
"Return entries whose tags match QUERY in org-agenda-files.
|
||||
|
@ -426,11 +433,11 @@ DATE is the date or date range to match."
|
|||
(gptel-make-tool
|
||||
:function #'gptel-org-tools--org-ql-select-all-tags-local
|
||||
:name "gptel-org-tools--org-ql-select-all-tags-local"
|
||||
:description "Run single string query against all files in (org-agenda-files). WITHOUT tag inheritance, only directly tagged headings."
|
||||
:args (list '(:name "query"
|
||||
:type string
|
||||
:description "A single word to scan for."))
|
||||
:category "org-ql"))
|
||||
:category "org-ql"
|
||||
:description "Returns entries whose tags match QUERY from all files, without tag inheritance. After using this, evaluate results for relevance, and proceed with completing user's request."))
|
||||
|
||||
(defun gptel-org-tools--org-ql-select-all-tags (query)
|
||||
"Return entries whose tags match QUERY,
|
||||
|
@ -447,11 +454,11 @@ with inheritance, in org-agenda-files.
|
|||
(gptel-make-tool
|
||||
:function #'gptel-org-tools--org-ql-select-all-tags
|
||||
:name "gptel-org-tools--org-ql-select-all-tags"
|
||||
:description "Run single string query against all files in (org-agenda-files). WITH tag inheritance."
|
||||
:args (list '(:name "query"
|
||||
:type string
|
||||
:description "A simple (single) string to scan for."))
|
||||
:category "org-ql"))
|
||||
:category "org-ql"
|
||||
:description "Returns entries whose tags match QUERY from BUFFER, with tag inheritance. After using this, evaluate results for relevance, and proceed with completing user's request."))
|
||||
|
||||
(defun gptel-org-tools--org-ql-select-all-rifle (query)
|
||||
"Return entries containing QUERY from org-agenda-files.
|
||||
|
@ -471,7 +478,8 @@ with inheritance, in org-agenda-files.
|
|||
:args (list '(:name "query"
|
||||
:type string
|
||||
:description "The string to match entry headings and content against."))
|
||||
:category "org-ql"))
|
||||
:category "org-ql"
|
||||
:description "Returns entries matching QUERY from all files. After using this, evaluate results for relevance, and proceed with completing user's request." ))
|
||||
|
||||
(defun gptel-org-tools--org-ql-select-all-regexp (query)
|
||||
"Return all entries matching regexp QUERY in org-agenda-files.
|
||||
|
@ -491,7 +499,8 @@ with inheritance, in org-agenda-files.
|
|||
:args (list '(:name "query"
|
||||
:type string
|
||||
:description "Regexp, Emacs Lisp format. Automatically wrapped in a word boundary by the tool."))
|
||||
:category "org-ql"))
|
||||
:category "org-ql"
|
||||
:description "Returns entries matching regexp QUERY from BUFFER. After using this, evaluate results for relevance, and proceed with completing user's request. The regexp *must* be in Emacs rx format!" ))
|
||||
|
||||
(provide 'gptel-org-tools)
|
||||
;;; gptel-org-tools.el ends here
|
||||
|
|
Loading…
Add table
Reference in a new issue