gateway/modules/interfaces/lucydomModel.py
2025-05-17 11:38:38 +02:00

265 lines
No EOL
14 KiB
Python

"""
LucyDOM model classes for the workflow and document system.
"""
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 getLabel(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")
mandateId: int = Field(description="ID of the associated mandate")
userId: 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
fieldLabels: Dict[str, Label] = {
"id": Label(default="ID", translations={}),
"mandateId": Label(default="Mandate ID", translations={"en": "Mandate ID", "fr": "ID de mandat"}),
"userId": 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")
mandateId: int = Field(description="ID of the associated mandate")
userId: int = Field(description="ID of the creator")
name: str = Field(description="Name of the data object")
mimeType: str = Field(description="Type of the data object MIME type")
size: Optional[int] = Field(None, description="Size of the data object in bytes")
fileHash: str = Field(description="Hash code for deduplication")
creationDate: Optional[str] = Field(None, description="Upload date")
workflowId: 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
fieldLabels: Dict[str, Label] = {
"id": Label(default="ID", translations={}),
"mandateId": Label(default="Mandate ID", translations={"en": "Mandate ID", "fr": "ID de mandat"}),
"userId": Label(default="User ID", translations={"en": "User ID", "fr": "ID d'utilisateur"}),
"name": Label(default="Name", translations={"en": "Name", "fr": "Nom"}),
"mimeType": Label(default="Type", translations={"en": "Type", "fr": "Type"}),
"size": Label(default="Size", translations={"en": "Size", "fr": "Taille"}),
"fileHash": Label(default="File Hash", translations={"en": "Hash", "fr": "Hash"}),
"creationDate": Label(default="Upload date", translations={"en": "Upload date", "fr": "Date de téléchargement"}),
"workflowId": 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="content of the file, text or base64 encoded based on base64Encoded flag")
base64Encoded: bool = Field(description="Flag indicating whether the data is base64 encoded")
class MsftToken(BaseModel):
"""Data model for Microsoft authentication tokens"""
id: int = Field(description="Unique ID of the token")
mandateId: int = Field(description="ID of the associated mandate")
userId: int = Field(description="ID of the user")
token_data: str = Field(description="JSON string containing the token data")
created_at: str = Field(description="Timestamp when the token was created")
updated_at: str = Field(description="Timestamp when the token was last updated")
label: Label = Field(
default=Label(default="Microsoft Token", translations={"en": "Microsoft Token", "fr": "Jeton Microsoft"}),
description="Label for the class"
)
# Labels for attributes
fieldLabels: Dict[str, Label] = {
"id": Label(default="ID", translations={}),
"mandateId": Label(default="Mandate ID", translations={"en": "Mandate ID", "fr": "ID de mandat"}),
"userId": Label(default="User ID", translations={"en": "User ID", "fr": "ID d'utilisateur"}),
"token_data": Label(default="Token Data", translations={"en": "Token Data", "fr": "Données du jeton"}),
"created_at": Label(default="Created At", translations={"en": "Created At", "fr": "Créé le"}),
"updated_at": Label(default="Updated At", translations={"en": "Updated At", "fr": "Mis à jour le"})
}
# Workflow model classes
class DocumentContent(BaseModel):
"""Content of a document in the workflow"""
sequenceNr: 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")
mimeType: str = Field(description="MIME type")
summary: str = Field(description="Summary of the file content")
data: str = Field(description="Actual content, text or base64 encoded based on base64Encoded flag")
base64Encoded: bool = Field(description="Flag indicating whether the data is base64 encoded")
metadata: Dict[str, Any] = Field(default_factory=dict, description="Metadata about the content, such as isText 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")
fileId: int = Field(description="ID of the referenced file in the database")
mimeType: str = Field(description="MIME type")
data: str = Field(description="Content of the data as text or base64 encoded based on base64Encoded flag")
base64Encoded: bool = Field(description="Flag indicating whether the data is base64 encoded")
contents: List[DocumentContent] = Field(description="Document contents")
class DataStats(BaseModel):
"""Statistics for performance and data usage"""
processingTime: Optional[float] = Field(None, description="Processing time in seconds")
tokenCount: Optional[int] = Field(None, description="Token count (for AI models)")
bytesSent: Optional[int] = Field(None, description="Bytes sent")
bytesReceived: Optional[int] = Field(None, description="Bytes received")
class WorkflowMessage(BaseModel):
"""Message object in the workflow"""
id: str = Field(description="Unique ID of the message")
workflowId: str = Field(description="Reference to the parent workflow")
parentMessageId: Optional[str] = Field(None, description="Reference to the replied message")
startedAt: str = Field(description="Timestamp for message creation")
finishedAt: Optional[str] = Field(None, description="Timestamp for message completion")
sequenceNo: int = Field(description="Sequence number for sorting")
status: str = Field(description="Status of the message ('first', 'step', 'last')")
role: str = Field(description="Role of the sender ('system', 'user', 'assistant')")
dataStats: 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")
agentName: Optional[str] = Field(None, description="Name of the agent used")
class WorkflowLog(BaseModel):
"""Log entry for a workflow"""
id: str = Field(description="Unique ID of the log entry")
workflowId: str = Field(description="ID of the associated workflow")
message: str = Field(description="Log message content")
type: str = Field(description="Type of log ('info', 'warning', 'error')")
timestamp: str = Field(description="Timestamp of the log entry")
agentName: str = Field(description="Name of the agent that created the log")
status: str = Field(description="Status of the workflow at log time")
progress: Optional[int] = Field(None, description="Progress value (0-100)")
mandateId: Optional[int] = Field(None, description="ID of the mandate")
userId: Optional[int] = Field(None, description="ID of the user")
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")
mandateId: int = Field(description="ID of the mandate")
userId: int = Field(description="ID of the user")
status: str = Field(description="Status of the workflow ('running', 'completed', 'failed', 'stopped')")
startedAt: str = Field(description="Start timestamp")
lastActivity: str = Field(description="Timestamp of the last activity")
dataStats: Optional[Dict[str, Any]] = Field(None, description="Total statistics")
currentRound: int = Field(default=1, description="Current round/iteration of the workflow")
messageIds: List[str] = Field(default=[], description="List of message IDs in this workflow")
messages: List[WorkflowMessage] = Field(default=[], description="Message history (in-memory representation)")
logs: List[WorkflowLog] = Field(default=[], description="Log entries (in-memory representation)")
# Agent and Workflow Task Models
class AgentResult(BaseModel):
"""Result structure returned by agent processing"""
feedback: str = Field(description="Text response explaining what the agent did")
documents: List[Document] = Field(default=[], description="List of document objects created by the agent")
label: Label = Field(
default=Label(default="Agent Result", translations={"en": "Agent Result", "fr": "Résultat d'agent"}),
description="Label for the class"
)
class AgentInfo(BaseModel):
"""Information about an agent's capabilities"""
name: str = Field(description="Name of the agent")
description: str = Field(description="Description of the agent's functionality")
capabilities: List[str] = Field(default=[], description="List of agent capabilities")
label: Label = Field(
default=Label(default="Agent Information", translations={"en": "Agent Information", "fr": "Information d'agent"}),
description="Label for the class"
)
class InputDocument(BaseModel):
"""Input document specification for a task"""
label: str = Field(description="Document label in the format 'filename.ext'")
fileId: Optional[int] = Field(None, description="ID of the existing document if referring to one")
contentPart: str = Field(default="", description="Content part to focus on, empty string for all contents")
prompt: str = Field(description="AI prompt to describe what data to extract from the file")
class OutputDocument(BaseModel):
"""Output document specification for a task"""
label: str = Field(description="Document label in the format 'filename.ext'")
prompt: str = Field(description="AI prompt to describe the content of the file")
class TaskItem(BaseModel):
"""Individual task in the workplan"""
agent: str = Field(description="Name of an available agent")
prompt: str = Field(description="Specific instructions to the agent, that he knows what to do with which documents and which output to provide")
outputDocuments: List[OutputDocument] = Field(default=[], description="List of required output documents")
inputDocuments: List[InputDocument] = Field(default=[], description="List of input documents to process")
label: Label = Field(
default=Label(default="Task Item", translations={"en": "Task Item", "fr": "Élément de tâche"}),
description="Label for the class"
)
class TaskPlan(BaseModel):
"""Work plan created by project manager"""
objFinalDocuments: List[str] = Field(default=[], description="List of required result documents")
objWorkplan: List[TaskItem] = Field(default=[], description="Plan for executing agents")
objUserResponse: str = Field(description="Response to the user explaining the plan")
userLanguage: str = Field(default="en", description="Language code of the user's request")
label: Label = Field(
default=Label(default="Task Plan", translations={"en": "Task Plan", "fr": "Plan de tâches"}),
description="Label for the class"
)
class WorkflowStatus(BaseModel):
"""Workflow status messages"""
init: str = Field(default="Workflow initialized")
running: str = Field(default="Running workflow")
waiting: str = Field(default="Waiting for input")
completed: str = Field(default="Workflow completed successfully")
stopped: str = Field(default="Workflow stopped by user")
failed: str = Field(default="Error in workflow")
label: Label = Field(
default=Label(default="Workflow Status", translations={"en": "Workflow Status", "fr": "État du workflow"}),
description="Label for the class"
)
# Request models for the API
class UserInputRequest(BaseModel):
"""Request for user input to a running workflow"""
prompt: str = Field(description="Message from the user")
listFileId: List[int] = Field(default=[], description="List of FileItem IDs")