@@ -563,6 +563,7 @@ Also format its value in the Transient menu."
563
563
(transient-define-prefix gptel-menu ()
564
564
" Change parameters of prompt to send to the LLM."
565
565
:incompatible '((" m" " y" " i" ) (" e" " g" " b" " k" ))
566
+ :refresh-suffixes t
566
567
; ; :value (list (concat "b" (buffer-name)))
567
568
[:description gptel-system-prompt--format
568
569
[" "
@@ -589,7 +590,11 @@ Also format its value in the Transient menu."
589
590
'face 'warning )
590
591
" )" ))))
591
592
:format " %d" :face transient-heading)
592
- (" t" " Select tools" gptel-tools :transient t )
593
+ (gptel--infix-set-tools)
594
+ (gptel--infix-remove-tools
595
+ :if (lambda () (length> gptel-tools 0 )))
596
+ (gptel--infix-remove-all-tools
597
+ :if (lambda () (length> gptel-tools 0 )))
593
598
(" T" " Continue tool calls"
594
599
(lambda () (interactive ) (gptel--handle-tool-use gptel--fsm-last))
595
600
:if (lambda () (and gptel--fsm-last
@@ -753,6 +758,76 @@ Customize `gptel-directives' for task-specific prompts."
753
758
:pad-keys t])
754
759
755
760
; ; ** Prefix for selecting tools
761
+ (defun gptel--completing-read-multiple-tools (prompt candidate-tools )
762
+ (cl-loop for selection in
763
+ (completing-read-multiple
764
+ prompt
765
+ (lambda (string pred action )
766
+ (if (eq action 'metadata )
767
+ '(metadata
768
+ ; ; (annotation-function . gptel-annotation-function)
769
+ (category . gptel-tool))
770
+ (complete-with-action
771
+ action
772
+ candidate-tools
773
+ string
774
+ pred)))
775
+ nil t )
776
+ nconc (alist-get selection candidate-tools nil nil #'string-equal )))
777
+
778
+ (transient-define-infix gptel--infix-set-tools ()
779
+ " Set tools to use."
780
+ :description " Select tools"
781
+ :class 'gptel-lisp-variable
782
+ :prompt " Select tools: "
783
+ :display-nil " "
784
+ :format " %k %d"
785
+ :variable 'gptel-tools
786
+ :set-value #'gptel--set-with-scope
787
+ :key " tt"
788
+ :reader (lambda (prompt &rest _ )
789
+ (append gptel-tools
790
+ (gptel--completing-read-multiple-tools
791
+ prompt
792
+ (cl-loop for (cat . tools-alist) in gptel--known-tools
793
+ nconc `(,(cons cat
794
+ (map-values tools-alist)))
795
+ nconc
796
+ (cl-loop for (tool_name . tool) in tools-alist
797
+ nconc
798
+ `(,(cons tool_name
799
+ `(, tool )))))))))
800
+
801
+ (transient-define-infix gptel--infix-remove-tools ()
802
+ " Remove tools being used."
803
+ :description " Remove tools"
804
+ :class 'gptel-lisp-variable
805
+ :prompt " Remove tools: "
806
+ :display-nil " none"
807
+ :format " %k %d"
808
+ :variable 'gptel-tools
809
+ :set-value #'gptel--set-with-scope
810
+ :key " tr"
811
+ :reader (lambda (prompt &rest _ )
812
+ (seq-difference
813
+ gptel-tools
814
+ (gptel--completing-read-multiple-tools
815
+ prompt
816
+ (mapcar (lambda (tool )
817
+ (list (gptel-tool-name tool) tool))
818
+ gptel-tools)))))
819
+
820
+ (transient-define-infix gptel--infix-remove-all-tools ()
821
+ " Remove tools being used."
822
+ :description " Remove tools"
823
+ :class 'gptel-lisp-variable
824
+ :prompt " Remove tools: "
825
+ :display-nil " none"
826
+ :format " %k %d"
827
+ :variable 'gptel-tools
828
+ :set-value (lambda (&rest _ ) (interactive ) (gptel--set-with-scope 'gptel-tools nil gptel--set-buffer-locally))
829
+ :key " tR"
830
+ :reader (lambda (&rest _ ) (interactive )))
756
831
757
832
;;;### autoload (autoload 'gptel-tools "gptel-transient" nil t)
758
833
(transient-define-prefix gptel-tools ()
0 commit comments