Copilot commented on code in PR #14028:
URL: https://github.com/apache/apisix/pull/14028#discussion_r4246090347


##########
apisix/plugins/ai-protocols/anthropic-messages.lua:
##########
@@ -29,10 +29,49 @@ local sse = require("apisix.plugins.ai-transport.sse")
 local table = table
 local type = type
 local ipairs = ipairs
+local pairs = pairs
 
 local _M = {}
 
 
+-- Anthropic reports cache tokens alongside input_tokens rather than inside it,
+-- so add them back to get a prompt total with the same meaning as OpenAI's
+-- prompt_tokens. Mirrors LiteLLM's AnthropicConfig.calculate_usage.
+local function to_usage(raw)
+    local cache_read = raw.cache_read_input_tokens or 0
+    local cache_creation = raw.cache_creation_input_tokens or 0
+    local prompt = (raw.input_tokens or 0) + cache_read + cache_creation
+    local completion = raw.output_tokens or 0
+    return {
+        prompt_tokens = prompt,
+        completion_tokens = completion,
+        total_tokens = prompt + completion,
+        cache_read_input_tokens = cache_read,
+        cache_creation_input_tokens = cache_creation,
+        reasoning_tokens = 0,
+    }
+end
+
+
+-- message_delta usage is cumulative but may omit fields reported at
+-- message_start (and some providers only report cache tokens there), so
+-- accumulate the raw fields across events before computing usage.
+local function accumulate_usage(state, raw)
+    if type(state) ~= "table" then
+        return raw
+    end
+    local acc = state.anthropic_usage
+    if not acc then
+        acc = {}
+        state.anthropic_usage = acc
+    end
+    for k, v in pairs(raw) do
+        acc[k] = v
+    end
+    return acc
+end

Review Comment:
   The function name/comment says “accumulate”, but the implementation is 
actually a field-wise merge/overwrite (last value wins) rather than numeric 
accumulation. To prevent future contributors from “fixing” it into a sum (which 
would break cumulative usage semantics), either rename it to something like 
`merge_usage_fields`/`coalesce_usage_fields` or adjust the comment to 
explicitly state it overwrites fields to preserve the latest cumulative values.



##########
apisix/plugins/ai-protocols/converters/anthropic-messages-to-openai-chat.lua:
##########
@@ -102,6 +102,33 @@ end
 
 
 -- SSE event helpers
+-- prompt_tokens_details keys that carry cache-write tokens, in LiteLLM's
+-- order, followed by the cache_creation_input_tokens shape some upstreams use.
+local CACHE_CREATION_DETAIL_KEYS = {
+    "cache_creation_tokens",
+    "cache_write_tokens",
+    "cache_creation_input_tokens",
+}
+
+
+local function cache_creation_tokens(usage)
+    local v = usage.cache_creation_input_tokens
+    if type(v) == "number" and v > 0 then
+        return v
+    end
+    local details = usage.prompt_tokens_details
+    if type(details) == "table" then
+        for _, key in ipairs(CACHE_CREATION_DETAIL_KEYS) do
+            v = details[key]
+            if type(v) == "number" and v > 0 then
+                return v
+            end
+        end
+    end
+    return 0
+end

Review Comment:
   `cache_creation_tokens` will raise an error if it’s ever called with a 
non-table `usage` (e.g., `nil`). Adding an early `if type(usage) ~= "table" 
then return 0 end` guard would make this helper safer and easier to reuse 
without relying on all call sites to pre-validate the shape.



##########
docs/zh/latest/plugins/prometheus.md:
##########
@@ -321,6 +321,8 @@ APISIX 在开始 LLM 上游尝试时递增该 gauge,并在请求的日志阶
 
 ### `apisix_llm_prompt_tokens` 的标签
 
+prompt token 包含从缓存读取和写入缓存的 token。对于 Anthropic Messages API,其值为 `input_tokens + 
cache_read_input_tokens + cache_creation_input_tokens`,与 OpenAI 的 
`prompt_tokens` 含义一致。

Review Comment:
   The Chinese docs line mixes singular/plural (“prompt token”) and English 
“token” wording in a way that’s inconsistent with surrounding terminology (“令牌” 
is used elsewhere in this doc). Consider revising to consistently use either 
“prompt tokens” or “提示令牌/提示 tokens”, and keep the cache read/write description 
consistent across zh docs.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to