feat: add PostgresModelUsageStore and ModelUsageTracker.seed()

- Add seed() method to ModelUsageTracker for bulk-loading persisted entries at startup
- Create PostgresModelUsageStore for persistence of model usage counters to Postgres
- Store only current cumulative snapshots (no historical time-series)
- Use standard CREATE TABLE IF NOT EXISTS idiom matching other Postgres stores
- Add comprehensive mocked unit tests for both components

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
wangwei
2026-07-23 14:18:22 +08:00
co-authored by Copilot
parent 4f6cc4812e
commit 5d132981ad
4 changed files with 290 additions and 0 deletions
+10
View File
@@ -97,6 +97,16 @@ class ModelUsageTracker:
except Exception as exc: # noqa: BLE001 - tracking must never break a real call
logger.warning("ModelUsageTracker.record failed for {}:{} - {}", provider, model, exc)
def seed(self, entries: dict[str, ModelUsageEntry]) -> None:
"""Bulk-load persisted entries (called once at startup, before any traffic).
Unlike record(), this replaces entries wholesale rather than
accumulating deltas — it exists to restore counters saved by a
previous process run, not to record a new call.
"""
with self._lock:
self._entries.update(entries)
def snapshot(self) -> dict[str, ModelUsageEntry]:
"""Return a shallow copy of all tracked entries, safe to mutate by the caller."""
with self._lock: