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.