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
63
README.org
63
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
|
***** (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
|
#+begin_src emacs-lisp
|
||||||
;; OPTIONAL configuration
|
;; OPTIONAL configuration
|
||||||
(setq-default
|
(setq
|
||||||
gptel-model "gpt-3.5-turbo"
|
gptel-model "gpt-3.5-turbo"
|
||||||
gptel-backend (gptel-make-azure "Azure-1"
|
gptel-backend (gptel-make-azure "Azure-1"
|
||||||
:protocol "https"
|
: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
|
***** (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
|
#+begin_src emacs-lisp
|
||||||
;; OPTIONAL configuration
|
;; OPTIONAL configuration
|
||||||
(setq-default
|
(setq
|
||||||
gptel-max-tokens 500
|
gptel-max-tokens 500
|
||||||
gptel-model "mistral-7b-openorca.Q4_0.gguf"
|
gptel-model "mistral-7b-openorca.Q4_0.gguf"
|
||||||
gptel-backend (gptel-make-gpt4all "GPT4All"
|
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
|
***** (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
|
#+begin_src emacs-lisp
|
||||||
;; OPTIONAL configuration
|
;; OPTIONAL configuration
|
||||||
(setq-default
|
(setq
|
||||||
gptel-model "mistral:latest"
|
gptel-model "mistral:latest"
|
||||||
gptel-backend (gptel-make-ollama "Ollama"
|
gptel-backend (gptel-make-ollama "Ollama"
|
||||||
:host "localhost:11434"
|
: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
|
***** (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
|
#+begin_src emacs-lisp
|
||||||
;; OPTIONAL configuration
|
;; OPTIONAL configuration
|
||||||
(setq-default
|
(setq
|
||||||
gptel-model "gemini-pro"
|
gptel-model "gemini-pro"
|
||||||
gptel-backend (gptel-make-gemini "Gemini"
|
gptel-backend (gptel-make-gemini "Gemini"
|
||||||
:key "YOUR_GEMINI_API_KEY"
|
: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
|
***** (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
|
#+begin_src emacs-lisp
|
||||||
;; OPTIONAL configuration
|
;; OPTIONAL configuration
|
||||||
(setq-default
|
(setq
|
||||||
gptel-model "test"
|
gptel-model "test"
|
||||||
gptel-backend (gptel-make-openai "llama-cpp"
|
gptel-backend (gptel-make-openai "llama-cpp"
|
||||||
:stream t
|
: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
|
***** (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
|
#+begin_src emacs-lisp
|
||||||
;; OPTIONAL configuration
|
;; OPTIONAL configuration
|
||||||
(setq-default
|
(setq
|
||||||
gptel-model "fastgpt"
|
gptel-model "fastgpt"
|
||||||
gptel-backend (gptel-make-kagi "Kagi"
|
gptel-backend (gptel-make-kagi "Kagi"
|
||||||
:key "YOUR_KAGI_API_KEY"))
|
: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
|
***** (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
|
#+begin_src emacs-lisp
|
||||||
;; OPTIONAL configuration
|
;; OPTIONAL configuration
|
||||||
(setq-default
|
(setq
|
||||||
gptel-model "mistralai/Mixtral-8x7B-Instruct-v0.1"
|
gptel-model "mistralai/Mixtral-8x7B-Instruct-v0.1"
|
||||||
gptel-backend
|
gptel-backend
|
||||||
(gptel-make-openai "TogetherAI"
|
(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
|
***** (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
|
#+begin_src emacs-lisp
|
||||||
;; OPTIONAL configuration
|
;; OPTIONAL configuration
|
||||||
(setq-default
|
(setq
|
||||||
gptel-model "mistralai/Mixtral-8x7B-Instruct-v0.1"
|
gptel-model "mistralai/Mixtral-8x7B-Instruct-v0.1"
|
||||||
gptel-backend
|
gptel-backend
|
||||||
(gptel-make-openai "Anyscale"
|
(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
|
***** (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
|
#+begin_src emacs-lisp
|
||||||
;; OPTIONAL configuration
|
;; OPTIONAL configuration
|
||||||
(setq-default
|
(setq
|
||||||
gptel-model "pplx-7b-chat"
|
gptel-model "pplx-7b-chat"
|
||||||
gptel-backend
|
gptel-backend
|
||||||
(gptel-make-openai "Perplexity"
|
(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
|
***** (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
|
#+begin_src emacs-lisp
|
||||||
;; OPTIONAL configuration
|
;; OPTIONAL configuration
|
||||||
(setq-default
|
(setq
|
||||||
gptel-model "claude-3-sonnet-20240229" ; "claude-3-opus-20240229" also available
|
gptel-model "claude-3-sonnet-20240229" ; "claude-3-opus-20240229" also available
|
||||||
gptel-backend (gptel-make-anthropic "Claude"
|
gptel-backend (gptel-make-anthropic "Claude"
|
||||||
:stream t :key "your-api-key"))
|
:stream t :key "your-api-key"))
|
||||||
|
@ -489,20 +489,19 @@ You can pick this backend from the menu when using gptel (see [[#usage][Usage]])
|
||||||
|
|
||||||
***** (Optional) Set as the default gptel backend
|
***** (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
|
#+begin_src emacs-lisp
|
||||||
;; OPTIONAL configuration
|
;; OPTIONAL configuration
|
||||||
(setq-default
|
(setq gptel-model "mixtral-8x7b-32768"
|
||||||
gptel-model "mixtral-8x7b-32768"
|
gptel-backend
|
||||||
gptel-backend
|
(gptel-make-openai "Groq"
|
||||||
(gptel-make-openai "Groq"
|
:host "api.groq.com"
|
||||||
:host "api.groq.com"
|
:endpoint "/openai/v1/chat/completions"
|
||||||
:endpoint "/openai/v1/chat/completions"
|
:stream t
|
||||||
:stream t
|
:key "your-api-key"
|
||||||
:key "your-api-key"
|
:models '("mixtral-8x7b-32768"
|
||||||
:models '("mixtral-8x7b-32768"
|
"gemma-7b-it"
|
||||||
"gemma-7b-it"
|
"llama2-70b-4096")))
|
||||||
"llama2-70b-4096")))
|
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
#+html: </details>
|
#+html: </details>
|
||||||
|
|
|
@ -33,7 +33,61 @@
|
||||||
(declare-function ediff-make-cloned-buffer "ediff-utils")
|
(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 ()
|
(defun gptel--refactor-or-rewrite ()
|
||||||
"Rewrite should be refactored into refactor.
|
"Rewrite should be refactored into refactor.
|
||||||
|
@ -105,6 +159,100 @@ which see."
|
||||||
(forward-line 1)))))
|
(forward-line 1)))))
|
||||||
gptel--crowdsourced-prompts))
|
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
|
;; * Transient Prefixes
|
||||||
|
|
||||||
|
@ -120,12 +268,14 @@ which see."
|
||||||
(string-replace
|
(string-replace
|
||||||
"\n" "⮐ "
|
"\n" "⮐ "
|
||||||
(truncate-string-to-width
|
(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"
|
"Instructions"
|
||||||
("s" "Set system message" gptel-system-prompt :transient t)
|
("s" "Set system message" gptel-system-prompt :transient t)
|
||||||
(gptel--infix-add-directive)]]
|
(gptel--infix-add-directive)]]
|
||||||
[["Model Parameters"
|
[[:pad-keys t
|
||||||
|
"Model Parameters"
|
||||||
|
(gptel--infix-variable-scope)
|
||||||
(gptel--infix-provider)
|
(gptel--infix-provider)
|
||||||
(gptel--infix-max-tokens)
|
(gptel--infix-max-tokens)
|
||||||
(gptel--infix-num-messages-to-send)
|
(gptel--infix-num-messages-to-send)
|
||||||
|
@ -238,12 +388,12 @@ which see."
|
||||||
(message "Directive: %s"
|
(message "Directive: %s"
|
||||||
,(string-replace "\n" "⮐ "
|
,(string-replace "\n" "⮐ "
|
||||||
(truncate-string-to-width prompt 100 nil nil t)))
|
(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)
|
:transient 'transient--do-return)
|
||||||
into prompt-suffixes
|
into prompt-suffixes
|
||||||
finally return
|
finally return
|
||||||
(nconc
|
(nconc
|
||||||
(list (list 'gptel--suffix-system-message))
|
|
||||||
prompt-suffixes
|
prompt-suffixes
|
||||||
(list (list "SPC" "Pick crowdsourced prompt"
|
(list (list "SPC" "Pick crowdsourced prompt"
|
||||||
'gptel--read-crowdsourced-prompt
|
'gptel--read-crowdsourced-prompt
|
||||||
|
@ -267,14 +417,15 @@ More extensive system messages can be useful for specific tasks.
|
||||||
|
|
||||||
Customize `gptel-directives' for task-specific prompts."
|
Customize `gptel-directives' for task-specific prompts."
|
||||||
[:description
|
[:description
|
||||||
(lambda () (format "System Message: %s"
|
(lambda () (string-replace
|
||||||
(string-replace
|
"\n" "⮐ "
|
||||||
"\n" "⮐"
|
(truncate-string-to-width
|
||||||
(truncate-string-to-width
|
gptel--system-message (max (- (window-width) 12) 14) nil nil t)))
|
||||||
gptel--system-message 100 nil nil t))))
|
[(gptel--suffix-system-message)]
|
||||||
:class transient-column
|
[(gptel--infix-variable-scope)]]
|
||||||
:setup-children gptel-system-prompt--setup
|
[:class transient-column
|
||||||
:pad-keys t])
|
:setup-children gptel-system-prompt--setup
|
||||||
|
:pad-keys t])
|
||||||
|
|
||||||
;; ** Prefix for rewriting/refactoring
|
;; ** Prefix for rewriting/refactoring
|
||||||
|
|
||||||
|
@ -305,23 +456,14 @@ Customize `gptel-directives' for task-specific prompts."
|
||||||
|
|
||||||
;; ** Infixes for model parameters
|
;; ** Infixes for model parameters
|
||||||
|
|
||||||
(defun gptel--transient-read-variable (prompt initial-input history)
|
(transient-define-infix gptel--infix-variable-scope ()
|
||||||
"Read value from minibuffer and interpret the result as a Lisp object.
|
"Set gptel's model parameters and system message in this buffer or globally."
|
||||||
|
:argument "scope"
|
||||||
PROMPT, INITIAL-INPUT and HISTORY are as in the Transient reader
|
:variable 'gptel--set-buffer-locally
|
||||||
documention."
|
:class 'gptel--switches
|
||||||
(ignore-errors
|
:format " %k %d %v"
|
||||||
(read-from-minibuffer prompt initial-input read-expression-map t history)))
|
:key "="
|
||||||
|
:description (propertize "Set" 'face 'transient-inactive-argument))
|
||||||
(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-num-messages-to-send ()
|
(transient-define-infix gptel--infix-num-messages-to-send ()
|
||||||
"Number of recent messages to send with each exchange.
|
"Number of recent messages to send with each exchange.
|
||||||
|
@ -333,6 +475,7 @@ include."
|
||||||
:description "previous responses"
|
:description "previous responses"
|
||||||
:class 'gptel-lisp-variable
|
:class 'gptel-lisp-variable
|
||||||
:variable 'gptel--num-messages-to-send
|
:variable 'gptel--num-messages-to-send
|
||||||
|
:set-value #'gptel--set-with-scope
|
||||||
:display-nil 'all
|
:display-nil 'all
|
||||||
:format " %k %v %d"
|
:format " %k %v %d"
|
||||||
:key "-n"
|
:key "-n"
|
||||||
|
@ -348,38 +491,19 @@ responses."
|
||||||
:description "Response length (tokens)"
|
:description "Response length (tokens)"
|
||||||
:class 'gptel-lisp-variable
|
:class 'gptel-lisp-variable
|
||||||
:variable 'gptel-max-tokens
|
:variable 'gptel-max-tokens
|
||||||
|
:set-value #'gptel--set-with-scope
|
||||||
:display-nil 'auto
|
:display-nil 'auto
|
||||||
:key "-c"
|
:key "-c"
|
||||||
:prompt "Response length in tokens (leave empty: default, 80-200: short, 200-500: long): "
|
:prompt "Response length in tokens (leave empty: default, 80-200: short, 200-500: long): "
|
||||||
:reader 'gptel--transient-read-variable)
|
: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 ()
|
(transient-define-infix gptel--infix-provider ()
|
||||||
"AI Provider for Chat."
|
"AI Provider for Chat."
|
||||||
:description "GPT Model"
|
:description "GPT Model"
|
||||||
:class 'gptel-provider-variable
|
:class 'gptel-provider-variable
|
||||||
:prompt "Model provider: "
|
:prompt "Model: "
|
||||||
:variable 'gptel-backend
|
:variable 'gptel-backend
|
||||||
|
:set-value #'gptel--set-with-scope
|
||||||
:model 'gptel-model
|
:model 'gptel-model
|
||||||
:key "-m"
|
:key "-m"
|
||||||
:reader (lambda (prompt &rest _)
|
:reader (lambda (prompt &rest _)
|
||||||
|
@ -388,7 +512,7 @@ responses."
|
||||||
nconc (cl-loop for model in (gptel-backend-models backend)
|
nconc (cl-loop for model in (gptel-backend-models backend)
|
||||||
collect (list (concat name ":" model) backend model))
|
collect (list (concat name ":" model) backend model))
|
||||||
into models-alist finally return
|
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)))))
|
models-alist)))))
|
||||||
|
|
||||||
(transient-define-infix gptel--infix-temperature ()
|
(transient-define-infix gptel--infix-temperature ()
|
||||||
|
@ -396,67 +520,13 @@ responses."
|
||||||
:description "Temperature (0 - 2.0)"
|
:description "Temperature (0 - 2.0)"
|
||||||
:class 'transient-lisp-variable
|
:class 'transient-lisp-variable
|
||||||
:variable 'gptel-temperature
|
:variable 'gptel-temperature
|
||||||
|
:set-value #'gptel--set-with-scope
|
||||||
:key "-t"
|
:key "-t"
|
||||||
:prompt "Temperature controls the response randomness (0.0-2.0, leave empty for default): "
|
:prompt "Temperature controls the response randomness (0.0-2.0, leave empty for default): "
|
||||||
:reader 'gptel--transient-read-variable)
|
:reader 'gptel--transient-read-variable)
|
||||||
|
|
||||||
;; ** Infix for the refactor/rewrite system message
|
;; ** 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 ()
|
(transient-define-infix gptel--infix-add-directive ()
|
||||||
"Additional directive intended for the next query only.
|
"Additional directive intended for the next query only.
|
||||||
|
|
||||||
|
@ -487,12 +557,6 @@ Or in an extended conversation:
|
||||||
:description "Add directive"
|
:description "Add directive"
|
||||||
:transient t)
|
: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 ()
|
(transient-define-infix gptel--infix-rewrite-prompt ()
|
||||||
"Chat directive (system message) to use for rewriting or refactoring."
|
"Chat directive (system message) to use for rewriting or refactoring."
|
||||||
:description (lambda () (if (derived-mode-p 'prog-mode)
|
:description (lambda () (if (derived-mode-p 'prog-mode)
|
||||||
|
@ -564,7 +628,7 @@ Or in an extended conversation:
|
||||||
backend-name
|
backend-name
|
||||||
(truncate-string-to-width resp 30))))))
|
(truncate-string-to-width resp 30))))))
|
||||||
((setq gptel-buffer-name
|
((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)))
|
(substring s 1)))
|
||||||
args))
|
args))
|
||||||
(setq output-to-other-buffer-p t)
|
(setq output-to-other-buffer-p t)
|
||||||
|
@ -616,7 +680,7 @@ Or in an extended conversation:
|
||||||
(gptel--update-status " Waiting..." 'warning)
|
(gptel--update-status " Waiting..." 'warning)
|
||||||
(setq position (point)))))))
|
(setq position (point)))))))
|
||||||
((setq gptel-buffer-name
|
((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)))
|
(substring s 1)))
|
||||||
args))
|
args))
|
||||||
(setq output-to-other-buffer-p t)
|
(setq output-to-other-buffer-p t)
|
||||||
|
@ -717,9 +781,12 @@ This uses the prompts in the variable
|
||||||
(message "No prompts available.")))
|
(message "No prompts available.")))
|
||||||
|
|
||||||
(transient-define-suffix gptel--suffix-system-message ()
|
(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
|
:transient 'transient--do-exit
|
||||||
:description "Set or edit system message"
|
:description "Set or edit system message"
|
||||||
|
:format " %k %d"
|
||||||
:key "s"
|
:key "s"
|
||||||
(interactive)
|
(interactive)
|
||||||
(let ((orig-buf (current-buffer))
|
(let ((orig-buf (current-buffer))
|
||||||
|
@ -771,7 +838,8 @@ This uses the prompts in the variable
|
||||||
(let ((system-message
|
(let ((system-message
|
||||||
(buffer-substring msg-start (point-max))))
|
(buffer-substring msg-start (point-max))))
|
||||||
(with-current-buffer orig-buf
|
(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)))
|
(funcall quit-to-menu)))
|
||||||
(local-set-key (kbd "C-c C-k") 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
|
:safe #'always
|
||||||
:type '(alist :key-type symbol :value-type string))
|
: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)
|
(put 'gptel--system-message 'safe-local-variable #'always)
|
||||||
|
|
||||||
(defcustom gptel-max-tokens nil
|
(defcustom gptel-max-tokens nil
|
||||||
|
@ -381,7 +382,6 @@ responses.
|
||||||
|
|
||||||
To set the target token count for a chat session interactively
|
To set the target token count for a chat session interactively
|
||||||
call `gptel-send' with a prefix argument."
|
call `gptel-send' with a prefix argument."
|
||||||
:local t
|
|
||||||
:safe #'always
|
:safe #'always
|
||||||
:group 'gptel
|
:group 'gptel
|
||||||
:type '(choice (integer :tag "Specify Token count")
|
: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
|
To set the model for a chat session interactively call
|
||||||
`gptel-send' with a prefix argument."
|
`gptel-send' with a prefix argument."
|
||||||
:local t
|
|
||||||
:safe #'always
|
:safe #'always
|
||||||
:group 'gptel
|
:group 'gptel
|
||||||
:type '(choice
|
: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
|
To set the temperature for a chat session interactively call
|
||||||
`gptel-send' with a prefix argument."
|
`gptel-send' with a prefix argument."
|
||||||
:local t
|
|
||||||
:safe #'always
|
:safe #'always
|
||||||
:group 'gptel
|
:group 'gptel
|
||||||
:type 'number)
|
:type 'number)
|
||||||
|
@ -461,7 +459,6 @@ one of the available backend creation functions:
|
||||||
- `gptel-make-gemini'
|
- `gptel-make-gemini'
|
||||||
See their documentation for more information and the package
|
See their documentation for more information and the package
|
||||||
README for examples."
|
README for examples."
|
||||||
:local t
|
|
||||||
:safe #'always
|
:safe #'always
|
||||||
:group 'gptel
|
:group 'gptel
|
||||||
:type `(choice
|
:type `(choice
|
||||||
|
@ -477,7 +474,7 @@ This opens up advanced options in `gptel-menu'.")
|
||||||
(defvar-local gptel--bounds nil)
|
(defvar-local gptel--bounds nil)
|
||||||
(put 'gptel--bounds 'safe-local-variable #'always)
|
(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)
|
(put 'gptel--num-messages-to-send 'safe-local-variable #'always)
|
||||||
|
|
||||||
(defcustom gptel-log-level nil
|
(defcustom gptel-log-level nil
|
||||||
|
|
Loading…
Add table
Reference in a new issue