diff --git a/app/MindWork AI Studio/Assistants/I18N/allTexts.lua b/app/MindWork AI Studio/Assistants/I18N/allTexts.lua index c5e9e5c3..ba4ce53d 100644 --- a/app/MindWork AI Studio/Assistants/I18N/allTexts.lua +++ b/app/MindWork AI Studio/Assistants/I18N/allTexts.lua @@ -2410,6 +2410,9 @@ UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::VISUALBRIEFING::VISUALBRIEFINGASSISTANT:: -- Creates a new version from the current sources and instructions while keeping the current structure and design. UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::VISUALBRIEFING::VISUALBRIEFINGASSISTANT::T2703645157"] = "Creates a new version from the current sources and instructions while keeping the current structure and design." +-- Images are not supported by the selected provider and model. Select a model with image support, or remove the image sources. +UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::VISUALBRIEFING::VISUALBRIEFINGASSISTANT::T2720475627"] = "Images are not supported by the selected provider and model. Select a model with image support, or remove the image sources." + -- Import as copy UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::VISUALBRIEFING::VISUALBRIEFINGASSISTANT::T2745663129"] = "Import as copy" diff --git a/app/MindWork AI Studio/Assistants/VisualBriefing/VisualBriefingAssistant.razor.Validation.cs b/app/MindWork AI Studio/Assistants/VisualBriefing/VisualBriefingAssistant.razor.Validation.cs index aad36754..0c4f5a8d 100644 --- a/app/MindWork AI Studio/Assistants/VisualBriefing/VisualBriefingAssistant.razor.Validation.cs +++ b/app/MindWork AI Studio/Assistants/VisualBriefing/VisualBriefingAssistant.razor.Validation.cs @@ -1,4 +1,6 @@ using AIStudio.Provider; +using AIStudio.Settings; +using AIStudio.Tools.Rust; using ProviderSettings = AIStudio.Settings.Provider; @@ -15,6 +17,15 @@ public partial class VisualBriefingAssistant /// private bool HasSourceMaterial => this.selectedBriefing?.Sources.Any(source => source.Kind is VisualBriefingSourceKind.SOURCE_MATERIAL) == true; + /// Gets whether any stored source reaches the model as an image. + /// + /// Both source kinds can end up as an image: source preparation converts every visual asset into an + /// image attachment, and a source material file is attached as it is, where the attachment type is + /// derived from the file extension alone. Checking the extension therefore covers both, and it + /// matches the rule the attachment control already applies while a file is being added. + /// + private bool HasImageSources => this.selectedBriefing?.Sources.Any(source => FileTypes.IsAllowedPath(source.Path, FileTypes.IMAGE)) == true; + /// Gets all current field, source, and revision issues shown below the actions. /// /// This is the complete list for the user. The generate buttons disable themselves from the same @@ -53,6 +64,12 @@ public partial class VisualBriefingAssistant } /// Gets the issues with the stored sources, which block only the modes that read them. + /// + /// The image check belongs here rather than to the fields, even though it depends on the selected + /// model: it only matters for the modes that hand the sources to the model at all. Changing just the + /// design reuses the stored evidence and sends no attachments, which is the same distinction the + /// build orchestrator makes before it runs source preparation. + /// private IReadOnlyList SourceIssues { get @@ -64,6 +81,11 @@ public partial class VisualBriefingAssistant if (!this.HasSourceMaterial) issues.Add(T("Please add at least one source material file.")); + // A model can be selected long after the images were attached, so the capability that was + // checked while attaching them has to be checked again here: + if (this.HasImageSources && this.editor.Provider != ProviderSettings.NONE && !this.editor.Provider.SupportsImageInput()) + issues.Add(T("Images are not supported by the selected provider and model. Select a model with image support, or remove the image sources.")); + foreach (var source in this.selectedBriefing.Sources) { var fileName = Path.GetFileName(source.Path); diff --git a/app/MindWork AI Studio/Plugins/languages/de-de-43065dbc-78d0-45b7-92be-f14c2926e2dc/plugin.lua b/app/MindWork AI Studio/Plugins/languages/de-de-43065dbc-78d0-45b7-92be-f14c2926e2dc/plugin.lua index 87536244..53b1f26e 100644 --- a/app/MindWork AI Studio/Plugins/languages/de-de-43065dbc-78d0-45b7-92be-f14c2926e2dc/plugin.lua +++ b/app/MindWork AI Studio/Plugins/languages/de-de-43065dbc-78d0-45b7-92be-f14c2926e2dc/plugin.lua @@ -2412,6 +2412,9 @@ UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::VISUALBRIEFING::VISUALBRIEFINGASSISTANT:: -- Creates a new version from the current sources and instructions while keeping the current structure and design. UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::VISUALBRIEFING::VISUALBRIEFINGASSISTANT::T2703645157"] = "Erstellt eine neue Version aus dem aktuellen Ausgangsmaterial und Anweisungen, wobei die bestehende Struktur und das Design beibehalten werden." +-- Images are not supported by the selected provider and model. Select a model with image support, or remove the image sources. +UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::VISUALBRIEFING::VISUALBRIEFINGASSISTANT::T2720475627"] = "Bilder werden vom ausgewählten Anbieter und Modell nicht unterstützt. Wählen Sie ein Modell mit Bildunterstützung aus oder entfernen Sie die Bildquellen." + -- Import as copy UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::VISUALBRIEFING::VISUALBRIEFINGASSISTANT::T2745663129"] = "Als Kopie importieren" diff --git a/app/MindWork AI Studio/Plugins/languages/en-us-97dfb1ba-50c4-4440-8dfa-6575daf543c8/plugin.lua b/app/MindWork AI Studio/Plugins/languages/en-us-97dfb1ba-50c4-4440-8dfa-6575daf543c8/plugin.lua index ebd90710..b269603a 100644 --- a/app/MindWork AI Studio/Plugins/languages/en-us-97dfb1ba-50c4-4440-8dfa-6575daf543c8/plugin.lua +++ b/app/MindWork AI Studio/Plugins/languages/en-us-97dfb1ba-50c4-4440-8dfa-6575daf543c8/plugin.lua @@ -2412,6 +2412,9 @@ UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::VISUALBRIEFING::VISUALBRIEFINGASSISTANT:: -- Creates a new version from the current sources and instructions while keeping the current structure and design. UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::VISUALBRIEFING::VISUALBRIEFINGASSISTANT::T2703645157"] = "Creates a new version from the current sources and instructions while keeping the current structure and design." +-- Images are not supported by the selected provider and model. Select a model with image support, or remove the image sources. +UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::VISUALBRIEFING::VISUALBRIEFINGASSISTANT::T2720475627"] = "Images are not supported by the selected provider and model. Select a model with image support, or remove the image sources." + -- Import as copy UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::VISUALBRIEFING::VISUALBRIEFINGASSISTANT::T2745663129"] = "Import as copy" diff --git a/app/MindWork AI Studio/Settings/ProviderExtensions.cs b/app/MindWork AI Studio/Settings/ProviderExtensions.cs index c1aa43b3..3d18e586 100644 --- a/app/MindWork AI Studio/Settings/ProviderExtensions.cs +++ b/app/MindWork AI Studio/Settings/ProviderExtensions.cs @@ -15,6 +15,23 @@ public static partial class ProviderExtensions return provider.CapabilityOverrides?.ApplyTo(automaticCapabilities) ?? automaticCapabilities; } + /// + /// Get whether the model used by the configured provider accepts images as input. + /// + /// + /// Two capabilities express image input, one for a single image and one for several. Anything that + /// wants to know whether an image may be sent has to accept both, which is why the question is asked + /// here instead of at each call site: attaching a file and validating an already attached file must + /// never disagree about it. + /// + /// The configured provider. + /// true when the model accepts image input. + public static bool SupportsImageInput(this Provider provider) + { + var capabilities = provider.GetModelCapabilities(); + return capabilities.Contains(Capability.SINGLE_IMAGE_INPUT) || capabilities.Contains(Capability.MULTIPLE_IMAGE_INPUT); + } + /// /// Get the capabilities of a model for a specific provider. /// diff --git a/app/MindWork AI Studio/Tools/Validation/FileExtensionValidation.cs b/app/MindWork AI Studio/Tools/Validation/FileExtensionValidation.cs index 2251ecd5..3ac4ade6 100644 --- a/app/MindWork AI Studio/Tools/Validation/FileExtensionValidation.cs +++ b/app/MindWork AI Studio/Tools/Validation/FileExtensionValidation.cs @@ -1,4 +1,3 @@ -using AIStudio.Provider; using AIStudio.Settings; using AIStudio.Tools.PluginSystem; using AIStudio.Tools.Rust; @@ -59,7 +58,6 @@ public static class FileExtensionValidation return false; } - var capabilities = provider?.GetModelCapabilities() ?? new(); if (FileTypes.IsAllowedPath(filePath, FileTypes.IMAGE)) { switch (useCae) @@ -76,8 +74,7 @@ public static class FileExtensionValidation return true; // In this use case, we can check the provider capabilities: - case UseCase.ATTACHING_CONTENT when capabilities.Contains(Capability.SINGLE_IMAGE_INPUT) || - capabilities.Contains(Capability.MULTIPLE_IMAGE_INPUT): + case UseCase.ATTACHING_CONTENT when provider?.SupportsImageInput() is true: return true; // We know that images are not supported: