Skip to content

Commit c6e2339

Browse files
committed
gptel: Presets can extend gptel-tools instead of replace
* gptel.el (gptel--apply-preset): Allow tool specifications in presets to be additions instead of a replacement. Presets are intended to be flexible enough to function in different roles: as option presets, but also as agents, permissions/capabilities and so on. Previously, applying a preset that includes a `:tools' specification would overwrite the current list of `gptel-tools'. This made it impossible to use presets as permissions. For example, we would like to give an LLM filesystem and web access by applying two presets: `@files @web do the thing` But each preset sets the value of `gptel-tools', so the effect of `files' is overwritten by `web'. Tools can now be specified in a preset by placing an optional `:append' key at the start, to extend the current value of gptel-tools: :tools '(:append "read-file" "create_file" ...) This change will persist, but the `:append' convention is experimental and subject to tweaking. (gptel-request): Update documentation and TODO markers. * gptel-transient.el (gptel--preset-mismatch-p): Account for `:append' when indicating preset mismatches in gptel's transient menus.
1 parent 1d89fb8 commit c6e2339

File tree

2 files changed

+29
-20
lines changed

2 files changed

+29
-20
lines changed

gptel-transient.el

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,10 +99,14 @@ For internal use only.")
9999
(eq gptel-backend val))
100100
(throw 'mismatch t)))
101101
((eq key :tools)
102-
(or (equal (sort val #'string-lessp)
103-
(sort (mapcar #'gptel-tool-name gptel-tools)
104-
#'string-lessp))
105-
(throw 'mismatch t)))
102+
(if (eq (car-safe val) :append)
103+
(cl-loop for name in (cdr val) ;preset tools contained in gptel-tools
104+
unless (memq (gptel-get-tool name) gptel-tools)
105+
do (throw 'mismatch t))
106+
(or (equal (sort val #'string-lessp) ;preset tools same as gptel-tools
107+
(sort (mapcar #'gptel-tool-name gptel-tools)
108+
#'string-lessp))
109+
(throw 'mismatch t))))
106110
(t (let* ((suffix (substring
107111
(if (symbolp key) (symbol-name key) key) 1))
108112
(sym (or (intern-soft (concat "gptel-" suffix))

gptel.el

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2291,6 +2291,7 @@ If PROMPT is
22912291
sending to the LLM.
22922292
- A list of strings, it is interpreted as a conversation, i.e. a
22932293
series of alternating user prompts and LLM responses.
2294+
(\"user msg 1\" \"llm msg 1\" \"user msg 2\" \"llm msg 2\" ...)
22942295
- nil but region is active, the region contents are used.
22952296
- nil, the current buffer's contents up to (point) are used.
22962297
Previous responses from the LLM are identified as responses.
@@ -2424,7 +2425,7 @@ model, backend or system prompt, or augmenting the prompt with
24242425
additional information (such as from a RAG engine).
24252426
24262427
- Synchronous transformers are called with zero or one argument, the
2427-
INFO plist for the request.
2428+
state machine for the request.
24282429
24292430
- Asynchronous transformers are called with two arguments, a callback
24302431
and the state machine. It should run the callback after finishing its
@@ -2469,6 +2470,7 @@ be used to rerun or continue the request at a later time."
24692470
((consp prompt)
24702471
;; (gptel--parse-list gptel-backend prompt)
24712472
(gptel--with-buffer-copy buffer nil nil
2473+
;; TEMP Decide on the annoated prompt-list format
24722474
(gptel--parse-list-and-insert prompt)
24732475
(current-buffer)))))
24742476
(info (list :data prompt-buffer
@@ -2485,8 +2487,8 @@ be used to rerun or continue the request at a later time."
24852487
(when dry-run (plist-put info :dry-run dry-run))
24862488
(setf (gptel-fsm-info fsm) info))
24872489

2488-
;; TEMP: Augment in separate let block to avoid overcapturing
2489-
;; FIXME(augment) Call augmentors with INFO, not FSM
2490+
;; TEMP: Augment in separate let block for now. Are we overcapturing?
2491+
;; FIXME(augment): Call augmentors with INFO, not FSM
24902492
(let ((info (gptel-fsm-info fsm)))
24912493
(with-current-buffer (plist-get info :data)
24922494
(setq-local gptel-prompt-transform-functions (plist-get info :transforms))
@@ -2507,7 +2509,7 @@ be used to rerun or continue the request at a later time."
25072509
(gptel--realize-query fsm)
25082510
(with-current-buffer (plist-get info :buffer) ;Apply prompt transformations
25092511
(gptel--update-status " Augmenting..." 'mode-line-emphasis))
2510-
;; TODO(augment): This needs to be converted into a linear callback
2512+
;; FIXME(augment): This needs to be converted into a linear callback
25112513
;; chain to avoid race conditions with multiple async augmentors.
25122514
(run-hook-wrapped
25132515
'gptel-prompt-transform-functions
@@ -3614,18 +3616,21 @@ example) apply the preset buffer-locally."
36143616
(user-error "gptel preset \"%s\": Cannot find backend %s."
36153617
(car preset) val))
36163618
(funcall setter 'gptel-backend val))
3617-
(:tools
3618-
(funcall
3619-
setter 'gptel-tools
3620-
(flatten-list
3621-
(cl-loop for tool-name in (ensure-list val)
3622-
for tool = (cl-etypecase tool-name
3623-
(gptel-tool tool-name)
3624-
(string (gptel-get-tool tool-name)))
3625-
do (unless tool
3626-
(user-error "gptel preset \"%s\": Cannot find tool %s."
3627-
(car preset) val))
3628-
collect tool))))
3619+
(:tools ;TEMP Confirm this `:append' convention
3620+
(let* ((append (when (eq (car-safe val) :append) (setq val (cdr val)) t))
3621+
(tools
3622+
(flatten-list
3623+
(cl-loop for tool-name in (ensure-list val)
3624+
for tool = (cl-etypecase tool-name
3625+
(gptel-tool tool-name)
3626+
(string (ignore-errors
3627+
(gptel-get-tool tool-name))))
3628+
do (unless tool
3629+
(user-error "gptel preset \"%s\": Cannot find tool %s."
3630+
(car preset) val))
3631+
collect tool))))
3632+
(funcall setter 'gptel-tools ;append makes a copy of gptel-tools, intentional
3633+
(if append (delete-dups (append gptel-tools tools)) tools))))
36293634
((and (let sym (or (intern-soft
36303635
(concat "gptel-" (substring (symbol-name key) 1)))
36313636
(intern-soft

0 commit comments

Comments
 (0)