"""AI session embedding storage for similar-session matching. Stores vector embeddings of AI session content (problem summary, resolution, domain) for cosine similarity search via pgvector. One embedding per session. """ import uuid from datetime import datetime, timezone from sqlalchemy import String, Text, DateTime, ForeignKey, Index from sqlalchemy.orm import Mapped, mapped_column from sqlalchemy.dialects.postgresql import UUID from app.core.database import Base try: from pgvector.sqlalchemy import Vector except ImportError: Vector = None class AISessionEmbedding(Base): __tablename__ = "ai_session_embeddings" __table_args__ = ( Index("ix_ai_session_embeddings_account_id", "account_id"), Index("ix_ai_session_embeddings_session_id", "session_id", unique=True), ) id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), primary_key=True, default=uuid.uuid4 ) session_id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), ForeignKey("ai_sessions.id", ondelete="CASCADE"), nullable=False, ) account_id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), ForeignKey("accounts.id", ondelete="CASCADE"), nullable=False, ) chunk_text: Mapped[str] = mapped_column(Text, nullable=False) embedding_model: Mapped[str] = mapped_column( String(50), nullable=False, default="voyage-3.5" ) # The embedding column is created via migration with vector(1024) type 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), )