branch: externals/llm
commit d5085859d22efb57c4d5c95ec8a5a9e54d112cc5
Author: Andrew Hyatt <[email protected]>
Commit: GitHub <[email protected]>

    Add reasoning output for Gemini (#210)
---
 NEWS.org      |  2 ++
 llm-vertex.el | 51 ++++++++++++++++++++++++++++++++++++---------------
 2 files changed, 38 insertions(+), 15 deletions(-)

diff --git a/NEWS.org b/NEWS.org
index 8283847ce5..d7dce6ee11 100644
--- a/NEWS.org
+++ b/NEWS.org
@@ -1,3 +1,5 @@
+* Version 0.27.3
+- Add reasoning output for Gemini.
 * Version 0.27.2
 - Add JSON response capabilities to Gemini, which had a non-standard API.
 - Add Claude 4.1 to supported models
diff --git a/llm-vertex.el b/llm-vertex.el
index 31677de833..b587e9ebf7 100644
--- a/llm-vertex.el
+++ b/llm-vertex.el
@@ -153,7 +153,23 @@ the key must be regenerated every hour."
                              (assoc-default 'content
                                             (aref (assoc-default 'candidates 
response) 0)))))
                  (when parts
-                   (assoc-default 'text (aref parts (- (length parts) 
1)))))))))
+                   (assoc-default 'text (seq-find (lambda (part)
+                                                    (not (assoc-default 
'thought part)))
+                                                  parts))))))))
+
+(cl-defmethod llm-provider-extract-reasoning ((provider llm-google) response)
+  (if (vectorp response)
+      (llm-provider-extract-reasoning provider (aref response 0))
+    ;; In some error cases, the response does not have any candidates.
+    (when (assoc-default 'candidates response)
+      (when-let* ((parts (assoc-default
+                          'parts (assoc-default
+                                  'content
+                                  (aref (assoc-default 'candidates response) 
0))))
+                  (thought-part (seq-find (lambda (part)
+                                            (assoc-default 'thought part))
+                                          parts)))
+        (assoc-default 'text thought-part)))))
 
 (cl-defmethod llm-provider-extract-tool-uses ((provider llm-google) response)
   (if (vectorp response)
@@ -254,12 +270,12 @@ the key must be regenerated every hour."
                                                       (setq inner-plist 
(plist-put inner-plist
                                                                                
    prop
                                                                                
    (llm-vertex-transform-response-format prep-def))))
-                                                      v)
+                                                    v)
                                             inner-plist))
                                          ((eq k :items)
                                           
(llm-vertex-transform-response-format v))
                                          (t v))))))
-              format)
+            format)
     result))
 
 (cl-defmethod llm-provider-chat-request ((provider llm-vertex) prompt _)
@@ -287,18 +303,23 @@ which is necessary to properly set some paremeters."
         (setq params-plist (plist-put params-plist :response_schema
                                       (llm-vertex-transform-response-format
                                        
(llm-provider-utils-convert-to-serializable format))))))
-    (when-let ((budget (llm-chat-prompt-reasoning prompt))
-               (max-budget (if (eq model 'gemini-2.5-pro) 32768 24576)))
-      (when (member 'reasoning (llm-model-capabilities (llm-models-by-symbol 
model)))
-        (if (and (eq model 'gemini-2.5-pro) (eq budget 'none))
-            (display-warning 'llm :warning "Cannot turn off reasoning in 
Gemini 2.5 Pro, ignoring reasoning setting")
-          (setq params-plist (plist-put params-plist :thinkingConfig
-                                                           `(:thinkingBudget
-                                          ,(pcase budget
-                                             ('none 0)
-                                             ('light 1024)
-                                             ('medium (/ max-budget 2))
-                                             ('maximum max-budget))))))))
+    (let* (thinking-plist
+           (model-data (llm-models-by-symbol model)))
+      (when (and model-data (member 'reasoning (llm-model-capabilities 
model-data)))
+        (setq thinking-plist '(:includeThoughts t))
+        (when-let ((budget (llm-chat-prompt-reasoning prompt))
+                   (max-budget (if (eq model 'gemini-2.5-pro) 32768 24576)))
+          (if (and (eq model 'gemini-2.5-pro) (eq budget 'none))
+              (display-warning 'llm :warning "Cannot turn off reasoning in 
Gemini 2.5 Pro, ignoring reasoning setting")
+            (setq thinking-plist (plist-put thinking-plist
+                                            :thinkingBudget
+                                            (pcase budget
+                                              ('none 0)
+                                              ('light 1024)
+                                              ('medium (/ max-budget 2))
+                                              ('maximum max-budget)))))))
+      (when thinking-plist
+        (setq params-plist (plist-put params-plist :thinkingConfig 
thinking-plist))))
     (when params-plist
       `(:generationConfig ,params-plist))))
 

Reply via email to