"""AI 调用日志""" from datetime import datetime from typing import Optional from sqlalchemy import BigInteger, DECIMAL, ForeignKey, Integer, Text, TIMESTAMP, VARCHAR, func from sqlalchemy.orm import Mapped, mapped_column from .base import BaseNoTenant class BaseLog(BaseNoTenant): """日志表基类""" __abstract__ = True tenant_id: Mapped[int] = mapped_column( BigInteger, nullable=False, default=1, index=True ) created_at: Mapped[datetime] = mapped_column( TIMESTAMP, nullable=False, server_default=func.now() ) class AICallLog(BaseLog): __tablename__ = "ai_call_logs" id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True) user_id: Mapped[Optional[int]] = mapped_column( BigInteger, ForeignKey("users.id"), nullable=True ) function_name: Mapped[str] = mapped_column(VARCHAR(255), nullable=False) prompt: Mapped[str] = mapped_column(Text, nullable=False) response: Mapped[Optional[str]] = mapped_column(Text, nullable=True) tokens_used: Mapped[Optional[int]] = mapped_column(Integer, nullable=True) cost: Mapped[Optional[float]] = mapped_column(DECIMAL(10, 6), nullable=True) status: Mapped[str] = mapped_column(VARCHAR(50), nullable=False) planned_tier: Mapped[Optional[str]] = mapped_column(VARCHAR(16), nullable=True, index=True) executed_tier: Mapped[Optional[str]] = mapped_column(VARCHAR(16), nullable=True, index=True) routing_decision: Mapped[Optional[str]] = mapped_column(VARCHAR(64), nullable=True, index=True) route_source: Mapped[Optional[str]] = mapped_column(VARCHAR(32), nullable=True) route_rule_name: Mapped[Optional[str]] = mapped_column(VARCHAR(255), nullable=True) routing_config_version: Mapped[Optional[str]] = mapped_column(VARCHAR(64), nullable=True) routing_config_updated_at: Mapped[Optional[str]] = mapped_column(VARCHAR(64), nullable=True)