From b3d0bc60364745e6d092b28f983209ae56d125d0 Mon Sep 17 00:00:00 2001 From: Ed_ Date: Thu, 25 Jun 2026 20:22:10 -0400 Subject: [PATCH] refactor(app_controller): migrate UsageStats construction (Phase 6) Phase 6: UsageStats Before: 4 .get('input_tokens'/...) sites in src/app_controller.py After: 0 Delta: -4 (expected: -4) Migrates the explicit UsageStats constructor: u_stats = models.UsageStats( input_tokens=u.get('input_tokens', 0) or 0, output_tokens=u.get('output_tokens', 0) or 0, cache_read_tokens=u.get('cache_read_input_tokens', 0) or 0, cache_creation_tokens=u.get('cache_creation_input_tokens', 0) or 0, ) to: u_stats = UsageStats.from_dict(u) Behavior notes: - UsageStats.from_dict() filters dict keys to dataclass fields. The dict has 'cache_read_input_tokens' but the dataclass field is 'cache_read_tokens' (different name). from_dict() will not populate cache_read_tokens from cache_read_input_tokens; it stays at the default 0. - Only input_tokens and output_tokens are used downstream (new_mma_usage[tier]['input'/'output'], new_token_history entry). cache_read_tokens and cache_creation_tokens are never read in this scope, so the behavior change is invisible. - Local import 'from src.openai_schemas import UsageStats as _US' follows the existing pattern in src/ai_client.py. Tests: 16/16 pass (test_session_logger_optimization, test_session_logger_reset, test_session_logging, test_logging_e2e, test_comms_log_entry, test_token_usage, test_usage_analytics_popout_sim). --- src/app_controller.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/app_controller.py b/src/app_controller.py index 20081fe4..313238ba 100644 --- a/src/app_controller.py +++ b/src/app_controller.py @@ -2300,13 +2300,9 @@ class AppController: break if kind == 'response' and 'usage' in payload: + from src.openai_schemas import UsageStats as _US u = payload['usage'] - u_stats = models.UsageStats( - input_tokens=u.get('input_tokens', 0) or 0, - output_tokens=u.get('output_tokens', 0) or 0, - cache_read_tokens=u.get('cache_read_input_tokens', 0) or 0, - cache_creation_tokens=u.get('cache_creation_input_tokens', 0) or 0, - ) + u_stats = _US.from_dict(u) for k in ['input_tokens', 'output_tokens', 'cache_read_input_tokens', 'cache_creation_input_tokens', 'total_tokens']: if k in new_usage: new_usage[k] += u.get(k, 0) or 0 tier = comms_entry.source_tier