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

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

[nongnu] elpa/gptel 397cc2fc7c: gptel-anthropic: Handle streaming + thin


From: ELPA Syncer
Subject: [nongnu] elpa/gptel 397cc2fc7c: gptel-anthropic: Handle streaming + thinking + tool-use
Date: Mon, 31 Mar 2025 19:00:38 -0400 (EDT)

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

    gptel-anthropic: Handle streaming + thinking + tool-use
    
    * gptel-anthropic.el (gptel-curl--parse-stream): When tool-use is
    enabled, we preserve the messages array until the back-and-forth
    exchange is complete.  The Anthropic API requires the last
    assistant message in this growing messages array (sent back and
    forth) to contain a thinking section when thinking and tools are
    both enabled.  Ensure that we pack the thinking block correctly
    into the messages array (with a signature field) when using both
    thinking and tools. (#743)
    
    This fix is not required for the non-streaming case since the
    thinking block is already supplied in the form required to send
    back to the model.
---
 gptel-anthropic.el | 21 ++++++++++++++++-----
 1 file changed, 16 insertions(+), 5 deletions(-)

diff --git a/gptel-anthropic.el b/gptel-anthropic.el
index 307636fcf0..bd5c58bb74 100644
--- a/gptel-anthropic.el
+++ b/gptel-anthropic.el
@@ -54,8 +54,9 @@
 ;; Do NOT change the plist-put to push or setf!
 
 ;; NOTE: The stream parser looks complicated only because it handles streaming
-;; tool calls.  Stream parsing is simple: if you are studying this code, look 
at
-;; a commit from before tool-use support was added to gptel.
+;; tool calls, streaming "thinking" blocks and their interactions.  Stream
+;; parsing is simple: if you are studying this code, look instead at a commit
+;; from before tool-use support was added to gptel.
 (cl-defmethod gptel-curl--parse-stream ((_backend gptel-anthropic) info)
   "Parse an Anthropic data stream.
 
@@ -82,7 +83,10 @@ information if the stream contains it.  Not my best work, I 
know."
                      (cons partial-json (plist-get info :partial_json)))
                   (if-let* ((thinking (plist-get delta :thinking)))
                       (plist-put info :reasoning
-                                 (concat (plist-get info :reasoning) 
thinking)))))))
+                                 (concat (plist-get info :reasoning) thinking))
+                    (if-let* ((signature (plist-get delta :signature)))
+                        (plist-put info :signature
+                                   (concat (plist-get info :signature) 
signature))))))))
            
            ((looking-at "content_block_start") ;Is the following block text or 
tool-use?
             (forward-line 1) (forward-char 5)
@@ -126,9 +130,12 @@ information if the stream contains it.  Not my best work, 
I know."
                  (vconcat
                   prompts
                   `((:role "assistant"
-                     :content ,(vconcat ;Insert any LLM text
+                     :content ,(vconcat ;Insert any LLM text and thinking text
+                                (and-let* ((reasoning (plist-get info 
:partial_reasoning)))
+                                 `((:type "thinking" :thinking ,reasoning
+                                    :signature ,(plist-get info :signature))))
                                 (and-let* ((strs (plist-get info 
:partial_text)))
-                                 (list (list :type "text" :text (apply 
#'concat (nreverse strs)))))
+                                 `((:type "text" :text ,(apply #'concat 
(nreverse strs)))))
                                 (mapcar (lambda (tool-call) ;followed by the 
tool calls
                                           (append (list :type "tool_use")
                                            (copy-sequence tool-call)))
@@ -150,6 +157,10 @@ information if the stream contains it.  Not my best work, 
I know."
       (unless (string-empty-p response-text)
         (plist-put info :partial_text
                    (cons response-text (plist-get info :partial_text))))
+      (when (plist-get info :tools)
+        (when-let* ((reasoning (plist-get info :reasoning)))
+          (plist-put info :partial_reasoning
+                     (concat (plist-get info :partial_reasoning) reasoning))))
       response-text)))
 
 (cl-defmethod gptel--parse-response ((_backend gptel-anthropic) response info)



reply via email to

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