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

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

[nongnu] elpa/gptel c9795fe9e8 060/273: gptel: org support for streaming


From: ELPA Syncer
Subject: [nongnu] elpa/gptel c9795fe9e8 060/273: gptel: org support for streaming WIP
Date: Wed, 1 May 2024 10:01:42 -0400 (EDT)

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

    gptel: org support for streaming WIP
    
    * gptel.el (gptel--convert-playback-markdown->org): New converter
    for markdown->org that works on text chunks while maintaining the
    parse state until the text stream is finished.
    
    * gptel-curl.el (gptel--insert-response-stream,
    gptel-curl-get-response): When using `gptel-playback' and
    requesting ChatGPT's responses in org-mode, run the above
    converter on the received response. This works by storing the
    converter and associated state as a closure in the async info
    plist that is supplied along with the response, and running it
    repeatedly on each chunk of text in the response stream before it
    is inserted into the buffer.
    
    FIXME: Note that `gptel-response-filter-functions' is currently
    ignored if using `gptel-stream'.
---
 gptel-curl.el | 18 ++++++++++++++----
 gptel.el      | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 66 insertions(+), 4 deletions(-)

diff --git a/gptel-curl.el b/gptel-curl.el
index e6ca0dd299..9c07d7113d 100644
--- a/gptel-curl.el
+++ b/gptel-curl.el
@@ -59,6 +59,8 @@ PROMPTS is the data to send, TOKEN is a unique identifier."
     (push (format "-d%s" data) args)
     (nreverse (cons url args))))
 
+;;TODO: The :transformer argument here is an alternate implementation of
+;;`gptel-response-filter-functions'. The two need to be unified.
 ;;;###autoload
 (defun gptel-curl-get-response (info &optional callback)
   "Retrieve response to prompt in INFO.
@@ -83,7 +85,13 @@ the response is inserted into the current buffer after 
point."
                          :callback (or callback
                                        (if gptel-playback
                                            #'gptel--insert-response-stream
-                                         #'gptel--insert-response)))
+                                         #'gptel--insert-response))
+                         :transformer (when (or (eq gptel-default-mode 
'org-mode)
+                                                (eq (buffer-local-value
+                                                     'major-mode
+                                                     (plist-get info 
:gptel-buffer))
+                                                    'org-mode))
+                                        
(gptel--convert-playback-markdown->org)))
                    info))
       (if gptel-playback
           (progn (set-process-sentinel process #'gptel-curl--cleanup-stream)
@@ -122,7 +130,8 @@ See `gptel--url-get-response' for details."
         (status-str  (plist-get response :status))
         (gptel-buffer (plist-get info :gptel-buffer))
         (start-marker (plist-get info :insert-marker))
-        (tracking-marker (plist-get info :tracking-marker)))
+        (tracking-marker (plist-get info :tracking-marker))
+        (transformer (plist-get info :transformer)))
     (if content-str
         (with-current-buffer gptel-buffer
           (save-excursion
@@ -134,8 +143,9 @@ See `gptel--url-get-response' for details."
               (set-marker-insertion-type tracking-marker t)
               (plist-put info :tracking-marker tracking-marker))
             
-            (setq content-str (gptel--transform-response
-                               content-str gptel-buffer))
+            (when transformer
+              (setq content-str (funcall transformer content-str)))
+            
             (put-text-property 0 (length content-str) 'gptel 'response 
content-str)
             (goto-char tracking-marker)
             (insert content-str)))
diff --git a/gptel.el b/gptel.el
index a1836b5589..18ed080db3 100644
--- a/gptel.el
+++ b/gptel.el
@@ -550,6 +550,58 @@ elements."
                      (insert "/")))))))
     (buffer-string)))
 
+(defun gptel--convert-playback-markdown->org ()
+  ""
+  (let ((in-src-block)
+        (temp-buf (generate-new-buffer-name "*gptel-temp*"))
+        (start-pt (make-marker)))
+    (lambda (str)
+      (let ((noop-p))
+        (with-current-buffer (get-buffer-create temp-buf)
+          (save-excursion (goto-char (point-max))
+                          (insert str))
+          (when (marker-position start-pt) (goto-char start-pt))
+          (save-excursion
+            (while (re-search-forward "`\\|\\*\\{1,2\\}\\|_" nil t)
+              (pcase (match-string 0)
+                ("`"
+                 (cond
+                  ((looking-at "``")
+                   (backward-char 1)
+                   (delete-char 3)
+                   (if in-src-block
+                       (progn (insert "#+end_src")
+                              (setq in-src-block nil))
+                     (insert "#+begin_src ")
+                     (setq in-src-block t)))
+                  ((looking-at "`\\|$")
+                   (setq noop-p t)
+                   (set-marker start-pt (1- (point)))
+                   (unless (eobp) (forward-char 1)))
+                  ((not in-src-block) (replace-match "="))))
+                ((and "**" (guard (not in-src-block)))
+                 (cond
+                  ((looking-at "\\*\\(?:[[:word:]]\\|\s\\)")
+                   (delete-char 1))
+                  ((looking-back "\\(?:[[:word:]]\\|\s\\)\\*\\{2\\}"
+                                 (max (- (point) 3) (point-min)))
+                   (backward-delete-char 1))))
+                ((and (or "_" "*") (guard (not in-src-block)))
+                 (when (save-match-data
+                         (save-excursion
+                           (backward-char 2)
+                           (or
+                            (looking-at
+                             
"[^[:space:][:punct:]\n]\\(?:_\\|\\*\\)\\(?:[[:space:][:punct:]]\\|$\\)")
+                            (looking-at
+                             
"\\(?:[[:space:][:punct:]]\\)\\(?:_\\|\\*\\)\\([^[:space:][:punct:]]\\|$\\)"))))
+                   (backward-delete-char 1)
+                   (insert "/"))))))
+          (if noop-p
+              (buffer-substring (point) start-pt)
+            (prog1 (buffer-substring (point) (point-max))
+                   (set-marker start-pt (point-max)))))))))
+
 (defun gptel--playback (buf content-str start-pt)
   "Playback CONTENT-STR in BUF.
 



reply via email to

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