From e450e530aaed61fe9919ca7defd0d644315421e1 Mon Sep 17 00:00:00 2001 From: ValueOn AG Date: Mon, 25 Aug 2025 23:57:14 +0200 Subject: [PATCH] release 2 end 2 end tested - before ui fixes --- modules/chat/handling/methodOutlook.py | 3 ++ modules/methods/methodOutlook.py | 57 ++++++++++++++++++++++++-- notes/changelog.txt | 50 +--------------------- 3 files changed, 58 insertions(+), 52 deletions(-) create mode 100644 modules/chat/handling/methodOutlook.py diff --git a/modules/chat/handling/methodOutlook.py b/modules/chat/handling/methodOutlook.py new file mode 100644 index 00000000..b28b04f6 --- /dev/null +++ b/modules/chat/handling/methodOutlook.py @@ -0,0 +1,3 @@ + + + diff --git a/modules/methods/methodOutlook.py b/modules/methods/methodOutlook.py index 7fff0faa..dfa7ce22 100644 --- a/modules/methods/methodOutlook.py +++ b/modules/methods/methodOutlook.py @@ -190,6 +190,13 @@ class MethodOutlook(MethodBase): # Clean the query clean_query = query.strip() + # Handle folder specifications first + if clean_query.lower().startswith('folder:'): + folder_name = clean_query[7:].strip() + if folder_name: + # Return the folder specification as-is + return clean_query + # Remove any double quotes that might cause issues clean_query = clean_query.replace('"', '') @@ -227,13 +234,22 @@ class MethodOutlook(MethodBase): clean_query = self._sanitizeSearchQuery(query) + # Check if this is a folder specification (e.g., "folder:Drafts", "folder:Inbox") + if clean_query.lower().startswith('folder:'): + folder_name = clean_query[7:].strip() # Remove "folder:" prefix + if folder_name: + # This is a folder specification, not a text search + # Just filter by folder and return + params["$filter"] = f"parentFolderId eq '{folder_name}'" + params["$orderby"] = "receivedDateTime desc" + return params + # Check if this is a complex search query with multiple operators if any(op in clean_query.lower() for op in ['from:', 'to:', 'subject:', 'received:', 'hasattachment:']): # This is an advanced search query, use $search # Microsoft Graph API supports complex search syntax params["$search"] = f'"{clean_query}"' - # Note: When using $search, we cannot combine it with $orderby or $filter for folder # We'll need to filter results after the API call # Folder filtering will be done after the API call @@ -273,6 +289,13 @@ class MethodOutlook(MethodBase): filter_text = filter_text.strip() + # Handle folder specifications (e.g., "folder:Drafts", "folder:Inbox") + if filter_text.lower().startswith('folder:'): + folder_name = filter_text[7:].strip() # Remove "folder:" prefix + if folder_name: + # This is a folder specification, return empty to let the main method handle it + return {} + # Handle search queries (from:, to:, subject:, etc.) - check this FIRST if any(filter_text.startswith(prefix) for prefix in ['from:', 'to:', 'subject:', 'received:', 'hasattachment:']): return {"$search": f'"{filter_text}"'} @@ -853,6 +876,13 @@ class MethodOutlook(MethodBase): if not query or not query.strip(): return ActionResult.failure(error="Search query is required and cannot be empty") + # Check if this is a folder specification query + if query.strip().lower().startswith('folder:'): + folder_name = query.strip()[7:].strip() # Remove "folder:" prefix + if not folder_name: + return ActionResult.failure(error="Invalid folder specification. Use format 'folder:FolderName'") + logger.info(f"Search query is a folder specification: {folder_name}") + # Validate limit try: limit = int(limit) @@ -883,7 +913,11 @@ class MethodOutlook(MethodBase): api_url = f"{graph_url}/me/messages" params = self._buildSearchParameters(query, folder, limit) - + # Log search parameters for debugging + logger.debug(f"Search query: '{query}'") + logger.debug(f"Search folder: '{folder}'") + logger.debug(f"Search parameters: {params}") + logger.debug(f"API URL: {api_url}") # Make the API call response = requests.get(api_url, headers=headers, params=params) @@ -933,7 +967,7 @@ class MethodOutlook(MethodBase): if email.get("parentFolderId") == folder_id: filtered_emails.append(email) emails = filtered_emails - + logger.debug(f"Applied folder filtering: {len(filtered_emails)} emails found in folder {folder}") else: # Fallback: try to filter by folder name (less reliable) filtered_emails = [] @@ -946,8 +980,23 @@ class MethodOutlook(MethodBase): # If no folder info, include the email (less strict filtering) filtered_emails.append(email) - emails = filtered_emails + logger.debug(f"Applied fallback folder filtering: {len(filtered_emails)} emails found in folder {folder}") + + # Special handling for folder specification queries + if query.strip().lower().startswith('folder:'): + folder_name = query.strip()[7:].strip() + folder_id = self._getFolderId(folder_name, connection) + if folder_id: + # Filter results to only include emails from the specified folder + filtered_emails = [] + for email in emails: + if email.get("parentFolderId") == folder_id: + filtered_emails.append(email) + emails = filtered_emails + logger.debug(f"Applied folder specification filtering: {len(filtered_emails)} emails found in folder {folder_name}") + else: + logger.warning(f"Could not find folder ID for folder specification: {folder_name}") search_result = { diff --git a/notes/changelog.txt b/notes/changelog.txt index be22d634..76b4c957 100644 --- a/notes/changelog.txt +++ b/notes/changelog.txt @@ -2,58 +2,11 @@ TODO -# Document Handling and Handovers -we need to improve document handling in the chat workflow and prompting: - -- document list (result list) labeling including round#, task#, action# -- files: a user friendly name and a timestamp -- prompt: Section of document lists with documents -- document object: to have reference to message, to have label for chat including round#, task#, action#, to have reference to file -- message object: to have reference to round, task, action -- each action and task to deliver a user friendly message or error message to deliver to the user in his language - - -# General inputs: -- Look at the interface*model.py files, here are the current models. -- This is an automated chat, no user input request etc. analyse the code, to understand the logic and the data flow. -- we have no database, we have data interfaces. data objects in pydantic model. - -#Inputs for the models: - -Enhanced ChatDocument model - id: str = Field(default_factory=lambda: str(uuid.uuid4()), description="Primary key") - label: str = Field(description="User-friendly display name") - fileId: str = Field(description="Foreign key to file") - (fileName, fileSize, mimeType, creationDate) --> to remove as attributes; those attributes to get from referenced file object to always have valid attributes (if e.g. file name has been changed by user) - to include a function in model or to adapt calling references - - # New labeling system --> optional attributes - roundNumber: int = Field(description="Round number in workflow") - taskNumber: int = Field(description="Task number within round") - actionNumber: int = Field(description="Action number within task") - - -Enhanced File Management: we do not need a new model here. - -Enhanced Prompt System: we don not need a pydantic model for this. it is about to enhance the action generation prompt to present the document lists with the label and the containing document references; both containing round, task, action number and the file name and extension - -Enhanced Message Object: we do not need a new model here. The current model is good. - -Enhanced Action and Task System: Here we do not need a new model. What we need is the possibility to return "userMessage" in the user language. userMessageType e.g. is not required, as we already have "success" flag. No messgae templates, as message is ai generated. For this the enhanced AI prompt for task plan generation and action plan generation needs a enhanced utput json model including user message instruction with user language indication - - -Can you analyse again with my inputs and present a revised plan. - - - - - - - - # UI Rendering of the workflow - Besseres Rendering der Tasks, Actions, Files (hierarchisch eingerückt) und der Log Entries (ohne Rahmen) - Beim Laden des Workflows die Logs und Messages synchron laden, saubere chronologische Reihenfolge aller Objekte +- im action planning chat die historie des chats pro message (summary) anzeigen, jeweils pro message die dokumentlisten anzeigen, dmit der kontext aller docikente klar ist - documents: den file namen anzeigen, nicht den internen dokumentnamen - Chat: Die Benutzermeldungen pro Action und Task rendern - Über dem Rendering Fenster der Logs und Messages ein professionelles Dashboard, welches die Animation zeigt und graphisch die Blöcke der Tasks und immer animiert die aktive Action eines Tasks. Die Ansicht dynamisch aktualisiert immer nach Abschluss einer Action @@ -63,6 +16,7 @@ Can you analyse again with my inputs and present a revised plan. - neutralizer to activate AND put back placeholders to the returned data # Tests +- workflow continue after stop. to run normally - add a prompt --> then shall be visible in the workflow to select - msft connection bei 2 verschiedene users - chat 3x ausführen mit verschiedenen mailempfängern, test ob round greift