Dual-write cost tracker records to SQLite

Each LLM/TTS call now writes to both in-memory records and SQLite
via cost_db. Session totals updated on save(). All DB writes wrapped
in try/except to never break live shows.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-02 23:47:41 -06:00
co-authored by Claude Opus 4.6
parent 283e4a2f3c
commit 73d555b269
+28
View File
@@ -3,9 +3,12 @@
import json import json
import time import time
from dataclasses import dataclass, field, asdict from dataclasses import dataclass, field, asdict
from datetime import datetime
from pathlib import Path from pathlib import Path
from typing import Optional from typing import Optional
from backend.services import cost_db
@dataclass @dataclass
class LLMCallRecord: class LLMCallRecord:
@@ -95,6 +98,7 @@ def _calc_tts_cost(provider: str, char_count: int) -> float:
class CostTracker: class CostTracker:
def __init__(self): def __init__(self):
self._session_id = f"session-{datetime.now().strftime('%Y-%m-%d_%H%M%S')}"
self.llm_records: list[LLMCallRecord] = [] self.llm_records: list[LLMCallRecord] = []
self.tts_records: list[TTSCallRecord] = [] self.tts_records: list[TTSCallRecord] = []
# Running totals for fast get_live_summary() # Running totals for fast get_live_summary()
@@ -137,6 +141,16 @@ class CostTracker:
) )
self.llm_records.append(record) self.llm_records.append(record)
try:
cost_db.ensure_session(self._session_id)
cost_db.record_llm_call(
self._session_id, record.timestamp, record.category, record.model,
record.prompt_tokens, record.completion_tokens, record.cost_usd,
record.caller_name, record.latency_ms,
)
except Exception:
pass # don't break show over analytics
# Update running totals # Update running totals
self._llm_cost += cost self._llm_cost += cost
self._llm_calls += 1 self._llm_calls += 1
@@ -165,6 +179,15 @@ class CostTracker:
cost_usd=cost, cost_usd=cost,
) )
self.tts_records.append(record) self.tts_records.append(record)
try:
cost_db.record_tts_call(
self._session_id, record.timestamp, record.provider, record.voice,
record.char_count, record.cost_usd,
)
except Exception:
pass
self._tts_cost += cost self._tts_cost += cost
def get_live_summary(self) -> dict: def get_live_summary(self) -> dict:
@@ -369,6 +392,11 @@ class CostTracker:
json.dump(report, f, indent=2) json.dump(report, f, indent=2)
print(f"[Costs] Report saved to {filepath}") print(f"[Costs] Report saved to {filepath}")
try:
cost_db.update_session_totals(self._session_id)
except Exception:
pass
def reset(self): def reset(self):
self.llm_records.clear() self.llm_records.clear()
self.tts_records.clear() self.tts_records.clear()