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

    Update Ollama reasoning to use the latest reaosning API (#228)
    
    This should fix https://github.com/ahyatt/llm/issues/226.
---
 NEWS.org      |  2 ++
 llm-ollama.el | 88 ++++++++++++++++-------------------------------------------
 2 files changed, 26 insertions(+), 64 deletions(-)

diff --git a/NEWS.org b/NEWS.org
index 2bc2eb25a0..45f49bbe6d 100644
--- a/NEWS.org
+++ b/NEWS.org
@@ -1,3 +1,5 @@
+* Version 0.28.4
+- Fixed Ollama reasoning, whose API has changed
 * Version 0.28.3
 - Fixed breakage in Ollama streaming tool calling
 - Fixed incorrect Ollama streaming tool use capability reporting
diff --git a/llm-ollama.el b/llm-ollama.el
index c4eccdbe7d..deca6898ed 100644
--- a/llm-ollama.el
+++ b/llm-ollama.el
@@ -112,46 +112,12 @@ PROVIDER is the llm-ollama provider."
 (cl-defmethod llm-provider-batch-embeddings-extract-result ((_ llm-ollama) 
response)
   (append (assoc-default 'embeddings response) nil))
 
-(eval-and-compile
-  (defconst llm-ollama-reasoning-tags '("think" "reasoning")
-    "A list of possibilities for reasoning tags in Ollama responses.
-
-These are just the text inside the tag, not the tag itself."))
-
 (cl-defmethod llm-provider-chat-extract-result ((_ llm-ollama) response)
   "Return the chat response from the server RESPONSE."
-  (let ((raw-result (assoc-default 'content (assoc-default 'message 
response))))
-    ;; The raw result may have reasoning content in, which is in <think> tags
-    ;; (for DeepSeek reasoning).  We want to strip that out.
-    (with-temp-buffer
-      (insert raw-result)
-      (goto-char 0)
-      (if (seq-find (lambda (tag)
-                      (search-forward (format "</%s>" tag) nil t))
-                    llm-ollama-reasoning-tags)
-          (string-trim (buffer-substring (point) (point-max)))
-        raw-result))))
+  (assoc-default 'content (assoc-default 'message response)))
 
 (cl-defmethod llm-provider-extract-reasoning ((_ llm-ollama) response)
-  (let ((raw-result (assoc-default 'content (assoc-default 'message 
response))))
-    ;; Reasoning content is in <think> tags (for DeepSeek reasoning).  We want 
to
-    ;; extract the content between these tags.
-    (with-temp-buffer
-      (insert raw-result)
-      (goto-char 0)
-      (when (re-search-forward
-             (rx (seq (literal "<")
-                      (group (eval `(or ,@llm-ollama-reasoning-tags)))
-                      (literal ">")))
-             nil t)
-        (when-let* ((end (save-excursion
-                           (re-search-forward
-                            (rx (seq
-                                 (literal "</")
-                                 (group (literal (match-string 1)))
-                                 (literal ">"))) nil t))))
-          ;; +3 to account for the length of the two brackets and slash
-          (buffer-substring (point) (- end (+ 3 (length (match-string 
1))))))))))
+  (assoc-default 'thinking (assoc-default 'message response)))
 
 (defun llm-ollama--response-format (format)
   "Return the response format for FORMAT."
@@ -237,34 +203,28 @@ These are just the text inside the tag, not the tag 
itself."))
 (cl-defmethod llm-provider-streaming-media-handler ((_ llm-ollama) receiver _)
   (cons 'application/x-ndjson
         (plz-media-type:application/x-ndjson
-         :handler (let ((in-reasoning))
-                    (lambda (data)
-                      (let* ((message (assoc-default 'message data))
-                             (text (assoc-default 'content message))
-                             (tool-call (assoc-default 'tool_calls message))
-                             (response nil))
-                        (when (and text (> (length text) 0))
-                          ;; The response from ollama should just have the tag 
and
-                          ;; nothing more.
-                          (cond
-                           ((string-match (rx
-                                           (seq "<"
-                                                (eval `(or 
,@llm-ollama-reasoning-tags))
-                                                ">")) text)
-                            (setq in-reasoning t))
-                           ((string-match (rx
-                                           (seq "</"
-                                                (eval `(or 
,@llm-ollama-reasoning-tags))
-                                                ">")) text)
-                            (setq in-reasoning nil))
-                           (t
-                            (setq response
-                                  (plist-put response (if in-reasoning 
:reasoning :text) text)))))
-                        (when tool-call
-                          (setq response
-                                (plist-put response :tool-uses-raw
-                                           (aref tool-call 0))))
-                        (funcall receiver response)))))))
+         :handler (lambda (data)
+                    (let* ((message (assoc-default 'message data))
+                           (text (assoc-default 'content message))
+                           (reasoning (assoc-default 'thinking message))
+                           (tool-call (assoc-default 'tool_calls message))
+                           (response nil))
+                      (when reasoning
+                        (setq response
+                              (plist-put response :reasoning
+                                         (concat
+                                          (or (plist-get response :reasoning) 
"")
+                                          reasoning))))
+                      (when text
+                        (setq response
+                              (plist-put response :text (concat
+                                                         (or (plist-get 
response :text) "")
+                                                         text))))
+                      (when tool-call
+                        (setq response
+                              (plist-put response :tool-uses-raw
+                                         (aref tool-call 0))))
+                      (funcall receiver response))))))
 
 (cl-defmethod llm-provider-collect-streaming-tool-uses ((_ llm-ollama) data)
   ;; Ollama only supports one tool used at a time.

Reply via email to