emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[nongnu] elpa/gptel 39376aa3f4 020/273: gptel-transient: Add transient m


From: ELPA Syncer
Subject: [nongnu] elpa/gptel 39376aa3f4 020/273: gptel-transient: Add transient menus for setting parameters
Date: Wed, 1 May 2024 10:01:27 -0400 (EDT)

branch: elpa/gptel
commit 39376aa3f42436711c717fba647793754dfe7e6b
Author: Karthik Chikmagalur <karthikchikmagalur@gmail.com>
Commit: Karthik Chikmagalur <karthikchikmagalur@gmail.com>

    gptel-transient: Add transient menus for setting parameters
    
    gptel-transient (gptel-send-menu): Add new transient-prefix
    `gptel-send-menu' for setting API options for the buffer
    and (optionally) sending queries. Various infix options are supported.
    
    2023-03-09: Some transient menus are generated dynamically, which
    requires a more recent version of transient than the latest tagged
    release. As a result, the dynamic generation code is commented out for
    now.
---
 gptel-transient.el | 208 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 gptel.el           |   4 +-
 2 files changed, 210 insertions(+), 2 deletions(-)

diff --git a/gptel-transient.el b/gptel-transient.el
new file mode 100644
index 0000000000..f84182045d
--- /dev/null
+++ b/gptel-transient.el
@@ -0,0 +1,208 @@
+;;; gptel-transient.el --- Transient menu for GPTel  -*- lexical-binding: t; 
-*-
+
+;; Copyright (C) 2023  Karthik Chikmagalur
+
+;; Author: Karthik Chikmagalur <karthikchikmagalur@gmail.com>
+;; Keywords: convenience
+
+;; SPDX-License-Identifier: GPL-3.0-or-later
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+(require 'gptel)
+(require 'transient)
+
+;;;###autoload
+(transient-define-prefix gptel-send-menu ()
+     "Change parameters of prompt to send ChatGPT."
+     [:description
+      (lambda () (format "Directive:  %s"
+                    (truncate-string-to-width
+                     gptel--system-message (max (- (window-width) 14) 20) nil 
nil t)))
+      ("h" "Set directives for chat" gptel-system-prompt)]
+     [["Parameters"
+       (gptel--infix-max-tokens)
+       (gptel--infix-num-messages-to-send)
+       (gptel--infix-temperature)
+       (gptel--infix-model)]
+      ["Send"
+       (gptel--suffix-send-existing)
+       (gptel--suffix-send-new)
+       ("RET" "Send prompt" gptel-send)]])
+
+(transient-define-prefix gptel-system-prompt ()
+  "Change the system prompt to send ChatGPT.
+
+The \"system\" prompt establishes directives for the chat
+session. Some examples of system prompts are:
+
+You are a helpful assistant. Answer as concisely as possible.
+Reply only with shell commands and no prose.
+You are a poet. Reply only in verse.
+
+Customize `gptel--system-message-alist' for task-specific
+prompts."
+  [:description
+   (lambda () (format "Directive: %s"
+                 (truncate-string-to-width gptel--system-message (max (- 
(window-width) 14) 20) nil nil t)))
+   :class transient-column
+   :pad-keys t
+   (gptel--suffix-system-message)
+   ("p" "Programming"
+    (lambda () (interactive)
+      (setq gptel--system-message
+            (alist-get 'programming gptel--system-message-alist)))
+    :transient t)
+   ("d" "Default"
+    (lambda () (interactive)
+      (setq gptel--system-message
+            (alist-get 'default gptel--system-message-alist)))
+    :transient t)
+   ("w" "Writing"
+    (lambda () (interactive)
+      (setq gptel--system-message
+            (alist-get 'writing gptel--system-message-alist)))
+    :transient t)
+   ("c" "Chat"
+    (lambda () (interactive)
+      (setq gptel--system-message
+            (alist-get 'chat gptel--system-message-alist)))
+    :transient t)])
+
+;; TODO: Switch to dynamic Transient menus (below) once there's a new 
Transient release
+;; (transient-define-prefix gptel-system-prompt ()
+;;   "Change the system prompt to send ChatGPT."
+;;   [:description (lambda () (format "Current directive: %s"
+;;                                 (truncate-string-to-width 
gptel--system-message 100 nil nil t)))
+;;    :class transient-column
+;;    :setup-children gptel-system-prompt--setup
+;;    :pad-keys t])
+
+;; (defun gptel-system-prompt--setup (_)
+;;   "Set up suffixes for system prompt."
+;;   (transient-parse-suffixes
+;;    'gptel-system-prompt
+;;    (cl-loop for (type . prompt) in gptel--system-message-alist
+;;        for name = (symbol-name type)
+;;        for key = (substring name 0 1)
+;;        collect (list (key-description key) (capitalize name)
+;;                 `(lambda () (interactive)
+;;                   (message "Directive: %s" ,prompt)
+;;                   (setq gptel--system-message ,prompt))
+;;                 :transient t)
+;;        into prompt-suffixes
+;;        finally return (cons (list 'gptel--suffix-system-message)
+;;                             prompt-suffixes))))
+
+(transient-define-infix gptel--infix-num-messages-to-send ()
+  "Number of recent messages to send with each exchange.
+
+By default, the full conversation history is sent with every new
+prompt. This retains the full context of the conversation, but
+can be expensive in token size. Set how many recent messages to
+include."
+  :description "Number of past messages to send"
+  :class 'transient-lisp-variable
+  :variable 'gptel--num-messages-to-send
+  :key "n"
+  :prompt "Number of past messages to include (leave empty for all): "
+  :reader 'transient-read-number-N+)
+
+(transient-define-infix gptel--infix-max-tokens ()
+  "Max tokens per response.
+
+This is roughly the number of words in the response. 100-300 is a
+reasonable range for short answers, 400 or more for longer
+responses.
+
+If left unset, ChatGPT will target about 40% of the total token
+count of the conversation so far in each message, so messages
+will get progressively longer!"
+  :description "Response length (tokens)"
+  :class 'transient-lisp-variable
+  :variable 'gptel--max-tokens
+  :key "<"
+  :prompt "Response length in tokens (leave empty: default, 80-200: short, 
200-500: long): "
+  :reader 'transient-read-number-N+)
+
+(transient-define-infix gptel--infix-model ()
+  "AI Model for Chat."
+  :description "GPT Model: "
+  :class 'transient-lisp-variable
+  :variable 'gptel--model
+  :key "M"
+  :choices '("gpt-3.5-turbo-0301" "gpt-3.5-turbo")
+  :reader (lambda (prompt &rest _)
+            (completing-read
+             prompt
+             '("gpt-3.5-turbo-0301" "gpt-3.5-turbo"))))
+
+(transient-define-infix gptel--infix-temperature ()
+  "Temperature of request."
+  :description "Randomness (0 - 2.0)"
+  :class 'transient-lisp-variable
+  :variable 'gptel--temperature
+  :key "t"
+  :reader '(lambda (_ initial history)
+             (read-from-minibuffer "Set temperature (0.0-2.0, leave empty for 
default): "
+              (number-to-string gptel--temperature))))
+
+(transient-define-suffix gptel--suffix-system-message ()
+  "Set Establishing message sent to ChatGPT."
+  :transient nil
+  :description "Set custom directives"
+  :key "h"
+  (interactive)
+  (let ((orig-buf (current-buffer))
+        (msg-start (make-marker)))
+    (with-current-buffer (get-buffer-create "*gptel-system*")
+      (erase-buffer)
+      (text-mode)
+      (insert
+       "# Insert your system message below and press "
+       (propertize "C-c C-c" 'face 'help-key-binding)
+       " when ready.\n"
+       "# Example: You are a helpful assistant. Answer as concisely as 
possible.\n"
+       "# Example: Reply only with shell commands and no prose.\n"
+       "# Example: You are a poet. Reply only in verse.\n\n")
+      (set-marker msg-start (point))
+      (insert (buffer-local-value 'gptel--system-message orig-buf))
+      (goto-char (line-beginning-position))
+      (push-mark)
+      (goto-char (line-end-position))
+      (activate-mark)
+      (display-buffer (current-buffer)
+                      `((display-buffer-below-selected)
+                        (body-function . ,#'select-window)
+                        (window-height . ,#'fit-window-to-buffer)))
+      (local-set-key (kbd "C-c C-c")
+                     (lambda ()
+                       (interactive)
+                       (setf (buffer-local-value 'gptel--system-message 
orig-buf)
+                             (buffer-substring msg-start (point-max)))
+                       (quit-window)
+                       (display-buffer
+                        orig-buf
+                        `((display-buffer-reuse-window
+                           display-buffer-use-some-window)
+                          (body-function . ,#'select-window)))
+                       (call-interactively #'gptel-send-menu))))))
+
+(provide 'gptel-transient)
+;;; gptel-transient.el ends here
diff --git a/gptel.el b/gptel.el
index b5d73103c5..59ea3e99b7 100644
--- a/gptel.el
+++ b/gptel.el
@@ -4,7 +4,7 @@
 
 ;; Author: Karthik Chikmagalur
 ;; Version: 0.10
-;; Package-Requires: ((emacs "27.1") (aio "1.0"))
+;; Package-Requires: ((emacs "27.1") (aio "1.0") (transient "0.3.7"))
 ;; Keywords: convenience
 ;; URL: https://github.com/karthink/gptel
 
@@ -126,7 +126,7 @@ return the transformed string."
 (aio-defun gptel-send (&optional arg)
   "Submit this prompt to ChatGPT."
   (interactive "P")
-  (if (and arg (featurep 'gptel-transient))
+  (if (and arg (require 'gptel-transient nil t))
       (call-interactively #'gptel-send-menu)
   (message "Querying ChatGPT...")
   (and header-line-format



reply via email to

[Prev in Thread] Current Thread [Next in Thread]