branch: elpa/gptel
commit 604e34c875a72591563f97514ed74e855e0be802
Author: Karthik Chikmagalur <[email protected]>
Commit: Karthik Chikmagalur <[email protected]>

    gptel-request: Set backend consistently in multi-turn requests
    
    Some backend slots like the header and url can be functions that
    use gptel-backend and gptel-model from their environment.
    Previously, their "environment" was just the request buffer.  The
    backend and model can change mid-request in multi-turn requests,
    such as when employing sub-agents as tools, or if the user just
    happens to change them when a request is in progress.  This caused
    the request to throw an error as the wrong backend url/header
    functions were called.
    
    Hermetically "seal" the backend and model into the request INFO
    plist, and let-bind these values whenever calling a function whose
    behavior depends on them.  Currently this let-binding is required
    only when dispatching a new turn, in `gptel--url-get-response' and
    `gptel-curl--get-args', but this is something to keep in mind.
    
    Whenever possible, use (plist-get info :backend) and:(plist-get
    info :model) instead of the defvars `gptel-backend' and
    `gptel-model'.
    
    * gptel-request.el (gptel--realize-query): Store the model for the
    request in INFO.
    (gptel--url-get-response, gptel-curl--get-args): Let-bind the
    backend and model around calls correctly.
---
 gptel-request.el | 24 +++++++++++++-----------
 1 file changed, 13 insertions(+), 11 deletions(-)

diff --git a/gptel-request.el b/gptel-request.el
index 701c8df6b9c..f4043c3da40 100644
--- a/gptel-request.el
+++ b/gptel-request.el
@@ -2082,6 +2082,7 @@ Initiate the request when done."
           (gptel--inject-media gptel-backend full-prompt))
         (unless stream (cl-remf info :stream))
         (plist-put info :backend gptel-backend)
+        (plist-put info :model gptel-model)
         (when gptel-include-reasoning   ;Required for next-request-only scope
           (plist-put info :include-reasoning gptel-include-reasoning))
         (when (and gptel-use-tools gptel-tools)
@@ -2370,13 +2371,16 @@ the response is inserted into the current buffer after 
point."
   (let* ((inhibit-message t)
          (message-log-max nil)
          (url-request-method "POST")
+         (info (gptel-fsm-info fsm))
+         ;; We have to let-bind the following two since their dynamic
+         ;; values are used for key lookup and url resolution
+         (gptel-backend (plist-get info :backend))
+         (gptel-model (plist-get info :model))
          (url-request-extra-headers
           (append '(("Content-Type" . "application/json"))
                   (when-let* ((header (gptel-backend-header gptel-backend)))
                     (if (functionp header)
                         (funcall header) header))))
-         (info (gptel-fsm-info fsm))
-         (backend (plist-get info :backend))
          (callback (or (plist-get info :callback) ;if not the first run
                        #'gptel--insert-response)) ;default callback
          ;; NOTE: We don't need the decode-coding-string dance here since we
@@ -2398,14 +2402,13 @@ the response is inserted into the current buffer after 
point."
     (let ((proc-buf
            (url-retrieve (let ((backend-url (gptel-backend-url gptel-backend)))
                            (if (functionp backend-url)
-                               (with-current-buffer (plist-get info :buffer)
-                                 (funcall backend-url))
-                             backend-url))
+                               (funcall backend-url) backend-url))
                          (lambda (_)
                            (set-buffer-multibyte t)
                            (set-buffer-file-coding-system 'utf-8-unix)
                            (pcase-let ((`(,response ,http-status ,http-msg 
,error)
-                                        (gptel--url-parse-response backend 
info))
+                                        (gptel--url-parse-response
+                                         (plist-get info :backend) info))
                                        (buf (current-buffer)))
                              (plist-put info :http-status http-status)
                              (plist-put info :status http-msg)
@@ -2498,15 +2501,14 @@ See `gptel-curl--get-response' for its contents.")
 
 INFO contains the request data, TOKEN is a unique identifier."
   (let* ((data (plist-get info :data))
-         ;; We have to let-bind the following two variables since their dynamic
-         ;; values are used for key lookup and url resoloution
+         ;; We have to let-bind the following three since their dynamic
+         ;; values are used for key lookup and url resolution
          (gptel-backend (plist-get info :backend))
+         (gptel-model (plist-get info :model))
          (gptel-stream (plist-get info :stream))
          (url (let ((backend-url (gptel-backend-url gptel-backend)))
                 (if (functionp backend-url)
-                    (with-current-buffer (plist-get info :buffer)
-                      (funcall backend-url))
-                  backend-url)))
+                    (funcall backend-url) backend-url)))
          (data-json (decode-coding-string (gptel--json-encode data) 'utf-8 t))
          (headers
           (append '(("Content-Type" . "application/json"))

Reply via email to