branch: elpa/gptel
commit 135063383230d6ba341e18d32efae030cadc6d6a
Author: Karthik Chikmagalur <karthikchikmaga...@gmail.com>
Commit: Karthik Chikmagalur <karthikchikmaga...@gmail.com>

    gptel: Fix dispatch on prompt types in gptel--parse-list
    
    `gptel-request' accepts two kinds of prompt lists as arguments --
    a list of strings and a list of lists/cons cells.
    (The second kind is currently experimental and undocumented.)  In
    `gptel--parse-list', we distinguish between them by checking if
    the car of the prompt is a string.  But the car can also be nil,
    and this check fails.  Fix by checking if the car of the prompts
    list is a cons instead.
    
    * gptel-anthropic.el (gptel--parse-list): Make the change.
    * gptel-gemini.el (gptel--parse-list): Make the change.
    * gptel-ollama.el (gptel--parse-list): Make the change.
    * gptel-openai.el (gptel--parse-list): Make the change.
---
 gptel-anthropic.el | 54 +++++++++++++++++++++++++++---------------------------
 gptel-gemini.el    | 52 ++++++++++++++++++++++++++--------------------------
 gptel-ollama.el    | 46 +++++++++++++++++++++++-----------------------
 gptel-openai.el    | 54 +++++++++++++++++++++++++++---------------------------
 4 files changed, 103 insertions(+), 103 deletions(-)

