Skip to content

Commit 0c67daa

Browse files
committed
Support reasoning for ollama models that support think
1 parent fcbdd33 commit 0c67daa

File tree

9 files changed

+57
-33
lines changed

9 files changed

+57
-33
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
## Unreleased
44

5+
- Support reasoning for ollama models that support think.
6+
57
## 0.12.7
68

79
- Fix ollama tool calls.

docs/configuration.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ interface Config {
160160
host: string;
161161
port: string;
162162
useTools: boolean;
163+
think: boolean;
163164
};
164165
chat?: {
165166
welcomeMessage: string;
@@ -192,7 +193,8 @@ interface Config {
192193
"ollama" : {
193194
"host" : "http://localhost",
194195
"port" : 11434,
195-
"useTools": false
196+
"useTools": false,
197+
"think": true
196198
},
197199
"chat" : {
198200
"welcomeMessage" : "Welcome to ECA! What you have in mind?\n\n"

src/eca/config.clj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@
2727
:mcpServers {}
2828
:ollama {:host "http://localhost"
2929
:port 11434
30-
:useTools true}
30+
:useTools true
31+
:think true}
3132
:chat {:welcomeMessage "Welcome to ECA!\n\nType '/' for commands\n\n"}
3233
:customProviders {}
3334
:index {:ignoreFiles [{:type :gitignore}]}})

src/eca/handlers.clj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@
3333
(fn [models {:keys [model]}]
3434
(assoc models
3535
(str config/ollama-model-prefix model)
36-
{:tools (get-in config [:ollama :useTools] false)}))
36+
{:tools (get-in config [:ollama :useTools] false)
37+
:think (get-in config [:ollama :think] false)}))
3738
{}
3839
ollama-models))))
3940

src/eca/llm_api.clj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@
145145
(llm-providers.ollama/completion!
146146
{:host (-> config :ollama :host)
147147
:port (-> config :ollama :port)
148-
:reason? reason?
148+
:reason? (and reason? (:think model-config))
149149
:model (string/replace-first model config/ollama-model-prefix "")
150150
:instructions instructions
151151
:user-messages user-messages

src/eca/llm_providers/ollama.clj

Lines changed: 44 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -37,26 +37,28 @@
3737

3838
(defn ^:private base-completion-request! [{:keys [rid url body on-error on-response]}]
3939
(llm-util/log-request logger-tag rid url body)
40-
(http/post
41-
url
42-
{:body (json/generate-string body)
43-
:throw-exceptions? false
44-
:async? true
45-
:as :stream}
46-
(fn [{:keys [status body]}]
47-
(try
48-
(if (not= 200 status)
49-
(let [body-str (slurp body)]
50-
(logger/warn logger-tag "Unexpected response status: %s body: %s" status body-str)
51-
(on-error {:message (format "Ollama response status: %s body: %s" status body-str)}))
52-
(with-open [rdr (io/reader body)]
53-
(doseq [[event data] (llm-util/event-data-seq rdr)]
54-
(llm-util/log-response logger-tag rid event data)
55-
(on-response rid event data))))
56-
(catch Exception e
57-
(on-error {:exception e}))))
58-
(fn [e]
59-
(on-error {:exception e}))))
40+
(let [reason-id (str (random-uuid))
41+
reasoning?* (atom false)]
42+
(http/post
43+
url
44+
{:body (json/generate-string body)
45+
:throw-exceptions? false
46+
:async? true
47+
:as :stream}
48+
(fn [{:keys [status body]}]
49+
(try
50+
(if (not= 200 status)
51+
(let [body-str (slurp body)]
52+
(logger/warn logger-tag "Unexpected response status: %s body: %s" status body-str)
53+
(on-error {:message (format "Ollama response status: %s body: %s" status body-str)}))
54+
(with-open [rdr (io/reader body)]
55+
(doseq [[event data] (llm-util/event-data-seq rdr)]
56+
(llm-util/log-response logger-tag rid event data)
57+
(on-response rid event data reasoning?* reason-id))))
58+
(catch Exception e
59+
(on-error {:exception e}))))
60+
(fn [e]
61+
(on-error {:exception e})))))
6062

6163
(defn ^:private ->tools [tools]
6264
(mapv (fn [tool]
@@ -70,22 +72,24 @@
7072
"tool_call" {:role "assistant" :tool-calls [{:type "function"
7173
:function content}]}
7274
"tool_call_output" {:role "tool" :content (llm-util/stringfy-tool-result content)}
75+
"reason" {:role "assistant" :content (:text content)}
7376
msg))
7477
past-messages))
7578

76-
(defn completion! [{:keys [model user-messages instructions host port past-messages tools]}
77-
{:keys [on-message-received on-error on-prepare-tool-call on-tool-called]}]
79+
(defn completion! [{:keys [model user-messages reason? instructions host port past-messages tools]}
80+
{:keys [on-message-received on-error on-prepare-tool-call on-tool-called
81+
on-reason]}]
7882
(let [messages (concat
7983
(normalize-messages (concat [{:role "system" :content instructions}] past-messages))
8084
(normalize-messages user-messages))
8185
body {:model model
8286
:messages messages
83-
:think false
87+
:think reason?
8488
:tools (->tools tools)
8589
:stream true}
8690
url (format chat-url (base-url host port))
8791
tool-calls* (atom {})
88-
on-response-fn (fn handle-response [rid _event data]
92+
on-response-fn (fn handle-response [rid _event data reasoning?* reason-id]
8993
(let [{:keys [message done_reason]} data]
9094
(cond
9195
(seq (:tool_calls message))
@@ -111,8 +115,22 @@
111115
:finish-reason done_reason}))
112116

113117
message
114-
(on-message-received {:type :text
115-
:text (:content message)}))))]
118+
(if (:thinking message)
119+
(do
120+
(when-not @reasoning?*
121+
(on-reason {:status :started
122+
:id reason-id})
123+
(reset! reasoning?* true))
124+
(on-reason {:status :thinking
125+
:id reason-id
126+
:text (:thinking message)}))
127+
(do
128+
(when @reasoning?*
129+
(on-reason {:status :finished
130+
:id reason-id})
131+
(reset! reasoning?* false))
132+
(on-message-received {:type :text
133+
:text (:content message)}))))))]
116134
(base-completion-request!
117135
{:rid (llm-util/gen-rid)
118136
:url url

test/eca/llm_providers/anthropic_test.clj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
[eca.llm-providers.anthropic :as llm-providers.anthropic]
55
[matcher-combinators.test :refer [match?]]))
66

7-
(deftest ->messages-with-history-test
7+
(deftest ->normalize-messages-test
88
(testing "no previous history"
99
(is (match?
1010
[]

test/eca/llm_providers/ollama_test.clj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
[eca.llm-providers.ollama :as llm-providers.ollama]
55
[matcher-combinators.test :refer [match?]]))
66

7-
(deftest ->messages-with-history-test
7+
(deftest ->normalize-messages-test
88
(testing "no previous history"
99
(is (match?
1010
[]

test/eca/llm_providers/openai_test.clj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
[eca.llm-providers.openai :as llm-providers.openai]
55
[matcher-combinators.test :refer [match?]]))
66

7-
(deftest ->messages-with-history-test
7+
(deftest ->normalize-messages-test
88
(testing "no previous history"
99
(is (match?
1010
[]

0 commit comments

Comments
 (0)