@@ -760,19 +760,23 @@ Customize `gptel-directives' for task-specific prompts."
760
760
; ; ** Prefix for selecting tools
761
761
(defun gptel--completing-read-multiple-tools (prompt candidate-tools )
762
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 )
763
+ ; ; Without this, when duplicate values are selected in
764
+ ; ; `completing-read-multiple' , it will result in a circular-list error
765
+ (seq-uniq
766
+ (completing-read-multiple
767
+ prompt
768
+ (lambda (string pred action )
769
+ (if (eq action 'metadata )
770
+ '(metadata
771
+ ; ; (annotation-function . gptel-annotation-function)
772
+ (category . gptel-tool))
773
+ (complete-with-action
774
+ action
775
+ candidate-tools
776
+ string
777
+ pred)))
778
+ nil t )
779
+ #'string-equal )
776
780
nconc (alist-get selection candidate-tools nil nil #'string-equal )))
777
781
778
782
(transient-define-infix gptel--infix-set-tools ()
@@ -786,17 +790,22 @@ Customize `gptel-directives' for task-specific prompts."
786
790
:set-value #'gptel--set-with-scope
787
791
:key " tt"
788
792
: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 )))))))))
793
+ (seq-uniq
794
+ (append gptel-tools
795
+ (gptel--completing-read-multiple-tools
796
+ prompt
797
+ (let ((gptel-tools--names (mapcar (lambda (tool ) (gptel-tool-name tool)) gptel-tools)))
798
+ (cl-loop for (cat . tools-alist) in gptel--known-tools
799
+ for filtered-tools-alist = (cl-loop for (tool_name . tool) in tools-alist
800
+ unless (memq tool_name gptel-tools--names)
801
+ nconc
802
+ `(,(cons (concat cat " ::" tool_name)
803
+ `(, tool ))))
804
+ if (length> filtered-tools-alist 0 )
805
+ nconc `(,(cons cat
806
+ (flatten-list (map-values filtered-tools-alist))))
807
+ and nconc filtered-tools-alist))))
808
+ #'equal )))
800
809
801
810
(transient-define-infix gptel--infix-remove-tools ()
802
811
" Remove tools being used."
@@ -813,9 +822,17 @@ Customize `gptel-directives' for task-specific prompts."
813
822
gptel-tools
814
823
(gptel--completing-read-multiple-tools
815
824
prompt
816
- (mapcar (lambda (tool )
817
- (list (gptel-tool-name tool) tool))
818
- gptel-tools)))))
825
+ (let ((category-candidates))
826
+ (append
827
+ (mapcar
828
+ (lambda (tool )
829
+ (let ((category (gptel-tool-category tool)))
830
+ (push tool
831
+ (alist-get category category-candidates
832
+ nil nil #'string-equal ))
833
+ (list (concat category " ::" (gptel-tool-name tool)) tool)))
834
+ gptel-tools)
835
+ category-candidates))))))
819
836
820
837
(transient-define-infix gptel--infix-remove-all-tools ()
821
838
" Remove tools being used."
0 commit comments