From ff63ebcb39a43ec085ce99dfb67a8c3e46949a3d Mon Sep 17 00:00:00 2001
From: ValueOn AG
Date: Fri, 16 May 2025 16:04:14 +0200
Subject: [PATCH] fixed auth
---
modules/lucydomModel.py | 97 +++++++++++++++++++++++++++++++++++++++++
notes/changelog.txt | 33 +++++++++++---
routes/routeUsers.py | 15 ++++++-
3 files changed, 137 insertions(+), 8 deletions(-)
diff --git a/modules/lucydomModel.py b/modules/lucydomModel.py
index 782d0b0e..3c71414c 100644
--- a/modules/lucydomModel.py
+++ b/modules/lucydomModel.py
@@ -181,6 +181,103 @@ class Workflow(BaseModel):
logs: List[WorkflowLog] = Field(default=[], description="Log entries (in-memory representation)")
+# Agent and Workflow Task Models
+
+class AgentTask(BaseModel):
+ """Standardized task structure for agent processing"""
+ taskId: str = Field(description="Unique ID for this task")
+ workflowId: str = Field(description="ID of the parent workflow")
+ prompt: str = Field(description="The main instruction for the agent")
+ inputDocuments: List[Document] = Field(default=[], description="List of document objects to process")
+ outputSpecifications: List[Dict[str, str]] = Field(default=[], description="List of required output documents")
+ context: Dict[str, Any] = Field(description="Additional contextual information")
+
+ label: Label = Field(
+ default=Label(default="Agent Task", translations={"en": "Agent Task", "fr": "Tâche d'agent"}),
+ description="Label for the class"
+ )
+
+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"
+ )
+
+class WorkflowLabels(BaseModel):
+ """Global workflow labels and messages"""
+ systemName: str = Field(default="AI Assistant")
+ workflowStatusMessages: WorkflowStatus = Field(default_factory=WorkflowStatus)
+
+ label: Label = Field(
+ default=Label(default="Workflow Labels", translations={"en": "Workflow Labels", "fr": "Étiquettes du workflow"}),
+ description="Label for the class"
+ )
+
# Request models for the API
class UserInputRequest(BaseModel):
diff --git a/notes/changelog.txt b/notes/changelog.txt
index 641ccdb7..056a465e 100644
--- a/notes/changelog.txt
+++ b/notes/changelog.txt
@@ -1,15 +1,34 @@
....................... TASKS
+! function callAI() to ask with userPrompt,systemPrompt optional), not with json
+! in the taskplan to refer files always in context of user/mandate
+! userinput to handle with object AgentQuery --> when received in frontend to enhance for full object
+! user prompt to handle as directive AND content
+! database to work with files per record, not files per table
+! database to serialize list[] objects and replace by id-list
-agentDocumentation delivers a ".docx" file, but the content is a ".md" text markup file
+we need to adapt following things according to data objects in lucydomModel.py:
+- All file handling in whole code to be with correct file objects FileItem and FileData object
+- Everywhere to use datamodel specification by lucydomModel.py
+- the workflow in "workflowManager.py" to run with pure documents and no content extraction from documents. To use revised Document model everywhere
+- Prompts for tasklist to revise accordingly and to make clear, that the prompting for data extraction will be a job for each agent, not to be topic of the taskplan.
+- task to the agent to include the prompt for his job to do and also no data extraction. also here to make clear, that data extraction will be done by the agent.
-agentDocumentation to extract data per chapter
+Implemented agents: they use following tools depending on their job:
+- extract content using global function getContent(document list) --> define prompt for each document of to extract data based on agent's task. it creates an ai call to specify the prompt per document to extract relevant data in the required format using the global function documentProcessor() and stores extracted data in the content object to use
+- produce message object (feedback prompt, document list)
-check data extraction tabelle im pdf
-Check data extraction of types!
+function documentProcessor():
+- return one content per document using ai call
+- if there are many content objects in a document it uses one ai call per content to be specified, that if no relevant content is in the content object, an empty string is returned, otherwise the text in the required format
+- the extraction of each content object has a limit for data size. this exceeded the content is handled by batches depending on the file type (csv --> set of records, text in tokens, etc.)
+
+Other topics:
+- agentCoder only to do algorythmic jobs, no data extraction
+- agentDocumentation to extract data per chapter
+
-... next point
----------------------- OPEN
@@ -17,13 +36,13 @@ Check data extraction of types!
PRIO1:
+agentDocumentation delivers a ".docx" file, but the content is a ".md" text markup file
+
sharepoint connector with document search, content search, content extraction
PRIO2:
-Split big files into content-parts
-
Integrate NDA Text as modal form - Data governance agreement by login with checkbox
diff --git a/routes/routeUsers.py b/routes/routeUsers.py
index dffa63f8..0b8e4930 100644
--- a/routes/routeUsers.py
+++ b/routes/routeUsers.py
@@ -109,7 +109,20 @@ async def registerUser(userData: dict = Body(...)):
if "fullName" in userData and userData["fullName"]:
userCreateData["fullName"] = userData["fullName"]
+
newUser = gateway.createUser(**userCreateData)
+
+ # Verify that the password was properly stored
+ createdUser = gateway.getUserByUsername(userData["username"])
+ if not createdUser or "hashedPassword" not in createdUser:
+ # If password wasn't stored, delete the user and raise an error
+ if createdUser:
+ gateway.deleteUser(createdUser["id"])
+ raise HTTPException(
+ status_code=500,
+ detail="Failed to store password securely. Please try again."
+ )
+
return newUser
except ValueError as e:
logger.error(f"ValueError in registration: {str(e)}")
@@ -121,7 +134,7 @@ async def registerUser(userData: dict = Body(...)):
import traceback
logger.error(f"Unexpected error in registration: {str(e)}")
logger.error(traceback.format_exc())
- raise HTTPException(status_code=500, detail=f"Registration failed: {str(e)}")
+ raise HTTPException(status_code=500, detail=f"Registration failed: {str(e)}")
@router.post("/register-with-msal", response_model=Dict[str, Any])
async def registerUserWithMsal(userData: dict = Body(...)):