branch: elpa/gptel
commit 0c32dbdbf4319b9d3cdd4302249d25c2a3495f1e
Author: Karthik Chikmagalur <[email protected]>
Commit: Karthik Chikmagalur <[email protected]>
gptel: Improve preset validation, modify-spec handling
* gptel.el (gptel--modify-value): Use keywordp instead of
checking for it the hard way. I keep forgetting that keywordp
exists. (Like car-safe, this is a weird choice of functions to
implement in C.)
* gptel-transient.el (gptel--preset-mismatch-p,
gptel--read-apply-preset): Set `gptel--preset' when applying a
preset via `completing-read'.
Try to handle modify-specs for :tools when checking if there is a
preset mismatch. Handle both tools and tool names in the :tools
spec correctly. (#1099)
Handling all possible modify-specs correctly in
`gptel--preset-mismatch-p' is impossible, or at least impractical.
For example, if a spec contains
:system (:function 'do-something)
where do-something is not idempotent, then we have nothing to
compare the current system message (which is
(do-something gptel--system-message))
against gptel--system-message.
---
gptel-transient.el | 23 +++++++++++++++--------
gptel.el | 4 +---
2 files changed, 16 insertions(+), 11 deletions(-)
diff --git a/gptel-transient.el b/gptel-transient.el
index 662fc5ed740..769d3982833 100644
--- a/gptel-transient.el
+++ b/gptel-transient.el
@@ -89,6 +89,8 @@ For internal use only.")
((memq key '(:description :parents)) 'nil)
((eq key :system)
(or (equal gptel--system-message val)
+ (functionp val) ; Ignore functions, modify-specs for speed
here
+ (and (consp val) (keywordp (car val)))
(and-let* (((symbolp val))
(p (assq val gptel-directives)))
(equal gptel--system-message (cdr p)))
@@ -99,18 +101,22 @@ For internal use only.")
(eq gptel-backend val))
(throw 'mismatch t)))
((eq key :tools)
- (if (eq (car-safe val) :append)
- (cl-loop for name in (cdr val) ;preset tools contained in
gptel-tools
- unless (memq (gptel-get-tool name) gptel-tools)
- do (throw 'mismatch t))
- (or (equal (sort val #'string-lessp) ;preset tools same as
gptel-tools
- (sort (mapcar #'gptel-tool-name gptel-tools)
- #'string-lessp))
- (throw 'mismatch t))))
+ (setq val (cl-loop ; Check against tool names, not tools (faster
with sorting)
+ for tool in (ensure-list (gptel--modify-value gptel-tools
val))
+ for tool-name = (or (and (stringp tool) tool)
+ (ignore-errors (gptel-tool-name
tool)))
+ if (not (member tool-name uniq-tool-names))
+ collect tool-name into uniq-tool-names
+ finally return uniq-tool-names))
+ (or (equal (sort val #'string-lessp) ;preset tools same as
gptel-tools?
+ (sort (mapcar #'gptel-tool-name gptel-tools)
+ #'string-lessp))
+ (throw 'mismatch t)))
(t (let* ((suffix (substring
(if (symbolp key) (symbol-name key) key) 1))
(sym (or (intern-soft (concat "gptel-" suffix))
(intern-soft (concat "gptel--" suffix)))))
+ ;; FIXME(modify-list): Fix for values specified with a spec,
like :eval
(or (null sym)
(and (boundp sym) (equal (eval sym) val))
(throw 'mismatch t)))))))))
@@ -530,6 +536,7 @@ which see."
('t "buffer-locally")
(_ "globally")))
gptel--known-presets nil t)))))
+ (gptel--set-with-scope 'gptel--preset name gptel--set-buffer-locally)
(gptel--apply-preset
name (lambda (sym val)
(gptel--set-with-scope sym val gptel--set-buffer-locally)))
diff --git a/gptel.el b/gptel.el
index 30dba91ccea..f6a15f1cf47 100644
--- a/gptel.el
+++ b/gptel.el
@@ -312,9 +312,7 @@ form it is returned as is.
- :function will call val with ORIGINAL as its argument, and return the result.
- :merge will treat ORIGINAL and NEW-SPEC as plists and return a merged plist,
with NEW-SPEC taking precedence."
- (if (not (and (consp new-spec)
- (symbolp (car new-spec))
- (string-prefix-p ":" (symbol-name (car new-spec)))))
+ (if (not (and (consp new-spec) (keywordp (car new-spec))))
new-spec
(let ((current original) (tail new-spec))
(while tail