Skip to content

Commit 38b298d

Browse files
committed
Fix crash when hook returns additionalContext and user called /compact
1 parent b795bcd commit 38b298d

4 files changed

Lines changed: 37 additions & 11 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
- Improve error handling when MCP promtps fail on server side.
99
- Use rewrite-json to edit jsons without losing formatting.
1010
- Allow shell output redirections to `/tmp/` in plan/explorer agents instead of denying them.
11+
- Fix crash when hook returns additionalContext and message has string content (e.g. `/compact` command).
1112

1213
## 0.115.1
1314

src/eca/features/chat.clj

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,9 @@
408408
(and (seq additional-contexts) context-idx)
409409
(reduce (fn [msgs {:keys [hook-name content]}]
410410
(update-in msgs [context-idx :content]
411-
#(conj (vec %)
411+
#(conj (if (string? %)
412+
[{:type :text :text %}]
413+
(vec %))
412414
{:type :text
413415
:text (lifecycle/wrap-additional-context hook-name content)})))
414416
rewritten

src/eca/llm_providers/anthropic.clj

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -158,19 +158,20 @@
158158
(if (string? c)
159159
(string/trim c)
160160
(vec
161-
(keep #(case (name (:type %))
161+
(keep #(when-let [t (:type %)]
162+
(case (name t)
162163

163-
"text"
164-
(update % :text string/trim)
164+
"text"
165+
(update % :text string/trim)
165166

166-
"image"
167-
(when supports-image?
168-
{:type "image"
169-
:source {:data (:base64 %)
170-
:media_type (:media-type %)
171-
:type "base64"}})
167+
"image"
168+
(when supports-image?
169+
{:type "image"
170+
:source {:data (:base64 %)
171+
:media_type (:media-type %)
172+
:type "base64"}})
172173

173-
%)
174+
%))
174175
c))))))))
175176
past-messages))
176177

test/eca/llm_providers/anthropic_test.clj

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,28 @@
190190
:raw-content [{:type "web_search_result" :title "Test" :url "https://test.com"}]}}]
191191
true))))))
192192

193+
(deftest normalize-messages-nil-type-resilience-test
194+
(testing "content blocks with nil :type are filtered out"
195+
(is (match?
196+
[{:role "user"
197+
:content [{:type :text :text "hello"}]}]
198+
(#'llm-providers.anthropic/normalize-messages
199+
[{:role "user"
200+
:content [{:type :text :text "hello"}
201+
{:text "orphan without type"}
202+
nil]}]
203+
true))))
204+
(testing "message with keyword :type content works (additionalContext injection)"
205+
(is (match?
206+
[{:role "user"
207+
:content [{:type :text :text "compact the chat"}
208+
{:type :text :text "<additionalContext from=\"test\">\ntoday is monday\n</additionalContext>"}]}]
209+
(#'llm-providers.anthropic/normalize-messages
210+
[{:role "user"
211+
:content [{:type :text :text "compact the chat"}
212+
{:type :text :text "<additionalContext from=\"test\">\ntoday is monday\n</additionalContext>"}]}]
213+
true)))))
214+
193215
(deftest server-web-search-full-pipeline-test
194216
(testing "thinking + server web search + thinking + text normalizes to single assistant message"
195217
(let [input [{:role "user" :content "search for something"}

0 commit comments

Comments
 (0)