diff --git a/app/MindWork AI Studio/Assistants/I18N/allTexts.lua b/app/MindWork AI Studio/Assistants/I18N/allTexts.lua index 17788f24..06009d62 100644 --- a/app/MindWork AI Studio/Assistants/I18N/allTexts.lua +++ b/app/MindWork AI Studio/Assistants/I18N/allTexts.lua @@ -7309,6 +7309,9 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::VALIDATION::FILEEXTENSIONVALIDATION::T29806295 -- Images are not supported at this place UI_TEXT_CONTENT["AISTUDIO::TOOLS::VALIDATION::FILEEXTENSIONVALIDATION::T305247150"] = "Images are not supported at this place" +-- Unsupported file type +UI_TEXT_CONTENT["AISTUDIO::TOOLS::VALIDATION::FILEEXTENSIONVALIDATION::T4041351522"] = "Unsupported file type" + -- Executables are not allowed UI_TEXT_CONTENT["AISTUDIO::TOOLS::VALIDATION::FILEEXTENSIONVALIDATION::T4167762413"] = "Executables are not allowed" diff --git a/app/MindWork AI Studio/Chat/ContentText.cs b/app/MindWork AI Studio/Chat/ContentText.cs index 93d0fcb2..9daeec49 100644 --- a/app/MindWork AI Studio/Chat/ContentText.cs +++ b/app/MindWork AI Studio/Chat/ContentText.cs @@ -229,11 +229,15 @@ public sealed class ContentText : IContent if(this.FileAttachments.Count > 0) { + var normalizedAttachments = this.FileAttachments + .Select(attachment => attachment.Normalize()) + .ToList(); + // Get the list of existing documents: - var existingDocuments = this.FileAttachments.Where(x => x.Type is FileAttachmentType.DOCUMENT && x.Exists).ToList(); + var existingDocuments = normalizedAttachments.Where(x => x.Type is FileAttachmentType.DOCUMENT && x.Exists).ToList(); // Log warning for missing files: - var missingDocuments = this.FileAttachments.Except(existingDocuments).Where(x => x.Type is FileAttachmentType.DOCUMENT).ToList(); + var missingDocuments = normalizedAttachments.Except(existingDocuments).Where(x => x.Type is FileAttachmentType.DOCUMENT).ToList(); if (missingDocuments.Count > 0) foreach (var missingDocument in missingDocuments) LOGGER.LogWarning("File attachment no longer exists and will be skipped: '{MissingDocument}'.", missingDocument.FilePath); @@ -269,7 +273,7 @@ public sealed class ContentText : IContent sb.AppendLine("````"); } - var numImages = this.FileAttachments.Count(x => x is { IsImage: true, Exists: true }); + var numImages = normalizedAttachments.Count(x => x is { IsImage: true, Exists: true }); if (numImages > 0) { sb.AppendLine(); diff --git a/app/MindWork AI Studio/Chat/FileAttachment.cs b/app/MindWork AI Studio/Chat/FileAttachment.cs index 10e506d8..bdc9651d 100644 --- a/app/MindWork AI Studio/Chat/FileAttachment.cs +++ b/app/MindWork AI Studio/Chat/FileAttachment.cs @@ -53,6 +53,11 @@ public record FileAttachment(FileAttachmentType Type, string FileName, string Fi /// public bool Exists => File.Exists(this.FilePath); + /// + /// Rebuilds the attachment from its current file path so file type detection uses the latest rules. + /// + public FileAttachment Normalize() => FromPath(this.FilePath); + /// /// Creates a FileAttachment from a file path by automatically determining the type, /// extracting the filename, and reading the file size. diff --git a/app/MindWork AI Studio/Components/ChatComponent.razor.cs b/app/MindWork AI Studio/Components/ChatComponent.razor.cs index f734d620..c4b30a2f 100644 --- a/app/MindWork AI Studio/Components/ChatComponent.razor.cs +++ b/app/MindWork AI Studio/Components/ChatComponent.razor.cs @@ -94,7 +94,7 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable // Apply template's file attachments, if any: foreach (var attachment in this.currentChatTemplate.FileAttachments) - this.chatDocumentPaths.Add(attachment); + this.chatDocumentPaths.Add(attachment.Normalize()); // // Check for deferred messages of the kind 'SEND_TO_CHAT', @@ -392,7 +392,7 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable // Apply template's file attachments (replaces existing): this.chatDocumentPaths.Clear(); foreach (var attachment in this.currentChatTemplate.FileAttachments) - this.chatDocumentPaths.Add(attachment); + this.chatDocumentPaths.Add(attachment.Normalize()); if(this.ChatThread is null) return; @@ -538,10 +538,15 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable IContent? lastUserPrompt; if (!reuseLastUserPrompt) { + var normalizedAttachments = this.chatDocumentPaths + .Select(attachment => attachment.Normalize()) + .Where(attachment => attachment.IsValid) + .ToList(); + lastUserPrompt = new ContentText { Text = this.userInput, - FileAttachments = [..this.chatDocumentPaths.Where(x => x.IsValid)], + FileAttachments = normalizedAttachments, }; // @@ -764,7 +769,7 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable // Apply template's file attachments: this.chatDocumentPaths.Clear(); foreach (var attachment in this.currentChatTemplate.FileAttachments) - this.chatDocumentPaths.Add(attachment); + this.chatDocumentPaths.Add(attachment.Normalize()); // Now, we have to reset the data source options as well: this.ApplyStandardDataSourceOptions(); diff --git a/app/MindWork AI Studio/Dialogs/ChatTemplateDialog.razor.cs b/app/MindWork AI Studio/Dialogs/ChatTemplateDialog.razor.cs index 0aa16ddf..cbc438cf 100644 --- a/app/MindWork AI Studio/Dialogs/ChatTemplateDialog.razor.cs +++ b/app/MindWork AI Studio/Dialogs/ChatTemplateDialog.razor.cs @@ -133,7 +133,7 @@ public partial class ChatTemplateDialog : MSGComponentBase SystemPrompt = this.DataSystemPrompt, PredefinedUserPrompt = this.PredefinedUserPrompt, ExampleConversation = this.dataExampleConversation, - FileAttachments = [..this.fileAttachments], + FileAttachments = this.fileAttachments.Select(attachment => attachment.Normalize()).ToList(), AllowProfileUsage = this.AllowProfileUsage, EnterpriseConfigurationPluginId = Guid.Empty,