from pydantic import BaseModel, Field from typing import List, Dict, Any, Optional class Label(BaseModel): """Label für ein Attribut oder eine Klasse mit Unterstützung für mehrere Sprachen""" default: str translations: Dict[str, str] = {} def get_label(self, language: str = None): """Gibt das Label in der angegebenen Sprache zurück, oder den Standardwert wenn nicht verfügbar""" if language and language in self.translations: return self.translations[language] return self.default class Prompt(BaseModel): """Datenmodell für einen Prompt""" id: int = Field(description="Eindeutige ID des Prompts") mandate_id: int = Field(description="ID des zugehörigen Mandanten") user_id: int = Field(description="ID des Erstellers") content: str = Field(description="Inhalt des Prompts") name: str = Field(description="Anzeigename des Prompts") label: Label = Field( default=Label(default="Prompt", translations={"en": "Prompt", "fr": "Invite"}), description="Label für die Klasse" ) # Labels für Attribute field_labels: Dict[str, Label] = { "id": Label(default="ID", translations={}), "mandate_id": Label(default="Mandanten-ID", translations={"en": "Mandate ID", "fr": "ID de mandat"}), "user_id": Label(default="Benutzer-ID", translations={"en": "User ID", "fr": "ID d'utilisateur"}), "content": Label(default="Inhalt", translations={"en": "Content", "fr": "Contenu"}), "name": Label(default="Name", translations={"en": "Label", "fr": "Nom"}), } class FileItem(BaseModel): """Datenmodell für ein File""" id: int = Field(description="Eindeutige ID des Datenobjekts") mandate_id: int = Field(description="ID des zugehörigen Mandanten") user_id: int = Field(description="ID des Erstellers") name: str = Field(description="Name des Datenobjekts") mime_type: str = Field(description="Typ des Datenobjekts MIME-Typ") size: Optional[int] = Field(None, description="Größe des Datenobjekts in Bytes") file_hash: str = Field(description="Hash code für Deduplizierung") creation_date: Optional[str] = Field(None, description="Datum des Hochladens") workflow_id: Optional[str] = Field(None, description="ID des zugehörigen Workflows, falls vorhanden") label: Label = Field( default=Label(default="Datenobjekt", translations={"en": "Data Object", "fr": "Objet de données"}), description="Label für die Klasse" ) # Labels für Attribute field_labels: Dict[str, Label] = { "id": Label(default="ID", translations={}), "mandate_id": Label(default="Mandanten-ID", translations={"en": "Mandate ID", "fr": "ID de mandat"}), "user_id": Label(default="Benutzer-ID", translations={"en": "User ID", "fr": "ID d'utilisateur"}), "name": Label(default="Name", translations={"en": "Name", "fr": "Nom"}), "mime_type": Label(default="Typ", translations={"en": "Type", "fr": "Type"}), "size": Label(default="Größe", translations={"en": "Size", "fr": "Taille"}), "file_hash": Label(default="File-Hash", translations={"en": "Hash", "fr": "Hash"}), "creation_date": Label(default="Upload-Datum", 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): """Datenmodell für den File-Inhalt""" id: int = Field(description="Eindeutige ID des Datenobjekts") data: str = Field(description="Binärer Inhalt der Datei als Base64-String") # Workflow-Modellklassen class DocumentContent(BaseModel): """Inhalt eines Dokuments im Workflow""" sequence_nr: int = Field(1, description="Sequenz-Nummer des Inhaltes im Quelldokument") name: str = Field(description="Bezeichnung") ext: str = Field(description="Content extension for export: txt, csv, json, jpg, png") content_type: str = Field(description="MIME-Typ") data: str = Field(description="Binärer Inhalt der Daten als Base64-String") summary: str = Field(description="Zusammenfassung des Datei-Inhaltes") metadata: Dict[str, Any] = Field(default_factory=dict, description="Metadaten zum Inhalt, wie z.B. is_text Flag, Format-Informationen, Encoding usw.") class Document(BaseModel): """Dokument im Workflow - Referenziert direkt eine Datei in der Datenbank""" id: str = Field(description="Eindeutige ID des Dokuments") name: str = Field(description="Name des Datenobjekts") ext: str = Field(description="Extension des Datenobjekts") file_id: int = Field(description="ID der referenzierten Datei in der Datenbank") contents: List[DocumentContent] = Field(description="Dokumentinhalte") class DataStats(BaseModel): """Statistiken für Performance und Datennutzung""" processing_time: Optional[float] = Field(None, description="Verarbeitungszeit in Sekunden") token_count: Optional[int] = Field(None, description="Token-Anzahl (für KI-Modelle)") bytes_sent: Optional[int] = Field(None, description="Gesendete Bytes") bytes_received: Optional[int] = Field(None, description="Empfangene Bytes") class Message(BaseModel): """Nachrichtenobjekt im Workflow""" id: str = Field(description="Eindeutige ID der Nachricht") workflow_id: str = Field(description="Referenz zum übergeordneten Workflow") parent_message_id: Optional[str] = Field(None, description="Referenz zur beantworteten Nachricht") started_at: str = Field(description="Zeitstempel für Nachrichtenerstellung") finished_at: Optional[str] = Field(None, description="Zeitstempel für Nachrichtenabschluss") sequence_no: int = Field(description="Sequenznummer für Sortierung") status: str = Field(description="Status der Nachricht ('processing', 'completed')") role: str = Field(description="Rolle des Absenders ('system', 'user', 'assistant')") data_stats: Optional[DataStats] = Field(None, description="Statistiken") documents: Optional[List[Document]] = Field(None, description="Dokumente in dieser Nachricht (Referenzen zu Dateien in der Datenbank)") content: Optional[str] = Field(None, description="Textinhalt der Nachricht") agent_name: Optional[str] = Field(None, description="Name des verwendeten Agenten") class Workflow(BaseModel): """Workflow-Objekt für Multi-Agent-System""" id: str = Field(description="Eindeutige ID des Workflows") name: Optional[str] = Field(None, description="Name des Workflows") mandate_id: int = Field(description="ID des Mandanten") user_id: int = Field(description="ID des Benutzers") status: str = Field(description="Status des Workflows ('running', 'failed', 'stopped')") started_at: str = Field(description="Startzeitpunkt") last_activity: str = Field(description="Zeitpunkt der letzten Aktivität") last_message_id: str = Field(description="The last registered message") data_stats: Optional[Dict[str, Any]] = Field(None, description="Gesamt-Statistiken") messages: List[Message] = Field(default=[], description="Nachrichtenverlauf") logs: List[Dict[str, Any]] = Field(default=[], description="Protokolleinträge") # Anfragemodelle für die API class WorkflowCreateRequest(BaseModel): """Anfrage zur Erstellung eines neuen Workflows""" name: Optional[str] = Field(None, description="Name des Workflows") prompt: str = Field(description="Zu verwendender Prompt") files: List[int] = Field(default=[], description="Liste von FileItem ID") class UserInputRequest(BaseModel): """Anfrage für Benutzereingabe an einen laufenden Workflow""" prompt: str = Field(description="Nachricht des Benutzers") listFileId: List[int] = Field(default=[], description="Liste zusätzlicher FileItem ID")