from pydantic import BaseModel, Field from typing import List, Dict, Any, Optional class Label(BaseModel): """Label for an attribute or a class with support for multiple languages""" default: str translations: Dict[str, str] = {} def get_label(self, language: str = None): """Returns the label in the specified language, or the default value if not available""" if language and language in self.translations: return self.translations[language] return self.default class Prompt(BaseModel): """Data model for a prompt""" id: int = Field(description="Unique ID of the prompt") mandate_id: int = Field(description="ID of the associated mandate") user_id: int = Field(description="ID of the creator") content: str = Field(description="Content of the prompt") name: str = Field(description="Display name of the prompt") label: Label = Field( default=Label(default="Prompt", translations={"en": "Prompt", "fr": "Invite"}), description="Label for the class" ) # Labels for attributes field_labels: Dict[str, Label] = { "id": Label(default="ID", translations={}), "mandate_id": Label(default="Mandate ID", translations={"en": "Mandate ID", "fr": "ID de mandat"}), "user_id": Label(default="User ID", translations={"en": "User ID", "fr": "ID d'utilisateur"}), "content": Label(default="Content", translations={"en": "Content", "fr": "Contenu"}), "name": Label(default="Name", translations={"en": "Label", "fr": "Nom"}), } class FileItem(BaseModel): """Data model for a file""" id: int = Field(description="Unique ID of the data object") mandate_id: int = Field(description="ID of the associated mandate") user_id: int = Field(description="ID of the creator") name: str = Field(description="Name of the data object") mime_type: str = Field(description="Type of the data object MIME type") size: Optional[int] = Field(None, description="Size of the data object in bytes") file_hash: str = Field(description="Hash code for deduplication") creation_date: Optional[str] = Field(None, description="Upload date") workflow_id: Optional[str] = Field(None, description="ID of the associated workflow, if any") label: Label = Field( default=Label(default="Data Object", translations={"en": "Data Object", "fr": "Objet de données"}), description="Label for the class" ) # Labels for attributes field_labels: Dict[str, Label] = { "id": Label(default="ID", translations={}), "mandate_id": Label(default="Mandate ID", translations={"en": "Mandate ID", "fr": "ID de mandat"}), "user_id": Label(default="User ID", translations={"en": "User ID", "fr": "ID d'utilisateur"}), "name": Label(default="Name", translations={"en": "Name", "fr": "Nom"}), "mime_type": Label(default="Type", translations={"en": "Type", "fr": "Type"}), "size": Label(default="Size", translations={"en": "Size", "fr": "Taille"}), "file_hash": Label(default="File Hash", translations={"en": "Hash", "fr": "Hash"}), "creation_date": Label(default="Upload date", translations={"en": "Upload date", "fr": "Date de téléchargement"}), "workflow_id": Label(default="Workflow ID", translations={"en": "Workflow ID", "fr": "ID du workflow"}) } class FileData(BaseModel): """Data model for file content""" id: int = Field(description="Unique ID of the data object") data: str = Field(description="Binary content of the file as base64 string") # Workflow model classes class DocumentContent(BaseModel): """Content of a document in the workflow""" sequence_nr: int = Field(1, description="Sequence number of the content in the source document") name: str = Field(description="Designation") ext: str = Field(description="Content extension for export: txt, csv, json, jpg, png") content_type: str = Field(description="MIME type") summary: str = Field(description="Summary of the file content") metadata: Dict[str, Any] = Field(default_factory=dict, description="Metadata about the content, such as is_text flag, format information, encoding, etc.") class Document(BaseModel): """Document in the workflow - References a file directly in the database""" id: str = Field(description="Unique ID of the document") name: str = Field(description="Name of the data object") ext: str = Field(description="Extension of the data object") file_id: int = Field(description="ID of the referenced file in the database") data: str = Field(description="Content of the data as base64 string") contents: List[DocumentContent] = Field(description="Document contents") class DataStats(BaseModel): """Statistics for performance and data usage""" processing_time: Optional[float] = Field(None, description="Processing time in seconds") token_count: Optional[int] = Field(None, description="Token count (for AI models)") bytes_sent: Optional[int] = Field(None, description="Bytes sent") bytes_received: Optional[int] = Field(None, description="Bytes received") class Message(BaseModel): """Message object in the workflow""" id: str = Field(description="Unique ID of the message") workflow_id: str = Field(description="Reference to the parent workflow") parent_message_id: Optional[str] = Field(None, description="Reference to the replied message") started_at: str = Field(description="Timestamp for message creation") finished_at: Optional[str] = Field(None, description="Timestamp for message completion") sequence_no: int = Field(description="Sequence number for sorting") status: str = Field(description="Status of the message ('processing', 'completed')") role: str = Field(description="Role of the sender ('system', 'user', 'assistant')") data_stats: Optional[DataStats] = Field(None, description="Statistics") documents: Optional[List[Document]] = Field(None, description="Documents in this message (references to files in the database)") content: Optional[str] = Field(None, description="Text content of the message") agent_name: Optional[str] = Field(None, description="Name of the agent used") class Workflow(BaseModel): """Workflow object for multi-agent system""" id: str = Field(description="Unique ID of the workflow") name: Optional[str] = Field(None, description="Name of the workflow") mandate_id: int = Field(description="ID of the mandate") user_id: int = Field(description="ID of the user") status: str = Field(description="Status of the workflow ('running', 'completed')") started_at: str = Field(description="Start timestamp") last_activity: str = Field(description="Timestamp of the last activity") message_ids: List[str] = Field(default=[], description="List of message IDs in this workflow") data_stats: Optional[Dict[str, Any]] = Field(None, description="Total statistics") messages: List[Message] = Field(default=[], description="Message history") logs: List[Dict[str, Any]] = Field(default=[], description="Log entries") # Request models for the API class UserInputRequest(BaseModel): """Request for user input to a running workflow""" prompt: str = Field(description="Message from the user") list_file_id: List[int] = Field(default=[], description="List of FileItem IDs")