questrag-backend / app /models /backup_conversation.py
eeshanyaj's picture
minor change
e699f51
raw
history blame
9.97 kB
# """
# Conversation Models for MongoDB
# Handles conversation persistence with:
# - Auto-generated titles from first message
# - Message metadata (policy actions, retrieval stats)
# - Archive/unarchive support
# - Search indexing ready
# """
# from datetime import datetime
# from typing import List, Optional, Dict, Any
# from pydantic import BaseModel, Field
# from bson import ObjectId
# # ============================================================================
# # CUSTOM TYPES
# # ============================================================================
# class PyObjectId(ObjectId):
# """Custom ObjectId type compatible with Pydantic v2"""
# @classmethod
# def __get_validators__(cls):
# yield cls.validate
# @classmethod
# def validate(cls, v):
# if not ObjectId.is_valid(v):
# raise ValueError("Invalid ObjectId")
# return ObjectId(v)
# @classmethod
# def __get_pydantic_json_schema__(cls, core_schema, handler):
# schema = handler(core_schema)
# schema.update(type="string")
# return schema
# # ============================================================================
# # MESSAGE MODEL
# # ============================================================================
# class Message(BaseModel):
# """
# Single message in a conversation.
# Contains:
# - User/assistant content
# - Metadata from RAG pipeline (policy action, retrieval stats)
# - Timestamp
# """
# role: str = Field(..., description="Role: 'user' or 'assistant'")
# content: str = Field(..., description="Message content")
# timestamp: datetime = Field(default_factory=datetime.utcnow)
# # Metadata from RAG pipeline (only for assistant messages)
# metadata: Optional[Dict[str, Any]] = Field(
# default=None,
# description="RAG metadata: policy_action, confidence, docs_retrieved, etc."
# )
# class Config:
# json_encoders = {
# datetime: lambda v: v.isoformat()
# }
# schema_extra = {
# "example": {
# "role": "user",
# "content": "What is my account balance?",
# "timestamp": "2024-01-15T10:30:00",
# "metadata": None
# }
# }
# # ============================================================================
# # CONVERSATION MODEL (MongoDB Document)
# # ============================================================================
# class Conversation(BaseModel):
# """
# Full conversation document stored in MongoDB.
# Features:
# - Auto-generated title from first user message
# - Message history with metadata
# - Archive/active status
# - User association
# - Search-ready structure
# """
# id: Optional[PyObjectId] = Field(alias="_id", default=None)
# user_id: str = Field(..., description="User ID who owns this conversation")
# title: str = Field(..., description="Conversation title (auto-generated or custom)")
# messages: List[Message] = Field(
# default_factory=list,
# description="List of messages in chronological order"
# )
# # Status flags
# is_archived: bool = Field(default=False, description="Is conversation archived?")
# is_deleted: bool = Field(default=False, description="Soft delete flag")
# # Timestamps
# created_at: datetime = Field(default_factory=datetime.utcnow)
# updated_at: datetime = Field(default_factory=datetime.utcnow)
# last_message_at: Optional[datetime] = Field(default=None)
# # Metadata
# message_count: int = Field(default=0, description="Total messages (excluding deleted)")
# class Config:
# model_config = {
# "populate_by_name": True,
# "arbitrary_types_allowed": True,
# "json_encoders": {
# ObjectId: str,
# datetime: lambda v: v.isoformat(),
# },
# }
# schema_extra = {
# "example": {
# "user_id": "user_123",
# "title": "Account Balance Inquiry",
# "messages": [
# {
# "role": "user",
# "content": "What is my account balance?",
# "timestamp": "2024-01-15T10:30:00"
# },
# {
# "role": "assistant",
# "content": "Your current account balance is...",
# "timestamp": "2024-01-15T10:30:05",
# "metadata": {
# "policy_action": "FETCH",
# "confidence": 0.95,
# "documents_retrieved": 3
# }
# }
# ],
# "is_archived": False,
# "created_at": "2024-01-15T10:30:00",
# "updated_at": "2024-01-15T10:30:05",
# "message_count": 2
# }
# }
# # ============================================================================
# # REQUEST/RESPONSE MODELS (for API)
# # ============================================================================
# class CreateConversationRequest(BaseModel):
# """Request body for creating a new conversation"""
# title: Optional[str] = Field(
# default=None,
# description="Optional custom title. If not provided, will be auto-generated from first message",
# max_length=100
# )
# first_message: Optional[str] = Field(
# default=None,
# description="Optional first user message to start the conversation",
# max_length=1000
# )
# class Config:
# schema_extra = {
# "example": {
# "title": "Savings Account Help",
# "first_message": "How do I open a savings account?"
# }
# }
# class AddMessageRequest(BaseModel):
# """Request body for adding a message to conversation"""
# message: str = Field(..., description="User message to add")
# class Config:
# schema_extra = {
# "example": {
# "message": "What are the interest rates?"
# }
# }
# class UpdateConversationRequest(BaseModel):
# """Request body for updating conversation properties"""
# title: Optional[str] = Field(default=None, description="New title")
# is_archived: Optional[bool] = Field(default=None, description="Archive status")
# class Config:
# schema_extra = {
# "example": {
# "title": "Fixed Deposit Rates Discussion"
# }
# }
# class ConversationResponse(BaseModel):
# """Response model for single conversation"""
# id: str = Field(..., description="Conversation ID")
# user_id: str
# title: str
# messages: List[Message]
# is_archived: bool
# created_at: datetime
# updated_at: datetime
# last_message_at: Optional[datetime]
# message_count: int
# class Config:
# json_encoders = {
# datetime: lambda v: v.isoformat()
# }
# class ConversationListResponse(BaseModel):
# """Response model for list of conversations (without full messages)"""
# id: str
# user_id: str
# title: str
# preview: str = Field(..., description="Last message preview (first 100 chars)")
# is_archived: bool
# created_at: datetime
# updated_at: datetime
# last_message_at: Optional[datetime]
# message_count: int
# class Config:
# json_encoders = {
# datetime: lambda v: v.isoformat()
# }
# schema_extra = {
# "example": {
# "id": "507f1f77bcf86cd799439011",
# "user_id": "user_123",
# "title": "Account Balance Inquiry",
# "preview": "What is my current account balance?",
# "is_archived": False,
# "created_at": "2024-01-15T10:30:00",
# "updated_at": "2024-01-15T10:35:00",
# "last_message_at": "2024-01-15T10:35:00",
# "message_count": 6
# }
# }
# class ConversationListResult(BaseModel):
# """Paginated list of conversations"""
# conversations: List[ConversationListResponse]
# total: int = Field(..., description="Total conversations matching filter")
# page: int = Field(default=1, description="Current page number")
# page_size: int = Field(default=20, description="Items per page")
# has_more: bool = Field(..., description="Are there more pages?")
# class Config:
# schema_extra = {
# "example": {
# "conversations": [],
# "total": 42,
# "page": 1,
# "page_size": 20,
# "has_more": True
# }
# }
# # class PyObjectId(ObjectId):
# # """Custom ObjectId type for Pydantic validation"""
# # @classmethod
# # def __get_validators__(cls):
# # yield cls.validate
# # @classmethod
# # def validate(cls, v):
# # if not ObjectId.is_valid(v):
# # raise ValueError("Invalid ObjectId")
# # return ObjectId(v)
# # @classmethod
# # def __modify_schema__(cls, field_schema):
# # field_schema.update(type="string")
# # allow_population_by_field_name = True
# # arbitrary_types_allowed = True
# # model_config = {
# # "populate_by_name": True,
# # "arbitrary_types_allowed": True,
# # }
# # json_encoders = {
# # ObjectId: str,
# # datetime: lambda v: v.isoformat()
# # }