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

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

[nongnu] elpa/gptel 040baad910 034/273: gptel: Remove aio dependency


From: ELPA Syncer
Subject: [nongnu] elpa/gptel 040baad910 034/273: gptel: Remove aio dependency
Date: Wed, 1 May 2024 10:01:32 -0400 (EDT)

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

    gptel: Remove aio dependency
    
    * gptel.el (gptel-send, gptel--insert-response,
    gptel--url-get-response): Remove aio dependency, turn aio-defuns
    into regular functions.  This requires splitting `gptel-send' into
    "before response" and "after response" functions, but the ability
    to debug the code fully is worth the inconvenience.  The new "after
    response" function is `gptel--insert-response'.
    
    * gptel-curl.el (gptel-curl--sentinel, gptel-curl-get-response):
    Turn aio-defuns into regular functions.
---
 gptel-curl.el | 38 +++++++++++++++----------------
 gptel.el      | 72 +++++++++++++++++++++++++++++++++++------------------------
 2 files changed, 61 insertions(+), 49 deletions(-)

diff --git a/gptel-curl.el b/gptel-curl.el
index 01b744227c..38a3bf82fe 100644
--- a/gptel-curl.el
+++ b/gptel-curl.el
@@ -32,7 +32,6 @@
   (require 'subr-x))
 (require 'map)
 (require 'json)
-(require 'aio)
 
 (defvar gptel-curl--process-alist nil
   "Alist of active GPTel curl requests.")
@@ -67,26 +66,24 @@ PROMPTS is the data to send, TOKEN is a unique identifier."
     (nreverse (cons url args))))
 
 ;;;###autoload
-(defun gptel-curl-get-response (prompts)
-  "Retrieve response to PROMPTS."
+(defun gptel-curl-get-response (info)
+  "Retrieve response to prompt in INFO.
+
+INFO is a plist with the following keys:
+- :prompt (the prompt being sent)
+- :gptel-buffer (the gptel buffer)
+- :insert-marker (marker at which to insert the response)."
   (with-current-buffer (generate-new-buffer "*gptel-curl*")
     (let* ((token (md5 (format "%s%s%s%s"
                                (random) (emacs-pid) (user-full-name)
                                (recent-keys))))
-           (args (gptel-curl--get-args prompts token))
+           (args (gptel-curl--get-args (plist-get info :prompt) token))
            (process (apply #'start-process "gptel-curl" (current-buffer)
-                           "curl" args))
-           (promise (aio-promise))
-           (cb (lambda (result)
-                 (aio-resolve promise (lambda () result))
-                 (setf (alist-get process
-                                  gptel-curl--process-alist nil 'remove)
-                       nil))))
-      (prog1 promise
-        (set-process-query-on-exit-flag process nil)
-        (setf (alist-get process gptel-curl--process-alist)
-              (list :callback cb :token token))
-        (set-process-sentinel process #'gptel-curl--sentinel)))))
+                           "curl" args)))
+      (set-process-query-on-exit-flag process nil)
+      (setf (alist-get process gptel-curl--process-alist)
+            (nconc (list :token token) info))
+      (set-process-sentinel process #'gptel-curl--sentinel))))
 
 (defun gptel-curl--sentinel (process status)
   "Process sentinel for GPTel curl requests.
@@ -96,13 +93,14 @@ PROCESS and STATUS are process parameters."
     (when gptel--debug
       (with-current-buffer proc-buf
         (clone-buffer "*gptel-error*" 'show)))
-    (if-let* ((ok-p (equal status "finished\n"))
+    (if-let* (((equal status "finished\n"))
               (proc-info (alist-get process gptel-curl--process-alist))
               (proc-token (plist-get proc-info :token))
-              (content (gptel-curl--parse-response proc-buf proc-token)))
-        (funcall (plist-get proc-info :callback) content)
+              (response (gptel-curl--parse-response proc-buf proc-token)))
+        (gptel--insert-response response proc-info)
       ;; Failed
-      (funcall (plist-get proc-info :callback) nil))
+      (gptel--insert-response (list :content nil :status status) proc-info))
+    (setf (alist-get process gptel-curl--process-alist nil 'remove) nil)
     (kill-buffer proc-buf)))
 
 (defun gptel-curl--parse-response (buf token)
diff --git a/gptel.el b/gptel.el
index d0652ebbbf..e2ffb4faf3 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") (transient "0.3.7"))
+;; Package-Requires: ((emacs "27.1") (transient "0.3.7"))
 ;; Keywords: convenience
 ;; URL: https://github.com/karthink/gptel
 
@@ -33,9 +33,6 @@
 ;; - You need an OpenAI API key. Set the variable `gptel-api-key' to the key 
or to
 ;;   a function of no arguments that returns the key.
 ;;
-;; - If installing manually: Install the package `emacs-aio' using `M-x 
package-install'
-;;   or however you install packages.
-;;
 ;; - Not required but recommended: Install `markdown-mode'.
 ;;
 ;; Usage:
@@ -56,7 +53,7 @@
   (require 'subr-x)
   (require 'cl-lib))
 
-(require 'aio)
+(require 'url)
 (require 'json)
 (require 'map)
 (require 'text-property-search)
@@ -150,8 +147,13 @@ return the transformed string."
 
 ;; TODO: Handle read-only buffers. Should we spawn a new buffer automatically?
 ;; TODO: Handle multiple requests(#15). (Only one request from one buffer at a 
time?)
-(aio-defun gptel-send (&optional arg)
-  "Submit this prompt to ChatGPT."
+;; TODO: Since we capture a marker for the insertion location, `gptel-buffer' 
no
+;; longer needs to be recorded
+(defun gptel-send (&optional arg)
+  "Submit this prompt to ChatGPT.
+
+With prefix arg ARG activate a transient menu with more options
+instead."
   (interactive "P")
   (if (and arg (require 'gptel-transient nil t))
       (call-interactively #'gptel-send-menu)
@@ -162,14 +164,23 @@ return the transformed string."
               (set-marker (make-marker) (region-end))
             (point-marker)))
          (gptel-buffer (current-buffer))
-         (full-prompt (gptel--create-prompt response-pt))
-         (response (aio-await
-                    (funcall
-                     (if gptel-use-curl
-                         #'gptel-curl-get-response #'gptel--url-get-response)
-                     full-prompt)))
-         (content-str (plist-get response :content))
-         (status-str  (plist-get response :status)))
+         (full-prompt (gptel--create-prompt response-pt)))
+    (funcall
+     (if gptel-use-curl
+         #'gptel-curl-get-response #'gptel--url-get-response)
+     (list :prompt full-prompt
+           :gptel-buffer gptel-buffer
+           :insert-marker response-pt)))))
+
+(defun gptel--insert-response (response info)
+  "Insert RESPONSE from ChatGPT into the gptel buffer.
+
+INFO is a plist containing information relevant to this buffer.
+See `gptel--url-get-response' for details."
+  (let* ((content-str (plist-get response :content))
+         (status-str  (plist-get response :status))
+         (gptel-buffer (plist-get info :gptel-buffer))
+         (response-pt (plist-get info :insert-marker)))
     (if content-str
         (with-current-buffer gptel-buffer
           (setq content-str (gptel--transform-response
@@ -178,9 +189,6 @@ return the transformed string."
             (put-text-property 0 (length content-str) 'gptel 'response 
content-str)
             (message "Querying ChatGPT... done.")
             (goto-char response-pt)
-            (display-buffer (current-buffer)
-                            '((display-buffer-reuse-window
-                               display-buffer-use-some-window)))
             (unless (bobp) (insert-before-markers-and-inherit "\n\n"))
             (if gptel-playback
                 (gptel--playback gptel-buffer content-str response-pt)
@@ -192,7 +200,7 @@ return the transformed string."
                 (gptel--update-header-line " Ready" 'success))))
           (goto-char (- (point) 2)))
       (gptel--update-header-line
-       (format " Response Error: %s" status-str) 'error)))))
+       (format " Response Error: %s" status-str) 'error))))
 
 (defun gptel--create-prompt (&optional prompt-end)
   "Return a full conversation prompt from the contents of this buffer.
@@ -273,10 +281,13 @@ BUFFER is the interaction buffer for ChatGPT."
     ('org-mode (gptel--convert-markdown->org content))
     (_ content)))
 
-(aio-defun gptel--url-get-response (prompts)
-  "Fetch response for PROMPTS from ChatGPT.
+(defun gptel--url-get-response (info)
+  "Fetch response to prompt in INFO from ChatGPT.
 
-Return the message received."
+INFO is a plist with the following keys:
+- :prompt (the prompt being sent)
+- :gptel-buffer (the gptel buffer)
+- :insert-marker (marker at which to insert the response)."
   (let* ((inhibit-message t)
          (message-log-max nil)
          (api-key
@@ -289,13 +300,16 @@ Return the message received."
          `(("Content-Type" . "application/json")
            ("Authorization" . ,(concat "Bearer " api-key))))
         (url-request-data
-         (encode-coding-string (json-encode (gptel--request-data prompts)) 
'utf-8)))
-    (pcase-let ((`(,_ . ,response-buffer)
-                 (aio-await
-                  (aio-url-retrieve 
"https://api.openai.com/v1/chat/completions";))))
-      (prog1
-          (gptel--url-parse-response response-buffer)
-        (kill-buffer response-buffer)))))
+         (encode-coding-string
+          (json-encode (gptel--request-data (plist-get info :prompt)))
+          'utf-8)))
+    (url-retrieve "https://api.openai.com/v1/chat/completions";
+                  (lambda (_)
+                    (let ((response
+                           (gptel--url-parse-response (current-buffer))))
+                      (gptel--insert-response response info)
+                      (kill-buffer)))
+                  nil t nil)))
 
 (defun gptel--url-parse-response (response-buffer)
   "Parse response in RESPONSE-BUFFER."



reply via email to

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