"""Copilot conversation model for in-session AI assistant. Tracks conversation state during flow navigation with contextual AI help. """ import uuid from datetime import datetime, timezone from typing import Optional, Any from sqlalchemy import String, DateTime, ForeignKey, Integer from sqlalchemy.orm import Mapped, mapped_column from sqlalchemy.dialects.postgresql import UUID, JSONB from app.core.database import Base class CopilotConversation(Base): __tablename__ = "copilot_conversations" id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), primary_key=True, default=uuid.uuid4 ) user_id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), ForeignKey("users.id", ondelete="CASCADE"), nullable=False, index=True, ) account_id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), ForeignKey("accounts.id", ondelete="CASCADE"), nullable=False, index=True, ) session_id: Mapped[Optional[uuid.UUID]] = mapped_column( UUID(as_uuid=True), ForeignKey("sessions.id", ondelete="SET NULL"), nullable=True, ) tree_id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), ForeignKey("trees.id", ondelete="CASCADE"), nullable=False, ) messages: Mapped[list[dict[str, Any]]] = mapped_column( JSONB, nullable=False, default=list ) current_node_id: Mapped[Optional[str]] = mapped_column( String(100), nullable=True ) message_count: Mapped[int] = mapped_column( Integer, nullable=False, default=0 ) total_input_tokens: Mapped[int] = mapped_column( Integer, nullable=False, default=0 ) total_output_tokens: Mapped[int] = mapped_column( Integer, nullable=False, default=0 ) created_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), default=lambda: datetime.now(timezone.utc) ) updated_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc), ) expires_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), nullable=False )