Skip to content

Commit 3c70c53

Browse files
committed
Fix promtps that send assistant messages not working for anthropic.
1 parent 644b52c commit 3c70c53

3 files changed

Lines changed: 41 additions & 2 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
## Unreleased
44

55
- Support http-streamable http servers (non auth support for now)
6+
- Fix promtps that send assistant messages not working for anthropic.
67

78
## 0.51.3
89

docs/configuration.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ For MCP servers configuration, use the `mcpServers` config, examples:
6868
"command": "npx",
6969
"args": ["-y", "@modelcontextprotocol/server-memory"],
7070
// optional
71-
"env": {"FOO" "bar"}
71+
"env": {"FOO" "bar"}
7272
}
7373
}
7474
}

src/eca/llm_providers/anthropic.clj

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,44 @@
1717

1818
(def ^:private messages-path "/v1/messages")
1919

20+
(defn ^:private any-assistant-message-without-thinking-previously?
21+
"If there is a assistant message, which has no previous any role message with thinking content, returns true."
22+
[messages]
23+
(loop [msgs messages
24+
seen-thinking? false]
25+
(if-let [msg (first msgs)]
26+
(let [is-assistant? (= "assistant" (:role msg))
27+
has-thinking? (and (vector? (:content msg))
28+
(some #(= "thinking" (:type %)) (:content msg)))]
29+
(cond
30+
;; If this is an assistant message and we haven't seen thinking before, return true
31+
(and is-assistant? (not seen-thinking?) (not has-thinking?))
32+
true
33+
34+
;; If this message has thinking content, mark it as seen
35+
has-thinking?
36+
(recur (rest msgs) true)
37+
38+
;; Otherwise continue
39+
:else
40+
(recur (rest msgs) seen-thinking?)))
41+
;; No assistant message found without previous thinking
42+
false)))
43+
44+
(defn ^:private fix-non-thinking-assistant-messages [messages]
45+
(if (any-assistant-message-without-thinking-previously? messages)
46+
;; Anthropic doesn't like assistant messages without thinking blocks,
47+
;; we force to be a user one when this happens
48+
;; (MCP prompts that return assistant messages as initial step like clojureMCP)
49+
;; https://clojurians.slack.com/archives/C093426FPUG/p1757622242502969
50+
(mapv (fn [{:keys [role content] :as msg}]
51+
(if (= "assistant" role)
52+
{:role "user"
53+
:content content}
54+
msg))
55+
messages)
56+
messages))
57+
2058
(defn ^:private ->tools [tools web-search]
2159
(cond->
2260
(mapv (fn [tool]
@@ -105,7 +143,7 @@
105143
tools web-search extra-payload]}
106144
{:keys [on-message-received on-error on-reason on-prepare-tool-call on-tools-called on-usage-updated]}]
107145
(let [messages (concat (normalize-messages past-messages)
108-
(normalize-messages user-messages))
146+
(normalize-messages (fix-non-thinking-assistant-messages user-messages)))
109147
body (merge (assoc-some
110148
{:model model
111149
:messages (add-cache-to-last-message messages)

0 commit comments

Comments
 (0)