gateway/modules/features/chatbotV2/datamodelFeatureChatbotV2.py

85 lines
5.1 KiB
Python

# Copyright (c) 2025 Patrick Motsch
# All rights reserved.
"""
Pydantic models for Chatbot V2 feature.
Stores context per chat: uploaded files, extracted content, and conversation history.
"""
import uuid
from typing import Optional, List, Dict, Any
from pydantic import BaseModel, Field
from modules.shared.timeUtils import getUtcTimestamp
class ChatbotV2ContextFile(BaseModel):
"""Uploaded file metadata for context extraction."""
id: str = Field(default_factory=lambda: str(uuid.uuid4()), description="Primary key")
conversationId: str = Field(description="Foreign key to conversation")
fileId: str = Field(description="Foreign key to file in central Files table")
fileName: str = Field(description="Original file name")
mimeType: str = Field(default="application/octet-stream", description="MIME type")
fileSize: int = Field(default=0, description="File size in bytes")
uploadOrder: int = Field(default=0, description="Order of upload (0-based)")
class ChatbotV2ExtractedContext(BaseModel):
"""Extracted content per conversation - text blocks and summaries for chat context."""
id: str = Field(default_factory=lambda: str(uuid.uuid4()), description="Primary key")
conversationId: str = Field(description="Foreign key to conversation")
textBlocks: List[Dict[str, Any]] = Field(default_factory=list, description="Extracted text blocks per file (page, text, block_id)")
summaries: List[Dict[str, Any]] = Field(default_factory=list, description="Optional per-document or per-section summaries")
extractionStatus: str = Field(default="pending", description="pending|running|completed|failed")
errors: List[str] = Field(default_factory=list, description="Extraction errors if any")
createdAt: float = Field(default_factory=getUtcTimestamp, description="When extraction completed")
class ChatbotV2Document(BaseModel):
"""Documents attached to chatbot V2 messages."""
id: str = Field(default_factory=lambda: str(uuid.uuid4()), description="Primary key")
messageId: str = Field(description="Foreign key to message")
fileId: str = Field(description="Foreign key to file")
fileName: str = Field(description="Name of the file")
fileSize: int = Field(default=0, description="Size of the file")
mimeType: str = Field(default="application/octet-stream", description="MIME type")
class ChatbotV2Message(BaseModel):
"""Messages in Chatbot V2 conversations."""
id: str = Field(default_factory=lambda: str(uuid.uuid4()), description="Primary key")
conversationId: str = Field(description="Foreign key to conversation")
parentMessageId: Optional[str] = Field(None, description="Parent message ID for threading")
message: Optional[str] = Field(None, description="Message content")
role: str = Field(description="Role: user or assistant")
status: str = Field(default="step", description="Status: first, step, last")
sequenceNr: int = Field(default=0, description="Sequence number of the message")
publishedAt: Optional[float] = Field(default=None, description="When the message was published (UTC timestamp)")
roundNumber: int = Field(default=1, description="Round number in conversation")
class ChatbotV2Log(BaseModel):
"""Log entries for Chatbot V2 conversations."""
id: str = Field(default_factory=lambda: str(uuid.uuid4()), description="Primary key")
conversationId: str = Field(description="Foreign key to conversation")
message: str = Field(description="Log message")
type: str = Field(default="info", description="Log type: info, warning, error")
timestamp: float = Field(default_factory=getUtcTimestamp, description="When the log entry was created")
status: Optional[str] = Field(None, description="Status of the log entry")
progress: Optional[float] = Field(None, description="Progress indicator (0.0 to 1.0)")
class ChatbotV2Conversation(BaseModel):
"""Chatbot V2 conversation - stores context information per chat."""
id: str = Field(default_factory=lambda: str(uuid.uuid4()), description="Primary key")
featureInstanceId: str = Field(description="Feature instance ID for per-instance isolation")
mandateId: Optional[str] = Field(None, description="Mandate ID for RBAC")
name: Optional[str] = Field(None, description="Name of the conversation")
status: str = Field(default="extracting", description="extracting|ready|running|stopped")
currentRound: int = Field(default=0, description="Current round number")
lastActivity: float = Field(default_factory=getUtcTimestamp, description="Timestamp of last activity")
startedAt: float = Field(default_factory=getUtcTimestamp, description="When the conversation started")
extractedContextId: Optional[str] = Field(None, description="FK to ChatbotV2ExtractedContext when ready")
maxSteps: int = Field(default=10, description="Maximum number of chat rounds")
# Hydrated from child tables (not stored in DB as columns)
contextFiles: List[ChatbotV2ContextFile] = Field(default_factory=list, description="Uploaded context files")
messages: List[ChatbotV2Message] = Field(default_factory=list, description="Conversation messages")