33 lines
1.6 KiB
Python
33 lines
1.6 KiB
Python
"""Verbrauch je Modellaufruf (→ Konzept 8.1, 13): Tokens und Kosten, unabhängig von Chats.
|
|
|
|
Einträge bleiben erhalten, wenn Chats oder Workspaces gelöscht werden; die Kosten
|
|
werden mit dem Preis zum Zeitpunkt des Aufrufs festgeschrieben.
|
|
"""
|
|
|
|
import uuid
|
|
from datetime import datetime
|
|
from decimal import Decimal
|
|
|
|
from sqlalchemy import BigInteger, ForeignKey, Identity, Integer, Numeric, String, Uuid
|
|
from sqlalchemy.orm import Mapped, mapped_column
|
|
|
|
from app.core.database import Base, now
|
|
|
|
|
|
class UsageRecord(Base):
|
|
__tablename__ = "usage_records"
|
|
|
|
id: Mapped[int] = mapped_column(BigInteger, Identity(), primary_key=True)
|
|
time: Mapped[datetime] = mapped_column(default=now, index=True)
|
|
# Kein Fremdschlüssel: der Run kann mit dem Chat gelöscht werden, der Verbrauch bleibt
|
|
run_id: Mapped[uuid.UUID | None] = mapped_column(Uuid, index=True)
|
|
team_id: Mapped[int | None] = mapped_column(ForeignKey("teams.id", ondelete="SET NULL"), index=True)
|
|
workspace_id: Mapped[int | None] = mapped_column(ForeignKey("workspaces.id", ondelete="SET NULL"), index=True)
|
|
user_id: Mapped[int | None] = mapped_column(ForeignKey("users.id", ondelete="SET NULL"))
|
|
model: Mapped[str] = mapped_column(String(200))
|
|
input_tokens: Mapped[int] = mapped_column(Integer, default=0)
|
|
cached_tokens: Mapped[int] = mapped_column(Integer, default=0)
|
|
output_tokens: Mapped[int] = mapped_column(Integer, default=0)
|
|
reasoning_tokens: Mapped[int] = mapped_column(Integer, default=0)
|
|
# Leer, wenn für das Modell kein Preis hinterlegt war
|
|
cost: Mapped[Decimal | None] = mapped_column(Numeric(14, 6))
|