Skip to content

Commit 9e797e0

Browse files
wpak-aicursoragent
andcommitted
fix: handle null usage token fields to prevent TypeError (#10)
dict.get(key, default) only uses the default when the key is absent; when the API emits a null value the result is None, causing `+= None` to raise TypeError. Replace `.get(key, 0)` with `.get(key) or 0` so null values are treated as 0. Fixes #10 Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent a8481b9 commit 9e797e0

2 files changed

Lines changed: 15 additions & 15 deletions

File tree

utils/jsonl_parser.py

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -180,21 +180,21 @@ def _process_assistant(entry: dict, messages: list, metadata: dict):
180180
metadata["api_errors"] += 1
181181

182182
usage = msg.get("usage", {})
183-
metadata["total_input_tokens"] += usage.get("input_tokens", 0)
184-
metadata["total_output_tokens"] += usage.get("output_tokens", 0)
185-
metadata["total_cache_read_tokens"] += usage.get("cache_read_input_tokens", 0)
186-
metadata["total_cache_creation_tokens"] += usage.get(
187-
"cache_creation_input_tokens", 0
183+
metadata["total_input_tokens"] += usage.get("input_tokens") or 0
184+
metadata["total_output_tokens"] += usage.get("output_tokens") or 0
185+
metadata["total_cache_read_tokens"] += usage.get("cache_read_input_tokens") or 0
186+
metadata["total_cache_creation_tokens"] += (
187+
usage.get("cache_creation_input_tokens") or 0
188188
)
189189

190190
# Extended cache metrics
191191
cache_creation = usage.get("cache_creation", {})
192192
if isinstance(cache_creation, dict):
193-
metadata["total_ephemeral_5m_tokens"] += cache_creation.get(
194-
"ephemeral_5m_input_tokens", 0
193+
metadata["total_ephemeral_5m_tokens"] += (
194+
cache_creation.get("ephemeral_5m_input_tokens") or 0
195195
)
196-
metadata["total_ephemeral_1h_tokens"] += cache_creation.get(
197-
"ephemeral_1h_input_tokens", 0
196+
metadata["total_ephemeral_1h_tokens"] += (
197+
cache_creation.get("ephemeral_1h_input_tokens") or 0
198198
)
199199

200200
# Service tier
@@ -249,10 +249,10 @@ def _process_assistant(entry: dict, messages: list, metadata: dict):
249249
"is_sidechain": entry.get("isSidechain", False),
250250
"is_api_error": entry.get("isApiErrorMessage", False),
251251
"usage": {
252-
"input_tokens": usage.get("input_tokens", 0),
253-
"output_tokens": usage.get("output_tokens", 0),
254-
"cache_read": usage.get("cache_read_input_tokens", 0),
255-
"cache_creation": usage.get("cache_creation_input_tokens", 0),
252+
"input_tokens": usage.get("input_tokens") or 0,
253+
"output_tokens": usage.get("output_tokens") or 0,
254+
"cache_read": usage.get("cache_read_input_tokens") or 0,
255+
"cache_creation": usage.get("cache_creation_input_tokens") or 0,
256256
"service_tier": usage.get("service_tier"),
257257
},
258258
})

utils/session_stats.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,8 @@ def _estimate_cost(messages: list, meta: dict) -> float | None:
119119
continue
120120
model = msg.get("model", "")
121121
usage = msg.get("usage", {})
122-
inp = usage.get("input_tokens", 0)
123-
out = usage.get("output_tokens", 0)
122+
inp = usage.get("input_tokens") or 0
123+
out = usage.get("output_tokens") or 0
124124
if not (inp or out):
125125
continue
126126

0 commit comments

Comments
 (0)