gptel: Make model parameters global
* gptel.el (gptel-backend, gptel-model, gptel-temperature, gptel-max-tokens, gptel--num-messages-to-send, gptel--system-message): Make all model/request paramters global variables, i.e. not buffer-local by default. This is following the discussion in #249. * gptel-transient.el (gptel-menu, gptel-system-prompt--setup, gptel-system-prompt, gptel--suffix-system-message, gptel--infix-provider, gptel--infix-temperature, gptel--switches, gptel--set-buffer-locally, gptel--set-with-scope): and associated transient methods: add a toggle `gptel--set-buffer-locally` to allow model parameters to be set buffer-locally. The function `gptel--set-with-scope` can be used to reset a variable or set it buffer-locally. Reorder gptel-transient so all the custom classes, methods and utility functions are at the top. * README.org (all backend sections): Replace `setq-default` with setq in the recommended configuration.
This commit is contained in:
parent
e3b3591d73
commit
5dcbf40066
3 changed files with 220 additions and 156 deletions
45
README.org
45
README.org
|
@ -160,10 +160,10 @@ You can pick this backend from the menu when using gptel. (see [[#usage][Usage]]
|
|||
|
||||
***** (Optional) Set as the default gptel backend
|
||||
|
||||
The above code makes the backend available to select. If you want it to be the default backend for gptel, you can set this as the default value of =gptel-backend=. Use this instead of the above.
|
||||
The above code makes the backend available to select. If you want it to be the default backend for gptel, you can set this as the value of =gptel-backend=. Use this instead of the above.
|
||||
#+begin_src emacs-lisp
|
||||
;; OPTIONAL configuration
|
||||
(setq-default
|
||||
(setq
|
||||
gptel-model "gpt-3.5-turbo"
|
||||
gptel-backend (gptel-make-azure "Azure-1"
|
||||
:protocol "https"
|
||||
|
@ -192,10 +192,10 @@ You can pick this backend from the menu when using gptel (see [[#usage][Usage]])
|
|||
|
||||
***** (Optional) Set as the default gptel backend
|
||||
|
||||
The above code makes the backend available to select. If you want it to be the default backend for gptel, you can set this as the default value of =gptel-backend=. Use this instead of the above. Additionally you may want to increase the response token size since GPT4All uses very short (often truncated) responses by default.
|
||||
The above code makes the backend available to select. If you want it to be the default backend for gptel, you can set this as the value of =gptel-backend=. Use this instead of the above. Additionally you may want to increase the response token size since GPT4All uses very short (often truncated) responses by default.
|
||||
#+begin_src emacs-lisp
|
||||
;; OPTIONAL configuration
|
||||
(setq-default
|
||||
(setq
|
||||
gptel-max-tokens 500
|
||||
gptel-model "mistral-7b-openorca.Q4_0.gguf"
|
||||
gptel-backend (gptel-make-gpt4all "GPT4All"
|
||||
|
@ -223,10 +223,10 @@ You can pick this backend from the menu when using gptel (see [[#usage][Usage]])
|
|||
|
||||
***** (Optional) Set as the default gptel backend
|
||||
|
||||
The above code makes the backend available to select. If you want it to be the default backend for gptel, you can set this as the default value of =gptel-backend=. Use this instead of the above.
|
||||
The above code makes the backend available to select. If you want it to be the default backend for gptel, you can set this as the value of =gptel-backend=. Use this instead of the above.
|
||||
#+begin_src emacs-lisp
|
||||
;; OPTIONAL configuration
|
||||
(setq-default
|
||||
(setq
|
||||
gptel-model "mistral:latest"
|
||||
gptel-backend (gptel-make-ollama "Ollama"
|
||||
:host "localhost:11434"
|
||||
|
@ -251,10 +251,10 @@ You can pick this backend from the menu when using gptel (see [[#usage][Usage]])
|
|||
|
||||
***** (Optional) Set as the default gptel backend
|
||||
|
||||
The above code makes the backend available to select. If you want it to be the default backend for gptel, you can set this as the default value of =gptel-backend=. Use this instead of the above.
|
||||
The above code makes the backend available to select. If you want it to be the default backend for gptel, you can set this as the value of =gptel-backend=. Use this instead of the above.
|
||||
#+begin_src emacs-lisp
|
||||
;; OPTIONAL configuration
|
||||
(setq-default
|
||||
(setq
|
||||
gptel-model "gemini-pro"
|
||||
gptel-backend (gptel-make-gemini "Gemini"
|
||||
:key "YOUR_GEMINI_API_KEY"
|
||||
|
@ -285,10 +285,10 @@ You can pick this backend from the menu when using gptel (see [[#usage][Usage]])
|
|||
|
||||
***** (Optional) Set as the default gptel backend
|
||||
|
||||
The above code makes the backend available to select. If you want it to be the default backend for gptel, you can set this as the default value of =gptel-backend=. Use this instead of the above.
|
||||
The above code makes the backend available to select. If you want it to be the default backend for gptel, you can set this as the value of =gptel-backend=. Use this instead of the above.
|
||||
#+begin_src emacs-lisp
|
||||
;; OPTIONAL configuration
|
||||
(setq-default
|
||||
(setq
|
||||
gptel-model "test"
|
||||
gptel-backend (gptel-make-openai "llama-cpp"
|
||||
:stream t
|
||||
|
@ -319,10 +319,10 @@ You can pick this backend and the model (fastgpt/summarizer) from the transient
|
|||
|
||||
***** (Optional) Set as the default gptel backend
|
||||
|
||||
The above code makes the backend available to select. If you want it to be the default backend for gptel, you can set this as the default value of =gptel-backend=. Use this instead of the above.
|
||||
The above code makes the backend available to select. If you want it to be the default backend for gptel, you can set this as the value of =gptel-backend=. Use this instead of the above.
|
||||
#+begin_src emacs-lisp
|
||||
;; OPTIONAL configuration
|
||||
(setq-default
|
||||
(setq
|
||||
gptel-model "fastgpt"
|
||||
gptel-backend (gptel-make-kagi "Kagi"
|
||||
:key "YOUR_KAGI_API_KEY"))
|
||||
|
@ -352,10 +352,10 @@ You can pick this backend from the menu when using gptel (see [[#usage][Usage]])
|
|||
|
||||
***** (Optional) Set as the default gptel backend
|
||||
|
||||
The above code makes the backend available to select. If you want it to be the default backend for gptel, you can set this as the default value of =gptel-backend=. Use this instead of the above.
|
||||
The above code makes the backend available to select. If you want it to be the default backend for gptel, you can set this as the value of =gptel-backend=. Use this instead of the above.
|
||||
#+begin_src emacs-lisp
|
||||
;; OPTIONAL configuration
|
||||
(setq-default
|
||||
(setq
|
||||
gptel-model "mistralai/Mixtral-8x7B-Instruct-v0.1"
|
||||
gptel-backend
|
||||
(gptel-make-openai "TogetherAI"
|
||||
|
@ -387,10 +387,10 @@ You can pick this backend from the menu when using gptel (see [[#usage][Usage]])
|
|||
|
||||
***** (Optional) Set as the default gptel backend
|
||||
|
||||
The above code makes the backend available to select. If you want it to be the default backend for gptel, you can set this as the default value of =gptel-backend=. Use this instead of the above.
|
||||
The above code makes the backend available to select. If you want it to be the default backend for gptel, you can set this as the value of =gptel-backend=. Use this instead of the above.
|
||||
#+begin_src emacs-lisp
|
||||
;; OPTIONAL configuration
|
||||
(setq-default
|
||||
(setq
|
||||
gptel-model "mistralai/Mixtral-8x7B-Instruct-v0.1"
|
||||
gptel-backend
|
||||
(gptel-make-openai "Anyscale"
|
||||
|
@ -424,10 +424,10 @@ You can pick this backend from the menu when using gptel (see [[#usage][Usage]])
|
|||
|
||||
***** (Optional) Set as the default gptel backend
|
||||
|
||||
The above code makes the backend available to select. If you want it to be the default backend for gptel, you can set this as the default value of =gptel-backend=. Use this instead of the above.
|
||||
The above code makes the backend available to select. If you want it to be the default backend for gptel, you can set this as the value of =gptel-backend=. Use this instead of the above.
|
||||
#+begin_src emacs-lisp
|
||||
;; OPTIONAL configuration
|
||||
(setq-default
|
||||
(setq
|
||||
gptel-model "pplx-7b-chat"
|
||||
gptel-backend
|
||||
(gptel-make-openai "Perplexity"
|
||||
|
@ -458,10 +458,10 @@ You can pick this backend from the menu when using gptel (see [[#usage][Usage]])
|
|||
|
||||
***** (Optional) Set as the default gptel backend
|
||||
|
||||
The above code makes the backend available to select. If you want it to be the default backend for gptel, you can set this as the default value of =gptel-backend=. Use this instead of the above.
|
||||
The above code makes the backend available to select. If you want it to be the default backend for gptel, you can set this as the value of =gptel-backend=. Use this instead of the above.
|
||||
#+begin_src emacs-lisp
|
||||
;; OPTIONAL configuration
|
||||
(setq-default
|
||||
(setq
|
||||
gptel-model "claude-3-sonnet-20240229" ; "claude-3-opus-20240229" also available
|
||||
gptel-backend (gptel-make-anthropic "Claude"
|
||||
:stream t :key "your-api-key"))
|
||||
|
@ -489,11 +489,10 @@ You can pick this backend from the menu when using gptel (see [[#usage][Usage]])
|
|||
|
||||
***** (Optional) Set as the default gptel backend
|
||||
|
||||
The above code makes the backend available to select. If you want it to be the default backend for gptel, you can set this as the default value of =gptel-backend=. Use this instead of the above.
|
||||
The above code makes the backend available to select. If you want it to be the default backend for gptel, you can set this as the value of =gptel-backend=. Use this instead of the above.
|
||||
#+begin_src emacs-lisp
|
||||
;; OPTIONAL configuration
|
||||
(setq-default
|
||||
gptel-model "mixtral-8x7b-32768"
|
||||
(setq gptel-model "mixtral-8x7b-32768"
|
||||
gptel-backend
|
||||
(gptel-make-openai "Groq"
|
||||
:host "api.groq.com"
|
||||
|
|
|
@ -33,7 +33,61 @@
|
|||
(declare-function ediff-make-cloned-buffer "ediff-utils")
|
||||
|
||||
|
||||
;; * Helper functions
|
||||
;; * Helper functions and vars
|
||||
|
||||
(defvar gptel--set-buffer-locally nil
|
||||
"Set model parameters from `gptel-menu' buffer-locally.
|
||||
|
||||
Affects the system message too.")
|
||||
|
||||
(defun gptel--set-with-scope (sym value &optional scope)
|
||||
"Set SYMBOL's symbol-value to VALUE with SCOPE.
|
||||
|
||||
If SCOPE is non-nil, set it buffer-locally, else clear any
|
||||
buffer-local value and set its default global value."
|
||||
(if scope
|
||||
(set (make-local-variable sym) value)
|
||||
(kill-local-variable sym)
|
||||
(set sym value)))
|
||||
|
||||
(defun gptel--get-directive (args)
|
||||
"Find the additional directive in the transient ARGS.
|
||||
|
||||
Meant to be called when `gptel-menu' is active."
|
||||
(cl-some (lambda (s) (and (stringp s) (string-prefix-p ":" s)
|
||||
(concat "\n\n" (substring s 1))))
|
||||
args))
|
||||
|
||||
(defun gptel--instructions-make-overlay (text &optional ov)
|
||||
"TODO"
|
||||
(save-excursion
|
||||
(cond
|
||||
((use-region-p) (goto-char (region-beginning)))
|
||||
((gptel--in-response-p) (gptel-beginning-of-response))
|
||||
(t (text-property-search-backward 'gptel 'response)))
|
||||
(skip-chars-forward "\n \t")
|
||||
(if (and ov (overlayp ov))
|
||||
(move-overlay ov (point) (point) (current-buffer))
|
||||
(setq ov (make-overlay (point) (point) nil t)))
|
||||
(overlay-put ov 'before-string nil)
|
||||
;; (unless (or (bobp) (eq (char-before) "\n"))
|
||||
;; (overlay-put ov 'before-string (propertize "\n" 'font-lock-face 'shadow)))
|
||||
(overlay-put ov 'category 'gptel)
|
||||
(overlay-put
|
||||
ov 'after-string
|
||||
(concat
|
||||
(propertize (concat "GPTEL: " text)
|
||||
'font-lock-face '(:inherit shadow :box t))
|
||||
"\n"))
|
||||
ov))
|
||||
|
||||
(defun gptel--transient-read-variable (prompt initial-input history)
|
||||
"Read value from minibuffer and interpret the result as a Lisp object.
|
||||
|
||||
PROMPT, INITIAL-INPUT and HISTORY are as in the Transient reader
|
||||
documention."
|
||||
(ignore-errors
|
||||
(read-from-minibuffer prompt initial-input read-expression-map t history)))
|
||||
|
||||
(defun gptel--refactor-or-rewrite ()
|
||||
"Rewrite should be refactored into refactor.
|
||||
|
@ -105,6 +159,100 @@ which see."
|
|||
(forward-line 1)))))
|
||||
gptel--crowdsourced-prompts))
|
||||
|
||||
|
||||
;; * Transient classes and methods for gptel
|
||||
|
||||
(defclass gptel--switches (transient-lisp-variable)
|
||||
((display-if-true :initarg :display-if-true :initform "for this buffer")
|
||||
(display-if-false :initarg :display-if-false :initform "globally"))
|
||||
"Boolean lisp variable class for gptel-transient.")
|
||||
|
||||
(cl-defmethod transient-infix-read ((obj gptel--switches))
|
||||
"Cycle through the mutually exclusive switches."
|
||||
(not (oref obj value)))
|
||||
|
||||
(cl-defmethod transient-format-value ((obj gptel--switches))
|
||||
(with-slots (value display-if-true display-if-false) obj
|
||||
(format
|
||||
(propertize "(%s)" 'face 'transient-delimiter)
|
||||
(concat
|
||||
(propertize display-if-false
|
||||
'face (if value 'transient-inactive-value 'transient-value))
|
||||
(propertize "|" 'face 'transient-delimiter)
|
||||
(propertize display-if-true
|
||||
'face (if value 'transient-value 'transient-inactive-value))))))
|
||||
|
||||
(defclass gptel-lisp-variable (transient-lisp-variable)
|
||||
((display-nil :initarg :display-nil))
|
||||
"Lisp variables that show :display-nil instead of nil.")
|
||||
|
||||
(cl-defmethod transient-format-value
|
||||
((obj gptel-lisp-variable))
|
||||
(propertize (prin1-to-string (or (oref obj value)
|
||||
(oref obj display-nil)))
|
||||
'face 'transient-value))
|
||||
|
||||
(cl-defmethod transient-infix-set ((obj gptel-lisp-variable) value)
|
||||
(funcall (oref obj set-value)
|
||||
(oref obj variable)
|
||||
(oset obj value value)
|
||||
gptel--set-buffer-locally))
|
||||
|
||||
(defclass gptel-provider-variable (transient-lisp-variable)
|
||||
((model :initarg :model)
|
||||
(model-value :initarg :model-value)
|
||||
(always-read :initform t)
|
||||
(set-value :initarg :set-value :initform #'set))
|
||||
"Class used for gptel-backends.")
|
||||
|
||||
(cl-defmethod transient-format-value ((obj gptel-provider-variable))
|
||||
(propertize (concat (gptel-backend-name (oref obj value)) ":"
|
||||
(buffer-local-value (oref obj model) transient--original-buffer))
|
||||
'face 'transient-value))
|
||||
|
||||
(cl-defmethod transient-infix-set ((obj gptel-provider-variable) value)
|
||||
(pcase-let ((`(,backend-value ,model-value) value))
|
||||
(funcall (oref obj set-value)
|
||||
(oref obj variable)
|
||||
(oset obj value backend-value)
|
||||
gptel--set-buffer-locally)
|
||||
(funcall (oref obj set-value)
|
||||
(oref obj model)
|
||||
(oset obj model-value model-value)
|
||||
gptel--set-buffer-locally)))
|
||||
|
||||
(defclass gptel-option-overlaid (transient-option)
|
||||
((display-nil :initarg :display-nil)
|
||||
(overlay :initarg :overlay))
|
||||
"Transient options for overlays displayed in the working buffer.")
|
||||
|
||||
(cl-defmethod transient-format-value ((obj gptel-option-overlaid))
|
||||
"set up the in-buffer overlay for additional directive, a string.
|
||||
|
||||
Also format its value in the Transient menu."
|
||||
(let ((value (oref obj value))
|
||||
(ov (oref obj overlay))
|
||||
(argument (oref obj argument)))
|
||||
;; Making an overlay
|
||||
(if (or (not value) (string-empty-p value))
|
||||
(when ov (delete-overlay ov))
|
||||
(with-current-buffer transient--original-buffer
|
||||
(oset obj overlay (gptel--instructions-make-overlay value ov)))
|
||||
(letrec ((ov-clear-hook
|
||||
(lambda () (when-let* ((ov (oref obj overlay))
|
||||
((overlayp ov)))
|
||||
(remove-hook 'transient-exit-hook
|
||||
ov-clear-hook)
|
||||
(delete-overlay ov)))))
|
||||
(add-hook 'transient-exit-hook ov-clear-hook)))
|
||||
;; Updating transient menu display
|
||||
(if value
|
||||
(propertize (concat argument (truncate-string-to-width value 25 nil nil "..."))
|
||||
'face 'transient-value)
|
||||
(propertize
|
||||
(concat "(" (symbol-name (oref obj display-nil)) ")")
|
||||
'face 'transient-inactive-value))))
|
||||
|
||||
|
||||
;; * Transient Prefixes
|
||||
|
||||
|
@ -120,12 +268,14 @@ which see."
|
|||
(string-replace
|
||||
"\n" "⮐ "
|
||||
(truncate-string-to-width
|
||||
gptel--system-message (max (- (window-width) 6) 14) nil nil t)))
|
||||
gptel--system-message (max (- (window-width) 12) 14) nil nil t)))
|
||||
[""
|
||||
"Instructions"
|
||||
("s" "Set system message" gptel-system-prompt :transient t)
|
||||
(gptel--infix-add-directive)]]
|
||||
[["Model Parameters"
|
||||
[[:pad-keys t
|
||||
"Model Parameters"
|
||||
(gptel--infix-variable-scope)
|
||||
(gptel--infix-provider)
|
||||
(gptel--infix-max-tokens)
|
||||
(gptel--infix-num-messages-to-send)
|
||||
|
@ -238,12 +388,12 @@ which see."
|
|||
(message "Directive: %s"
|
||||
,(string-replace "\n" "⮐ "
|
||||
(truncate-string-to-width prompt 100 nil nil t)))
|
||||
(setq gptel--system-message ,prompt))
|
||||
(gptel--set-with-scope 'gptel--system-message ,prompt
|
||||
gptel--set-buffer-locally))
|
||||
:transient 'transient--do-return)
|
||||
into prompt-suffixes
|
||||
finally return
|
||||
(nconc
|
||||
(list (list 'gptel--suffix-system-message))
|
||||
prompt-suffixes
|
||||
(list (list "SPC" "Pick crowdsourced prompt"
|
||||
'gptel--read-crowdsourced-prompt
|
||||
|
@ -267,12 +417,13 @@ More extensive system messages can be useful for specific tasks.
|
|||
|
||||
Customize `gptel-directives' for task-specific prompts."
|
||||
[:description
|
||||
(lambda () (format "System Message: %s"
|
||||
(string-replace
|
||||
"\n" "⮐"
|
||||
(lambda () (string-replace
|
||||
"\n" "⮐ "
|
||||
(truncate-string-to-width
|
||||
gptel--system-message 100 nil nil t))))
|
||||
:class transient-column
|
||||
gptel--system-message (max (- (window-width) 12) 14) nil nil t)))
|
||||
[(gptel--suffix-system-message)]
|
||||
[(gptel--infix-variable-scope)]]
|
||||
[:class transient-column
|
||||
:setup-children gptel-system-prompt--setup
|
||||
:pad-keys t])
|
||||
|
||||
|
@ -305,23 +456,14 @@ Customize `gptel-directives' for task-specific prompts."
|
|||
|
||||
;; ** Infixes for model parameters
|
||||
|
||||
(defun gptel--transient-read-variable (prompt initial-input history)
|
||||
"Read value from minibuffer and interpret the result as a Lisp object.
|
||||
|
||||
PROMPT, INITIAL-INPUT and HISTORY are as in the Transient reader
|
||||
documention."
|
||||
(ignore-errors
|
||||
(read-from-minibuffer prompt initial-input read-expression-map t history)))
|
||||
|
||||
(defclass gptel-lisp-variable (transient-lisp-variable)
|
||||
((display-nil :initarg :display-nil))
|
||||
"Lisp variables that show :display-nil instead of nil.")
|
||||
|
||||
(cl-defmethod transient-format-value
|
||||
((obj gptel-lisp-variable))
|
||||
(propertize (prin1-to-string (or (oref obj value)
|
||||
(oref obj display-nil)))
|
||||
'face 'transient-value))
|
||||
(transient-define-infix gptel--infix-variable-scope ()
|
||||
"Set gptel's model parameters and system message in this buffer or globally."
|
||||
:argument "scope"
|
||||
:variable 'gptel--set-buffer-locally
|
||||
:class 'gptel--switches
|
||||
:format " %k %d %v"
|
||||
:key "="
|
||||
:description (propertize "Set" 'face 'transient-inactive-argument))
|
||||
|
||||
(transient-define-infix gptel--infix-num-messages-to-send ()
|
||||
"Number of recent messages to send with each exchange.
|
||||
|
@ -333,6 +475,7 @@ include."
|
|||
:description "previous responses"
|
||||
:class 'gptel-lisp-variable
|
||||
:variable 'gptel--num-messages-to-send
|
||||
:set-value #'gptel--set-with-scope
|
||||
:display-nil 'all
|
||||
:format " %k %v %d"
|
||||
:key "-n"
|
||||
|
@ -348,38 +491,19 @@ responses."
|
|||
:description "Response length (tokens)"
|
||||
:class 'gptel-lisp-variable
|
||||
:variable 'gptel-max-tokens
|
||||
:set-value #'gptel--set-with-scope
|
||||
:display-nil 'auto
|
||||
:key "-c"
|
||||
:prompt "Response length in tokens (leave empty: default, 80-200: short, 200-500: long): "
|
||||
:reader 'gptel--transient-read-variable)
|
||||
|
||||
(defclass gptel-provider-variable (transient-lisp-variable)
|
||||
((model :initarg :model)
|
||||
(model-value :initarg :model-value)
|
||||
(always-read :initform t)
|
||||
(set-value :initarg :set-value :initform #'set))
|
||||
"Class used for gptel-backends.")
|
||||
|
||||
(cl-defmethod transient-format-value ((obj gptel-provider-variable))
|
||||
(propertize (concat (gptel-backend-name (oref obj value)) ":"
|
||||
(buffer-local-value (oref obj model) transient--original-buffer))
|
||||
'face 'transient-value))
|
||||
|
||||
(cl-defmethod transient-infix-set ((obj gptel-provider-variable) value)
|
||||
(pcase-let ((`(,backend-value ,model-value) value))
|
||||
(funcall (oref obj set-value)
|
||||
(oref obj variable)
|
||||
(oset obj value backend-value))
|
||||
(funcall (oref obj set-value)
|
||||
(oref obj model)
|
||||
(oset obj model-value model-value))))
|
||||
|
||||
(transient-define-infix gptel--infix-provider ()
|
||||
"AI Provider for Chat."
|
||||
:description "GPT Model"
|
||||
:class 'gptel-provider-variable
|
||||
:prompt "Model provider: "
|
||||
:prompt "Model: "
|
||||
:variable 'gptel-backend
|
||||
:set-value #'gptel--set-with-scope
|
||||
:model 'gptel-model
|
||||
:key "-m"
|
||||
:reader (lambda (prompt &rest _)
|
||||
|
@ -388,7 +512,7 @@ responses."
|
|||
nconc (cl-loop for model in (gptel-backend-models backend)
|
||||
collect (list (concat name ":" model) backend model))
|
||||
into models-alist finally return
|
||||
(cdr (assoc (completing-read "Model: " models-alist nil t)
|
||||
(cdr (assoc (completing-read prompt models-alist nil t)
|
||||
models-alist)))))
|
||||
|
||||
(transient-define-infix gptel--infix-temperature ()
|
||||
|
@ -396,67 +520,13 @@ responses."
|
|||
:description "Temperature (0 - 2.0)"
|
||||
:class 'transient-lisp-variable
|
||||
:variable 'gptel-temperature
|
||||
:set-value #'gptel--set-with-scope
|
||||
:key "-t"
|
||||
:prompt "Temperature controls the response randomness (0.0-2.0, leave empty for default): "
|
||||
:reader 'gptel--transient-read-variable)
|
||||
|
||||
;; ** Infix for the refactor/rewrite system message
|
||||
|
||||
(defun gptel--instructions-make-overlay (text &optional ov)
|
||||
"TODO"
|
||||
(save-excursion
|
||||
(cond
|
||||
((use-region-p) (goto-char (region-beginning)))
|
||||
((gptel--in-response-p) (gptel-beginning-of-response))
|
||||
(t (text-property-search-backward 'gptel 'response)))
|
||||
(skip-chars-forward "\n \t")
|
||||
(if (and ov (overlayp ov))
|
||||
(move-overlay ov (point) (point) (current-buffer))
|
||||
(setq ov (make-overlay (point) (point) nil t)))
|
||||
(overlay-put ov 'before-string nil)
|
||||
;; (unless (or (bobp) (eq (char-before) "\n"))
|
||||
;; (overlay-put ov 'before-string (propertize "\n" 'font-lock-face 'shadow)))
|
||||
(overlay-put ov 'category 'gptel)
|
||||
(overlay-put
|
||||
ov 'after-string
|
||||
(concat
|
||||
(propertize (concat "GPTEL: " text)
|
||||
'font-lock-face '(:inherit shadow :box t))
|
||||
"\n"))
|
||||
ov))
|
||||
|
||||
(defclass gptel-option-overlaid (transient-option)
|
||||
((display-nil :initarg :display-nil)
|
||||
(overlay :initarg :overlay))
|
||||
"Transient options for overlays displayed in the working buffer.")
|
||||
|
||||
(cl-defmethod transient-format-value ((obj gptel-option-overlaid))
|
||||
"set up the in-buffer overlay for additional directive, a string.
|
||||
|
||||
Also format its value in the Transient menu."
|
||||
(let ((value (oref obj value))
|
||||
(ov (oref obj overlay))
|
||||
(argument (oref obj argument)))
|
||||
;; Making an overlay
|
||||
(if (or (not value) (string-empty-p value))
|
||||
(when ov (delete-overlay ov))
|
||||
(with-current-buffer transient--original-buffer
|
||||
(oset obj overlay (gptel--instructions-make-overlay value ov)))
|
||||
(letrec ((ov-clear-hook
|
||||
(lambda () (when-let* ((ov (oref obj overlay))
|
||||
((overlayp ov)))
|
||||
(remove-hook 'transient-exit-hook
|
||||
ov-clear-hook)
|
||||
(delete-overlay ov)))))
|
||||
(add-hook 'transient-exit-hook ov-clear-hook)))
|
||||
;; Updating transient menu display
|
||||
(if value
|
||||
(propertize (concat argument (truncate-string-to-width value 25 nil nil "..."))
|
||||
'face 'transient-value)
|
||||
(propertize
|
||||
(concat "(" (symbol-name (oref obj display-nil)) ")")
|
||||
'face 'transient-inactive-value))))
|
||||
|
||||
(transient-define-infix gptel--infix-add-directive ()
|
||||
"Additional directive intended for the next query only.
|
||||
|
||||
|
@ -487,12 +557,6 @@ Or in an extended conversation:
|
|||
:description "Add directive"
|
||||
:transient t)
|
||||
|
||||
(defun gptel--get-directive (args)
|
||||
"Find the additional directive in the transient ARGS of this command."
|
||||
(cl-some (lambda (s) (and (string-prefix-p ":" s)
|
||||
(concat "\n\n" (substring s 1))))
|
||||
args))
|
||||
|
||||
(transient-define-infix gptel--infix-rewrite-prompt ()
|
||||
"Chat directive (system message) to use for rewriting or refactoring."
|
||||
:description (lambda () (if (derived-mode-p 'prog-mode)
|
||||
|
@ -564,7 +628,7 @@ Or in an extended conversation:
|
|||
backend-name
|
||||
(truncate-string-to-width resp 30))))))
|
||||
((setq gptel-buffer-name
|
||||
(cl-some (lambda (s) (and (string-prefix-p "g" s)
|
||||
(cl-some (lambda (s) (and (stringp s) (string-prefix-p "g" s)
|
||||
(substring s 1)))
|
||||
args))
|
||||
(setq output-to-other-buffer-p t)
|
||||
|
@ -616,7 +680,7 @@ Or in an extended conversation:
|
|||
(gptel--update-status " Waiting..." 'warning)
|
||||
(setq position (point)))))))
|
||||
((setq gptel-buffer-name
|
||||
(cl-some (lambda (s) (and (string-prefix-p "b" s)
|
||||
(cl-some (lambda (s) (and (stringp s) (string-prefix-p "b" s)
|
||||
(substring s 1)))
|
||||
args))
|
||||
(setq output-to-other-buffer-p t)
|
||||
|
@ -717,9 +781,12 @@ This uses the prompts in the variable
|
|||
(message "No prompts available.")))
|
||||
|
||||
(transient-define-suffix gptel--suffix-system-message ()
|
||||
"Edit LLM directives."
|
||||
"Edit LLM system message.
|
||||
|
||||
When LOCAL is non-nil, set the system message only in the current buffer."
|
||||
:transient 'transient--do-exit
|
||||
:description "Set or edit system message"
|
||||
:format " %k %d"
|
||||
:key "s"
|
||||
(interactive)
|
||||
(let ((orig-buf (current-buffer))
|
||||
|
@ -771,7 +838,8 @@ This uses the prompts in the variable
|
|||
(let ((system-message
|
||||
(buffer-substring msg-start (point-max))))
|
||||
(with-current-buffer orig-buf
|
||||
(setq gptel--system-message system-message)))
|
||||
(gptel--set-with-scope 'gptel--system-message system-message
|
||||
gptel--set-buffer-locally)))
|
||||
(funcall quit-to-menu)))
|
||||
(local-set-key (kbd "C-c C-k") quit-to-menu)))))
|
||||
|
||||
|
|
9
gptel.el
9
gptel.el
|
@ -369,7 +369,8 @@ interactively call `gptel-send' with a prefix argument."
|
|||
:safe #'always
|
||||
:type '(alist :key-type symbol :value-type string))
|
||||
|
||||
(defvar-local gptel--system-message (alist-get 'default gptel-directives))
|
||||
(defvar gptel--system-message (alist-get 'default gptel-directives)
|
||||
"The system message used by gptel.")
|
||||
(put 'gptel--system-message 'safe-local-variable #'always)
|
||||
|
||||
(defcustom gptel-max-tokens nil
|
||||
|
@ -381,7 +382,6 @@ responses.
|
|||
|
||||
To set the target token count for a chat session interactively
|
||||
call `gptel-send' with a prefix argument."
|
||||
:local t
|
||||
:safe #'always
|
||||
:group 'gptel
|
||||
:type '(choice (integer :tag "Specify Token count")
|
||||
|
@ -401,7 +401,6 @@ The current options for ChatGPT are
|
|||
|
||||
To set the model for a chat session interactively call
|
||||
`gptel-send' with a prefix argument."
|
||||
:local t
|
||||
:safe #'always
|
||||
:group 'gptel
|
||||
:type '(choice
|
||||
|
@ -421,7 +420,6 @@ of the response, with 2.0 being the most random.
|
|||
|
||||
To set the temperature for a chat session interactively call
|
||||
`gptel-send' with a prefix argument."
|
||||
:local t
|
||||
:safe #'always
|
||||
:group 'gptel
|
||||
:type 'number)
|
||||
|
@ -461,7 +459,6 @@ one of the available backend creation functions:
|
|||
- `gptel-make-gemini'
|
||||
See their documentation for more information and the package
|
||||
README for examples."
|
||||
:local t
|
||||
:safe #'always
|
||||
:group 'gptel
|
||||
:type `(choice
|
||||
|
@ -477,7 +474,7 @@ This opens up advanced options in `gptel-menu'.")
|
|||
(defvar-local gptel--bounds nil)
|
||||
(put 'gptel--bounds 'safe-local-variable #'always)
|
||||
|
||||
(defvar-local gptel--num-messages-to-send nil)
|
||||
(defvar gptel--num-messages-to-send nil)
|
||||
(put 'gptel--num-messages-to-send 'safe-local-variable #'always)
|
||||
|
||||
(defcustom gptel-log-level nil
|
||||
|
|
Loading…
Add table
Reference in a new issue