Skip to content

Commit c45f6ff

Browse files
authored
fix(langchain): skip priority-tier keys when subtracting token detail counts (#1549)
1 parent 72aa156 commit c45f6ff

File tree

2 files changed

+42
-0
lines changed

2 files changed

+42
-0
lines changed

langfuse/langchain/CallbackHandler.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1189,6 +1189,10 @@ def _parse_usage_model(usage: Union[pydantic.BaseModel, dict]) -> Any:
11891189
for key, value in input_token_details.items():
11901190
usage_model[f"input_{key}"] = value
11911191

1192+
# Skip priority-tier keys as they are not exclusive sub-categories
1193+
if key == "priority" or key.startswith("priority_"):
1194+
continue
1195+
11921196
if "input" in usage_model:
11931197
usage_model["input"] = max(0, usage_model["input"] - value)
11941198

@@ -1198,6 +1202,10 @@ def _parse_usage_model(usage: Union[pydantic.BaseModel, dict]) -> Any:
11981202
for key, value in output_token_details.items():
11991203
usage_model[f"output_{key}"] = value
12001204

1205+
# Skip priority-tier keys as they are not exclusive sub-categories
1206+
if key == "priority" or key.startswith("priority_"):
1207+
continue
1208+
12011209
if "output" in usage_model:
12021210
usage_model["output"] = max(0, usage_model["output"] - value)
12031211

tests/test_parse_usage_model.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
from langfuse.langchain.CallbackHandler import _parse_usage_model
2+
3+
4+
def test_standard_tier_input_token_details():
5+
"""Standard tier: audio and cache_read are subtracted from input."""
6+
usage = {
7+
"input_tokens": 13,
8+
"output_tokens": 1,
9+
"total_tokens": 14,
10+
"input_token_details": {"audio": 0, "cache_read": 3},
11+
"output_token_details": {"audio": 0},
12+
}
13+
result = _parse_usage_model(usage)
14+
assert result["input"] == 10 # 13 - 0 (audio) - 3 (cache_read)
15+
assert result["output"] == 1 # 1 - 0 (audio)
16+
assert result["total"] == 14
17+
18+
19+
def test_priority_tier_not_subtracted():
20+
"""Priority tier: 'priority' and 'priority_*' keys must NOT be subtracted."""
21+
usage = {
22+
"input_tokens": 13,
23+
"output_tokens": 1,
24+
"total_tokens": 14,
25+
"input_token_details": {"audio": 0, "priority_cache_read": 0, "priority": 13},
26+
"output_token_details": {"audio": 0, "priority_reasoning": 0, "priority": 1},
27+
}
28+
result = _parse_usage_model(usage)
29+
assert result["input"] == 13 # priority keys not subtracted
30+
assert result["output"] == 1
31+
assert result["total"] == 14
32+
# Priority keys are still stored with prefixed names
33+
assert result["input_priority"] == 13
34+
assert result["output_priority"] == 1

0 commit comments

Comments
 (0)