amazon-transcreation/backend/app/llm/token_tracker.py
DJP 98fa16bfc3 feat: complete Phase 1-2 scaffold — backend, frontend, pipeline skeleton
Full-stack Amazon AI Transcreation Platform with:
- FastAPI backend (async, PostgreSQL, Redis, Celery) with 11 DB tables
- JWT auth (SSO-ready abstract provider pattern)
- 6-agent pipeline orchestrator with deterministic modules
- Next.js 14 frontend with Amazon branding (Ember fonts, orange/dark theme)
- Job wizard, monitoring HUD, output review, admin screens
- 154 TM/reference files imported, 12 locales configured
- Docker Compose for all services

Agents 2-5 (TM retrieval, ranker, transcreator, compliance) are stubs
pending Phase 3 LLM integration.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-10 12:31:43 -04:00

101 lines
3 KiB
Python

"""Token usage tracking - records LLM usage to the database."""
import logging
from typing import Any
from uuid import UUID
from sqlalchemy.ext.asyncio import AsyncSession
from app.models.audit import TokenUsageLog
logger = logging.getLogger(__name__)
async def record_token_usage(
db: AsyncSession,
instance_id: UUID,
agent_name: str,
usage: dict[str, Any],
) -> TokenUsageLog:
"""Record token usage from an LLM call to the database.
Args:
db: Async database session.
instance_id: The locale instance ID this usage is for.
agent_name: Name of the agent that made the call.
usage: Usage dict from LLMClient with keys:
input_tokens, output_tokens, total_tokens,
estimated_cost_usd, model.
Returns:
The created TokenUsageLog record.
"""
log_entry = TokenUsageLog(
instance_id=instance_id,
agent_name=agent_name,
model=usage.get("model", "unknown"),
input_tokens=usage.get("input_tokens", 0),
output_tokens=usage.get("output_tokens", 0),
total_tokens=usage.get("total_tokens", 0),
estimated_cost_usd=usage.get("estimated_cost_usd", 0.0),
)
db.add(log_entry)
await db.flush()
logger.info(
f"Token usage recorded: agent={agent_name}, "
f"tokens={usage.get('total_tokens', 0)}, "
f"cost=${usage.get('estimated_cost_usd', 0.0):.6f}"
)
return log_entry
async def get_total_usage_for_instance(
db: AsyncSession,
instance_id: UUID,
) -> dict[str, Any]:
"""Get aggregated token usage for a locale instance.
Args:
db: Async database session.
instance_id: The locale instance ID.
Returns:
Dict with total_tokens, total_cost, by_agent breakdown.
"""
from sqlalchemy import func, select
result = await db.execute(
select(
func.sum(TokenUsageLog.input_tokens).label("total_input"),
func.sum(TokenUsageLog.output_tokens).label("total_output"),
func.sum(TokenUsageLog.total_tokens).label("total_tokens"),
func.sum(TokenUsageLog.estimated_cost_usd).label("total_cost"),
).where(TokenUsageLog.instance_id == instance_id)
)
row = result.one()
# By-agent breakdown
agent_result = await db.execute(
select(
TokenUsageLog.agent_name,
func.sum(TokenUsageLog.total_tokens).label("tokens"),
func.sum(TokenUsageLog.estimated_cost_usd).label("cost"),
)
.where(TokenUsageLog.instance_id == instance_id)
.group_by(TokenUsageLog.agent_name)
)
by_agent = {
agent_name: {"tokens": tokens, "cost": float(cost)}
for agent_name, tokens, cost in agent_result.all()
}
return {
"total_input_tokens": row.total_input or 0,
"total_output_tokens": row.total_output or 0,
"total_tokens": row.total_tokens or 0,
"total_cost_usd": float(row.total_cost or 0.0),
"by_agent": by_agent,
}