Skip to content

Commit f104717

Browse files
committed
Improve usage metrics for anthropic
1 parent 7224e14 commit f104717

File tree

5 files changed

+53
-22
lines changed

5 files changed

+53
-22
lines changed

resources/eca_prompt.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ You are pair programming with a USER to solve their coding task. Each time the U
66

77
<communication>
88
The chat is markdown mode.
9-
When using markdown in assistant messages, use backticks to format file, directory, function, and class names. Use \( and \) for inline math, \[ and \] for block math.
9+
When using markdown in assistant messages, use backticks to format file, directory, function, and class names.
1010
Pay attention to the langauge name after the code block backticks start, use the full language name like 'javascript' instead of 'js'.
1111
</communication>
1212

src/eca/db.clj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,23 @@
2929
:max-output-tokens 8196
3030
:reason-tokens 2048
3131
:input-token-cost (/ 3.0 one-million)
32+
:input-cache-creation-token-cost (/ 3.75 one-million)
33+
:input-cache-read-token-cost (/ 0.3 one-million)
3234
:output-token-cost (/ 15.0 one-million)}
3335
"claude-opus-4-0" {:tools true
3436
:web-search true
3537
:max-output-tokens 8196
3638
:reason-tokens 2048
3739
:input-token-cost (/ 15.0 one-million)
40+
:input-cache-creation-token-cost (/ 18.75 one-million)
41+
:input-cache-read-token-cost (/ 1.5 one-million)
3842
:output-token-cost (/ 75.0 one-million)}
3943
"claude-3-5-haiku-latest" {:tools true
4044
:web-search true
4145
:max-output-tokens 4096
4246
:input-token-cost (/ 0.8 one-million)
47+
:input-cache-creation-token-cost (/ 1.0 one-million)
48+
:input-cache-read-token-cost (/ 0.08 one-million)
4349
:output-token-cost (/ 4.0 one-million)}} ;; + ollama local models + custom provider models
4450
:mcp-clients {}})
4551

src/eca/features/chat.clj

Lines changed: 43 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -60,15 +60,50 @@
6060
(defn ^:private tool-name->origin [name all-tools]
6161
(:origin (first (filter #(= name (:name %)) all-tools))))
6262

63-
(defn ^:private tokens->cost [input-tokens output-tokens model db]
63+
(defn ^:private tokens->cost [input-tokens input-cache-creation-tokens input-cache-read-tokens output-tokens model db]
6464
(let [normalized-model (if (string/includes? model "/")
6565
(last (string/split model #"/"))
6666
model)
67-
{:keys [input-token-cost output-token-cost]} (get-in db [:models normalized-model])]
67+
{:keys [input-token-cost output-token-cost
68+
input-cache-creation-token-cost input-cache-read-token-cost]} (get-in db [:models normalized-model])
69+
input-cost (* input-tokens input-token-cost)
70+
input-cost (if input-cache-creation-tokens
71+
(+ input-cost (* input-cache-creation-tokens input-cache-creation-token-cost))
72+
input-cost)
73+
input-cost (if input-cache-read-tokens
74+
(+ input-cost (* input-cache-read-tokens input-cache-read-token-cost))
75+
input-cost)]
6876
(when (and input-token-cost output-token-cost)
69-
(format "%.2f" (+ (* input-tokens input-token-cost)
77+
(format "%.2f" (+ input-cost
7078
(* output-tokens output-token-cost))))))
7179

80+
(defn ^:private usage-msg->usage
81+
[{:keys [input-tokens output-tokens
82+
input-cache-creation-tokens input-cache-read-tokens]}
83+
model
84+
{:keys [chat-id db*] :as chat-ctx}]
85+
(when (and output-tokens input-tokens)
86+
(swap! db* update-in [:chats chat-id :total-input-tokens] (fnil + 0) input-tokens)
87+
(swap! db* update-in [:chats chat-id :total-output-tokens] (fnil + 0) output-tokens)
88+
(when input-cache-creation-tokens
89+
(swap! db* update-in [:chats chat-id :total-input-cache-creation-tokens] (fnil + 0) input-cache-creation-tokens))
90+
(when input-cache-read-tokens
91+
(swap! db* update-in [:chats chat-id :total-input-cache-read-tokens] (fnil + 0) input-cache-read-tokens))
92+
(let [db @db*
93+
total-input-tokens (get-in db [:chats chat-id :total-input-tokens] 0)
94+
total-input-cache-creation-tokens (get-in db [:chats chat-id :total-input-cache-creation-tokens] nil)
95+
total-input-cache-read-tokens (get-in db [:chats chat-id :total-input-cache-read-tokens] nil)
96+
message-input-cache-tokens (or input-cache-creation-tokens 0)
97+
total-input-cache-tokens (or total-input-cache-creation-tokens 0)
98+
total-output-tokens (get-in db [:chats chat-id :total-output-tokens] 0)]
99+
(send-content! chat-ctx :system
100+
(assoc-some {:type :usage
101+
:message-output-tokens output-tokens
102+
:message-input-tokens (+ input-tokens message-input-cache-tokens)
103+
:session-tokens (+ total-input-tokens total-input-cache-tokens total-output-tokens)}
104+
:message-cost (tokens->cost input-tokens input-cache-creation-tokens input-cache-read-tokens output-tokens model db)
105+
:session-cost (tokens->cost total-input-tokens total-input-cache-creation-tokens total-input-cache-read-tokens total-output-tokens model db))))))
106+
72107
(defn prompt
73108
[{:keys [message model behavior contexts chat-id request-id]}
74109
db*
@@ -104,10 +139,7 @@
104139
received-thinking* (atom "")
105140
tool-call-args-by-id* (atom {})
106141
add-to-history! (fn [msg]
107-
(swap! db* update-in [:chats chat-id :messages] (fnil conj []) msg))
108-
sum-sesison-tokens! (fn [input-tokens output-tokens]
109-
(swap! db* update-in [:chats chat-id :total-input-tokens] (fnil + 0) input-tokens)
110-
(swap! db* update-in [:chats chat-id :total-output-tokens] (fnil + 0) output-tokens))]
142+
(swap! db* update-in [:chats chat-id :messages] (fnil conj []) msg))]
111143
(send-content! chat-ctx :system {:type :progress
112144
:state :running
113145
:text "Waiting model"})
@@ -143,19 +175,10 @@
143175
(finish-chat-prompt! :idle chat-ctx))
144176
:finish (do
145177
(add-to-history! {:role "assistant" :content @received-msgs*})
146-
(when-let [{:keys [output-tokens input-tokens]} (:usage msg)]
147-
(when (and output-tokens input-tokens)
148-
(sum-sesison-tokens! input-tokens output-tokens)
149-
(let [db @db*
150-
total-input-tokens (get-in db [:chats chat-id :total-input-tokens] 0)
151-
total-output-tokens (get-in db [:chats chat-id :total-output-tokens] 0)]
152-
(send-content! chat-ctx :system
153-
(assoc-some {:type :usage
154-
:message-output-tokens output-tokens
155-
:message-input-tokens input-tokens
156-
:session-tokens (+ total-input-tokens total-output-tokens)}
157-
:message-cost (tokens->cost input-tokens output-tokens chosen-model db)
158-
:session-cost (tokens->cost total-input-tokens total-output-tokens chosen-model db))))))
178+
(when-let [usage (usage-msg->usage (:usage msg) chosen-model chat-ctx)]
179+
(send-content! chat-ctx :system
180+
(merge usage
181+
{:type :usage})))
159182
(finish-chat-prompt! :idle chat-ctx))))
160183
:on-prepare-tool-call (fn [{:keys [id name arguments-text]}]
161184
(assert-chat-not-stopped! chat-ctx)

src/eca/llm_providers/anthropic.clj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,8 @@
160160
(reset! content-block* {})
161161
(on-message-received {:type :finish
162162
:usage {:input-tokens (-> data :usage :input_tokens)
163+
:input-cache-creation-tokens (-> data :usage :cache_creation_input_tokens)
164+
:input-cache-read-tokens (-> data :usage :cache_read_input_tokens)
163165
:output-tokens (-> data :usage :output_tokens)}
164166
:finish-reason (-> data :delta :stop_reason)}))
165167
"max_tokens" (on-message-received {:type :limit-reached

src/eca/llm_providers/openai.clj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@
6565
web-search (conj {:type "web_search_preview"}))
6666
body {:model model
6767
:input input
68-
:user (str (System/getProperty "user.name") "@ECA")
68+
:prompt_cache_key (str (System/getProperty "user.name") "@ECA")
6969
:instructions instructions
7070
:temperature temperature
7171
:tools tools

0 commit comments

Comments
 (0)