Skip to content

Commit f5d5e4f

Browse files
authored
Merge pull request #235 from editor-code-assistant/fix-deepseek-openai-chat-reasoning
Fix DeepSeek reasoning support in openai-chat API
2 parents d1ee639 + 5c18fe0 commit f5d5e4f

File tree

6 files changed

+437
-228
lines changed

6 files changed

+437
-228
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
- Support Google Gemini thought signatures.
66
- Support `gemini-3-pro-preview` model.
7+
- Fix deepseek reasoning with openai-chat API #228
78
- Support `~` in dynamic string parser.
89
- Support removing nullable values from LLM request body if the value in extraPayload is null. #232
910

@@ -12,6 +13,7 @@
1213
- Improve agent behavior prompt to mention usage of editor_diagnostics tool. #230
1314
- Use selmer syntax for prompt templates.
1415

16+
1517
## 0.85.3
1618

1719
- Support `openai/gpt-5.2` and `github-copilot/gpt-5.2` by default.

src/eca/features/chat.clj

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@
1919
[eca.logger :as logger]
2020
[eca.messenger :as messenger]
2121
[eca.metrics :as metrics]
22-
[eca.shared :as shared :refer [assoc-some future*]]))
22+
[eca.shared :as shared :refer [assoc-some future*]]
23+
[eca.llm-util :as llm-util]))
2324

2425
(set! *warn-on-reflection* true)
2526

@@ -81,13 +82,11 @@
8182
(let [entry {:type :text :text (wrap-additional-context hook-name additional-context)}]
8283
(swap! db* update-in [:chats chat-id :messages]
8384
;; Optimized: Scans messages backwards since the tool output is likely one of the last items.
84-
#(let [idx (loop [i (dec (count %))]
85-
(when (>= i 0)
86-
(let [msg (nth % i)]
87-
(if (and (= "tool_call_output" (:role msg))
88-
(= tool-call-id (get-in msg [:content :id])))
89-
i
90-
(recur (dec i))))))]
85+
#(let [idx (llm-util/find-last-msg-idx
86+
(fn [msg]
87+
(and (= "tool_call_output" (:role msg))
88+
(= tool-call-id (get-in msg [:content :id]))))
89+
%)]
9190
(if idx
9291
(update-in % [idx :content :output :contents] conj entry)
9392
%))))))
@@ -811,10 +810,6 @@
811810
hook-rejected? (assoc :hook-continue hook-continue
812811
:hook-stop-reason hook-stop-reason))))
813812

814-
(defn ^:private find-last-user-msg-idx [messages]
815-
;; Returns the index of the last :role "user" message, or nil if none.
816-
(last (keep-indexed (fn [i m] (when (= "user" (:role m)) i)) messages)))
817-
818813
(defn ^:private on-tools-called! [{:keys [db* config chat-id behavior messenger metrics] :as chat-ctx}
819814
received-msgs* add-to-history!]
820815
(let [all-tools (f.tools/all-tools chat-id behavior @db* config)]
@@ -1026,7 +1021,7 @@
10261021
(run-pre-request-hooks! (assoc chat-ctx :message original-text))]
10271022
(cond
10281023
stop? (do (finish-chat-prompt! :idle chat-ctx) nil)
1029-
:else (let [last-user-idx (or (find-last-user-msg-idx user-messages)
1024+
:else (let [last-user-idx (or (llm-util/find-last-user-msg-idx user-messages)
10301025
(dec (count user-messages)))
10311026
rewritten (if (and modify-allowed?
10321027
last-user-idx
@@ -1135,20 +1130,22 @@
11351130
:arguments-text arguments-text
11361131
:summary (f.tools/tool-call-summary all-tools full-name nil config)})))
11371132
:on-tools-called (on-tools-called! chat-ctx received-msgs* add-to-history!)
1138-
:on-reason (fn [{:keys [status id text external-id]}]
1133+
:on-reason (fn [{:keys [status id text external-id delta-reasoning?]}]
11391134
(assert-chat-not-stopped! chat-ctx)
11401135
(case status
11411136
:started (do (swap! reasonings* assoc-in [id :start-time] (System/currentTimeMillis))
11421137
(send-content! chat-ctx :assistant {:type :reasonStarted :id id}))
11431138
:thinking (do (swap! reasonings* update-in [id :text] str text)
11441139
(send-content! chat-ctx :assistant {:type :reasonText :id id :text text}))
1145-
:finished (let [total-time-ms (- (System/currentTimeMillis) (get-in @reasonings* [id :start-time]))]
1146-
(add-to-history! {:role "reason"
1147-
:content {:id id
1148-
:external-id external-id
1149-
:total-time-ms total-time-ms
1150-
:text (get-in @reasonings* [id :text])}})
1151-
(send-content! chat-ctx :assistant {:type :reasonFinished :total-time-ms total-time-ms :id id}))
1140+
:finished (when-let [start-time (get-in @reasonings* [id :start-time])]
1141+
(let [total-time-ms (- (System/currentTimeMillis) start-time)]
1142+
(add-to-history! {:role "reason"
1143+
:content {:id id
1144+
:external-id external-id
1145+
:delta-reasoning? delta-reasoning?
1146+
:total-time-ms total-time-ms
1147+
:text (get-in @reasonings* [id :text])}})
1148+
(send-content! chat-ctx :assistant {:type :reasonFinished :total-time-ms total-time-ms :id id})))
11521149
nil))
11531150
:on-error (fn [{:keys [message exception]}]
11541151
(send-content! chat-ctx :system {:type :text :text (or message (str "Error: " (ex-message exception)))})

src/eca/llm_api.clj

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -264,14 +264,16 @@
264264
:user-messages user-messages
265265
:on-error on-error-wrapper
266266
:config config})]
267-
(let [{:keys [error output-text reason-text tools-to-call call-tools-fn reason-id usage]} result]
267+
(let [{:keys [error output-text reason-text reasoning-content tools-to-call call-tools-fn reason-id usage]} result]
268268
(if error
269269
(on-error-wrapper error)
270270
(do
271271
(when reason-text
272272
(on-reason-wrapper {:status :started :id reason-id})
273273
(on-reason-wrapper {:status :thinking :id reason-id :text reason-text})
274-
(on-reason-wrapper {:status :finished :id reason-id}))
274+
(on-reason-wrapper {:status :finished
275+
:id reason-id
276+
:delta-reasoning? (some? reasoning-content)}))
275277
(on-message-received-wrapper {:type :text :text output-text})
276278
(some-> usage (on-usage-updated))
277279
(if-let [new-result (when (seq tools-to-call)

0 commit comments

Comments
 (0)