Skip to content

Commit 1875ff6

Browse files
committed
Truncate by max size
1 parent f1622e1 commit 1875ff6

3 files changed

Lines changed: 38 additions & 6 deletions

File tree

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+
- Fix `outputTruncation.sizeKb` not being honored
6+
57
## 0.110.1
68

79
- Fix MCP Streamable HTTP servers stuck at starting due to Java SDK DummyEvent bug on 202 notification responses, and spurious OAuth detection from proxies returning 401 without www-authenticate on HEAD requests.

src/eca/features/tools/util.clj

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -148,13 +148,29 @@
148148
(or (> line-count max-lines)
149149
(> size-kb max-size-kb))))
150150

151-
(defn ^:private truncate-text-to-lines
151+
(defn ^:private truncate-text-lines
152152
"Truncates text to the given number of lines."
153153
[^String text max-lines]
154-
(let [lines (string/split-lines text)]
155-
(if (<= (count lines) max-lines)
156-
text
157-
(string/join "\n" (take max-lines lines)))))
154+
(->> text
155+
string/split-lines
156+
(take max-lines)
157+
(string/join "\n")))
158+
159+
(defn ^:private truncate-text-size
160+
"Truncates text to the given size in kb."
161+
[^String text max-size-kb]
162+
(->> text
163+
(#(.getBytes % "UTF-8"))
164+
(take (* max-size-kb 1024))
165+
(byte-array)
166+
(#(String. % "UTF-8"))))
167+
168+
(defn ^:private truncate-text
169+
"Truncates text to the given number of lines and size"
170+
[^String text max-lines max-size-kb]
171+
(-> text
172+
(truncate-text-lines max-lines)
173+
(truncate-text-size max-size-kb)))
158174

159175
(defn maybe-truncate-output
160176
"Checks if a tool call result exceeds configured output truncation limits.
@@ -171,7 +187,7 @@
171187
(let [full-text (str (contents->text (:contents result)))]
172188
(if (exceeds-truncation-limits? full-text max-lines max-size-kb)
173189
(let [saved-path (cache/save-tool-call-output! tool-call-id full-text)
174-
truncated (truncate-text-to-lines full-text max-lines)
190+
truncated (truncate-text full-text max-lines max-size-kb)
175191
notice (str "\n\n[OUTPUT TRUNCATED] The tool call succeeded but the output was truncated. "
176192
"Full output saved to: " saved-path "\n"
177193
"Use `eca__grep` or `eca__read_file` with offset/limit to view specific sections. Do not full read the file.")]

test/eca/features/tools/util_test.clj

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,3 +99,17 @@
9999
truncated (tools.util/maybe-truncate-output result config test-tool-call-id)]
100100
(is (= 1 (count (:contents truncated))))
101101
(is (match? {:type :text :text string?} (first (:contents truncated)))))))
102+
103+
(deftest maybe-truncate-output-truncates-very-long-lines-test
104+
(testing "truncates output by size when lines are very long"
105+
(let [text (apply str (repeat 20480 "x"))
106+
result (make-result text)
107+
max-size-kb 10
108+
config (config-with-truncation 5 max-size-kb)
109+
truncated (tools.util/maybe-truncate-output result config test-tool-call-id)
110+
output-text (-> truncated :contents first :text)
111+
output-size-kb (/ (alength (.getBytes output-text "UTF-8")) 1024.0)]
112+
(is (string/includes? output-text "[OUTPUT TRUNCATED]"))
113+
(is (< (- output-size-kb max-size-kb) 1)
114+
(str "Expected output to be truncated to be " max-size-kb "KB, but got " output-size-kb "KB"))
115+
(is (false? (:error truncated))))))

0 commit comments

Comments
 (0)