diff --git a/gptel-anthropic.el b/gptel-anthropic.el
index fcc2f67543..0e9b8743ca 100644
--- a/gptel-anthropic.el
+++ b/gptel-anthropic.el
@@ -314,33 +314,33 @@ TOOL-USE is a list of plists containing tool names, 
arguments and call results."
 
 (cl-defmethod gptel--parse-list ((backend gptel-anthropic) prompt-list)
   (let ((full-prompt
-         (if (stringp (car prompt-list))
-             (cl-loop for text in prompt-list ; Simple format, list of strings
-                      for role = t then (not role)
-                      if text
-                      collect (list :role (if role "user" "assistant")
-                                    :content `[(:type "text" :text ,text)]))
-           (let ((prompts))
-             (dolist (entry prompt-list) ; Advanced format, list of lists
-               (pcase entry
-                 (`(prompt . ,msg)
-                  (push (list :role "user"
-                              :content `[(:type "text" :text ,(or (car-safe 
msg) msg))])
-                        prompts))
-                 (`(response . ,msg)
-                  (push (list :role "assistant"
-                              :content `[(:type "text" :text ,(or (car-safe 
msg) msg))])
-                        prompts))
-                 (`(tool . ,call)
-                  (unless (plist-get call :id)
-                    (plist-put call :id (gptel--anthropic-format-tool-id nil)))
-                  (push (list :role "assistant"
-                              :content `[( :type "tool_use" :id ,(plist-get 
call :id)
-                                           :name ,(plist-get call :name)
-                                           :input ,(plist-get call :args))])
-                        prompts)
-                  (push (gptel--parse-tool-results backend (list (cdr entry))) 
prompts))))
-             (nreverse prompts)))))
+         (if (consp (car prompt-list))
+             (let ((prompts))
+               (dolist (entry prompt-list) ; Advanced format, list of lists
+                 (pcase entry
+                   (`(prompt . ,msg)
+                    (push (list :role "user"
+                                :content `[(:type "text" :text ,(or (car-safe 
msg) msg))])
+                          prompts))
+                   (`(response . ,msg)
+                    (push (list :role "assistant"
+                                :content `[(:type "text" :text ,(or (car-safe 
msg) msg))])
+                          prompts))
+                   (`(tool . ,call)
+                    (unless (plist-get call :id)
+                      (plist-put call :id (gptel--anthropic-format-tool-id 
nil)))
+                    (push (list :role "assistant"
+                                :content `[( :type "tool_use" :id ,(plist-get 
call :id)
+                                             :name ,(plist-get call :name)
+                                             :input ,(plist-get call :args))])
+                          prompts)
+                    (push (gptel--parse-tool-results backend (list (cdr 
entry))) prompts))))
+               (nreverse prompts))
+           (cl-loop for text in prompt-list ; Simple format, list of strings
+                    for role = t then (not role)
+                    if text
+                    collect (list :role (if role "user" "assistant")
+                                  :content `[(:type "text" :text ,text)])))))
     ;; cache messages if required: add cache_control to the last message
     (when (and (or (eq gptel-cache t) (memq 'message gptel-cache))
                (gptel--model-capable-p 'cache))
diff --git a/gptel-gemini.el b/gptel-gemini.el
index abd0e307e0..6b4cdb7314 100644
--- a/gptel-gemini.el
+++ b/gptel-gemini.el
@@ -228,32 +228,32 @@ See generic implementation for full documentation."
     (plist-put data :contents (vconcat prompts (list new-prompt)))))
 
 (cl-defmethod gptel--parse-list ((backend gptel-gemini) prompt-list)
-  (if (stringp (car prompt-list))
-      (cl-loop for text in prompt-list  ; Simple format, list of strings
-               for role = t then (not role)
-               if text
-               if role
-               collect (list :role "user" :parts `[(:text ,text)]) into prompts
-               else collect (list :role "model" :parts `(:text ,text)) into 
prompts
-               finally return prompts)
-    (let ((full-prompt))                ; Advanced format, list of lists
-      (dolist (entry prompt-list)
-        (pcase entry
-          (`(prompt . ,msg)
-           (push (list :role "user"
-                       :parts `[(:text ,(or (car-safe msg) msg))])
-                 full-prompt))
-          (`(response . ,msg)
-           (push (list :role "model"
-                       :parts `[(:text ,(or (car-safe msg) msg))])
-                 full-prompt))
-          (`(tool . ,call)
-           (push (list :role "model"
-                       :parts (vector `(:functionCall ( :name ,(plist-get call 
:name)
-                                                        :args ,(plist-get call 
:args)))))
-                 full-prompt)
-           (push (gptel--parse-tool-results backend (list (cdr entry))) 
full-prompt))))
-      (nreverse full-prompt))))
+  (if (consp (car prompt-list))
+      (let ((full-prompt))              ; Advanced format, list of lists
+        (dolist (entry prompt-list)
+          (pcase entry
+            (`(prompt . ,msg)
+             (push (list :role "user"
+                         :parts `[(:text ,(or (car-safe msg) msg))])
+                   full-prompt))
+            (`(response . ,msg)
+             (push (list :role "model"
+                         :parts `[(:text ,(or (car-safe msg) msg))])
+                   full-prompt))
+            (`(tool . ,call)
+             (push (list :role "model"
+                         :parts (vector `(:functionCall ( :name ,(plist-get 
call :name)
+                                                          :args ,(plist-get 
call :args)))))
+                   full-prompt)
+             (push (gptel--parse-tool-results backend (list (cdr entry))) 
full-prompt))))
+        (nreverse full-prompt))
+    (cl-loop for text in prompt-list    ; Simple format, list of strings
+             for role = t then (not role)
+             if text
+             if role
+             collect (list :role "user" :parts `[(:text ,text)]) into prompts
+             else collect (list :role "model" :parts `(:text ,text)) into 
prompts
+             finally return prompts)))
 
 (cl-defmethod gptel--parse-buffer ((backend gptel-gemini) &optional 
max-entries)
   (let ((prompts) (prev-pt (point))
diff --git a/gptel-ollama.el b/gptel-ollama.el
index 51d265d520..1253d27601 100644
--- a/gptel-ollama.el
+++ b/gptel-ollama.el
@@ -136,29 +136,29 @@ Store response metadata in state INFO."
 ;; handled by its defgeneric implementation
 
 (cl-defmethod gptel--parse-list ((backend gptel-ollama) prompt-list)
-  (if (stringp (car prompt-list))
-      (cl-loop for text in prompt-list  ; Simple format, list of strings
-               for role = t then (not role)
-               if text collect
-               (list :role (if role "user" "assistant") :content text))
-    (let ((full-prompt))                ; Advanced format, list of lists
-      (dolist (entry prompt-list)
-        (pcase entry
-          (`(prompt . ,msg)
-           (push (list :role "user" :content (or (car-safe msg) msg))
-                 full-prompt))
-          (`(response . ,msg)
-           (push (list :role "assistant" :content (or (car-safe msg) msg))
-                 full-prompt))
-          (`(tool . ,call)
-           (push (list :role "assistant"
-                       :content ""
-                       :tool_calls `[(:function (:name ,(plist-get call :name)
-                                                 :arguments ,(plist-get call 
:args)))])
-                 full-prompt)
-           (push (car (gptel--parse-tool-results backend (list (cdr entry))))
-                 full-prompt))))
-      (nreverse full-prompt))))
+  (if (consp (car prompt-list))
+      (let ((full-prompt))              ; Advanced format, list of lists
+        (dolist (entry prompt-list)
+          (pcase entry
+            (`(prompt . ,msg)
+             (push (list :role "user" :content (or (car-safe msg) msg))
+                   full-prompt))
+            (`(response . ,msg)
+             (push (list :role "assistant" :content (or (car-safe msg) msg))
+                   full-prompt))
+            (`(tool . ,call)
+             (push (list :role "assistant"
+                         :content ""
+                         :tool_calls `[(:function (:name ,(plist-get call 
:name)
+                                                   :arguments ,(plist-get call 
:args)))])
+                   full-prompt)
+             (push (car (gptel--parse-tool-results backend (list (cdr entry))))
+                   full-prompt))))
+        (nreverse full-prompt))
+    (cl-loop for text in prompt-list    ; Simple format, list of strings
+             for role = t then (not role)
+             if text collect
+             (list :role (if role "user" "assistant") :content text))))
 
 (cl-defmethod gptel--parse-buffer ((backend gptel-ollama) &optional 
max-entries)
   (let ((prompts) (prev-pt (point))
diff --git a/gptel-openai.el b/gptel-openai.el
index d77444a2cd..5de95d709d 100644
--- a/gptel-openai.el
+++ b/gptel-openai.el
@@ -350,33 +350,33 @@ If the ID has the format used by a different backend, use 
as-is."
 ;; is handled by its defgeneric implementation
 
 (cl-defmethod gptel--parse-list ((backend gptel-openai) prompt-list)
-  (if (stringp (car prompt-list))
-      (cl-loop for text in prompt-list  ; Simple format, list of strings
-               for role = t then (not role)
-               if text collect
-               (list :role (if role "user" "assistant") :content text))
-    (let ((full-prompt))                ; Advanced format, list of lists
-      (dolist (entry prompt-list)
-        (pcase entry
-          (`(prompt . ,msg)
-           (push (list :role "user" :content (or (car-safe msg) msg)) 
full-prompt))
-          (`(response . ,msg)
-           (push (list :role "assistant" :content (or (car-safe msg) msg)) 
full-prompt))
-          (`(tool . ,call)
-           (unless (plist-get call :id)
-             (plist-put call :id (gptel--openai-format-tool-id nil)))
-           (push
-            (list
-             :role "assistant"
-             :tool_calls
-             (vector
-              (list :type "function"
-                    :id (plist-get call :id)
-                    :function `( :name ,(plist-get call :name)
-                                 :arguments ,(gptel--json-encode (plist-get 
call :args))))))
-            full-prompt)
-           (push (car (gptel--parse-tool-results backend (list (cdr entry)))) 
full-prompt))))
-      (nreverse full-prompt))))
+  (if (consp (car prompt-list))
+      (let ((full-prompt))              ; Advanced format, list of lists
+        (dolist (entry prompt-list)
+          (pcase entry
+            (`(prompt . ,msg)
+             (push (list :role "user" :content (or (car-safe msg) msg)) 
full-prompt))
+            (`(response . ,msg)
+             (push (list :role "assistant" :content (or (car-safe msg) msg)) 
full-prompt))
+            (`(tool . ,call)
+             (unless (plist-get call :id)
+               (plist-put call :id (gptel--openai-format-tool-id nil)))
+             (push
+              (list
+               :role "assistant"
+               :tool_calls
+               (vector
+                (list :type "function"
+                      :id (plist-get call :id)
+                      :function `( :name ,(plist-get call :name)
+                                   :arguments ,(gptel--json-encode (plist-get 
call :args))))))
+              full-prompt)
+             (push (car (gptel--parse-tool-results backend (list (cdr 
entry)))) full-prompt))))
+        (nreverse full-prompt))
+    (cl-loop for text in prompt-list    ; Simple format, list of strings
+             for role = t then (not role)
+             if text collect
+             (list :role (if role "user" "assistant") :content text))))
 
 (cl-defmethod gptel--parse-buffer ((backend gptel-openai) &optional 
max-entries)
   (let ((prompts) (prev-pt (point))

Reply via email to