From a5088d74c887726dfeaf7c8e6c8062631b888f5e Mon Sep 17 00:00:00 2001 From: Thorsten Sommer Date: Tue, 14 Jul 2026 18:42:48 +0200 Subject: [PATCH] Fixed media transcription state handling --- .../Assistants/AssistantBase.razor.cs | 3 ++ .../DocumentAnalysisAssistant.razor | 6 ++-- .../DocumentAnalysisAssistant.razor.cs | 11 +++++++ .../Components/AttachDocuments.razor.cs | 32 ++++++++++++++++--- .../Components/ReadFileContent.razor.cs | 9 ++++-- .../Dialogs/ConfirmDialog.razor | 13 ++++++-- .../Dialogs/ConfirmDialog.razor.cs | 6 ++++ .../Layout/MainLayout.razor.cs | 29 ++++++++++++++--- .../plugin.lua | 24 ++++++++++++++ .../plugin.lua | 24 ++++++++++++++ app/MindWork AI Studio/Tools/Markdown.cs | 24 ++++++++++++++ .../wwwroot/changelog/v26.7.3.md | 5 +-- 12 files changed, 168 insertions(+), 18 deletions(-) diff --git a/app/MindWork AI Studio/Assistants/AssistantBase.razor.cs b/app/MindWork AI Studio/Assistants/AssistantBase.razor.cs index 172b27b8..ec728fb9 100644 --- a/app/MindWork AI Studio/Assistants/AssistantBase.razor.cs +++ b/app/MindWork AI Studio/Assistants/AssistantBase.razor.cs @@ -150,6 +150,9 @@ public abstract partial class AssistantBase : AssistantLowerBase wher /// protected bool HasAssistantSession => this.assistantSessionId is not null; + /// Gets whether this assistant currently owns active media work. + protected bool IsMediaImportBusy => this.MediaTranscriptionService.IsBusy(this.CurrentMediaImportOwner); + /// /// Gets the assistant-specific identifier used to distinguish session slots. /// diff --git a/app/MindWork AI Studio/Assistants/DocumentAnalysis/DocumentAnalysisAssistant.razor b/app/MindWork AI Studio/Assistants/DocumentAnalysis/DocumentAnalysisAssistant.razor index 89f8e04c..be60a4c8 100644 --- a/app/MindWork AI Studio/Assistants/DocumentAnalysis/DocumentAnalysisAssistant.razor +++ b/app/MindWork AI Studio/Assistants/DocumentAnalysis/DocumentAnalysisAssistant.razor @@ -21,7 +21,7 @@ } else { - + @foreach (var policy in this.SettingsManager.ConfigurationData.DocumentAnalysis.Policies) { @if (policy.IsEnterpriseConfiguration) @@ -44,10 +44,10 @@ else } - + @T("Add policy") - + @T("Delete this policy") diff --git a/app/MindWork AI Studio/Assistants/DocumentAnalysis/DocumentAnalysisAssistant.razor.cs b/app/MindWork AI Studio/Assistants/DocumentAnalysis/DocumentAnalysisAssistant.razor.cs index 436c5c4d..d896d315 100644 --- a/app/MindWork AI Studio/Assistants/DocumentAnalysis/DocumentAnalysisAssistant.razor.cs +++ b/app/MindWork AI Studio/Assistants/DocumentAnalysis/DocumentAnalysisAssistant.razor.cs @@ -333,9 +333,14 @@ public partial class DocumentAnalysisAssistant : AssistantBaseCore this.selectedPolicy is null || this.selectedPolicy.IsProtected; private bool IsNoPolicySelected => this.selectedPolicy is null; + + private bool ArePolicyControlsDisabled => this.IsProcessing || this.IsMediaImportBusy; private void SelectedPolicyChanged(DataDocumentAnalysisPolicy? policy) { + if (this.ArePolicyControlsDisabled) + return; + this.selectedPolicy = policy; this.ResetForm(); this.policyDefinitionExpanded = !this.selectedPolicy?.IsProtected ?? true; @@ -353,6 +358,9 @@ public partial class DocumentAnalysisAssistant : AssistantBaseCoreRehydrates results after the component is assigned another chat or target. + protected override async Task OnParametersSetAsync() + { + await base.OnParametersSetAsync(); await this.SyncCompletedMediaAttachmentsAsync(); } @@ -168,11 +174,24 @@ public partial class AttachDocuments : MSGComponentBase var completed = delivery?.Attachments ?? []; var pending = this.OwnerChat?.PendingMediaTranscripts ?? []; var changed = false; + var ownerPendingChanged = false; foreach (var attachment in completed.Concat(pending)) changed |= this.DocumentPaths.Add(attachment); - if (changed) + if (this.OwnerChat is not null) + { + foreach (var attachment in completed.OfType()) + { + if (this.OwnerChat.PendingMediaTranscripts.All(existing => existing.FilePath != attachment.FilePath)) + { + this.OwnerChat.PendingMediaTranscripts.Add(attachment); + ownerPendingChanged = true; + } + } + } + + if (changed || ownerPendingChanged) { await this.DocumentPathsChanged.InvokeAsync(this.DocumentPaths); await this.OnChange(this.DocumentPaths); @@ -410,12 +429,17 @@ public partial class AttachDocuments : MSGComponentBase return; } - var names = string.Join(Environment.NewLine, mediaPaths.Select(path => $"• {Path.GetFileName(path)}")); + var names = string.Join('\n', mediaPaths.Select(path => $"- {Markdown.EscapeInlineText(Path.GetFileName(path))}")); + var message = this.T("The selected audio and video files will be prepared locally. Their audio will then be uploaded to the configured transcription provider."); var dialogParameters = new DialogParameters { { - x => x.Message, - $"{this.T("The selected audio and video files will be prepared locally. Their audio will then be uploaded to the configured transcription provider.")}{Environment.NewLine}{Environment.NewLine}{names}" + x => x.MarkdownBody, + $""" + {message} + + {names} + """ }, }; diff --git a/app/MindWork AI Studio/Components/ReadFileContent.razor.cs b/app/MindWork AI Studio/Components/ReadFileContent.razor.cs index 53e40de6..5d412f57 100644 --- a/app/MindWork AI Studio/Components/ReadFileContent.razor.cs +++ b/app/MindWork AI Studio/Components/ReadFileContent.razor.cs @@ -290,11 +290,16 @@ public partial class ReadFileContent : MSGComponentBase return false; } + var message = this.T("The selected media file will be prepared locally. Its audio will then be uploaded to the configured transcription provider."); var dialogParameters = new DialogParameters { { - x => x.Message, - $"{this.T("The selected media file will be prepared locally. Its audio will then be uploaded to the configured transcription provider.")}{Environment.NewLine}{Environment.NewLine}{Path.GetFileName(filePath)}" + x => x.MarkdownBody, + $""" + {message} + + - {Markdown.EscapeInlineText(Path.GetFileName(filePath))} + """ }, }; var dialogReference = await this.DialogService.ShowAsync( diff --git a/app/MindWork AI Studio/Dialogs/ConfirmDialog.razor b/app/MindWork AI Studio/Dialogs/ConfirmDialog.razor index 9e55a4b3..6f48c798 100644 --- a/app/MindWork AI Studio/Dialogs/ConfirmDialog.razor +++ b/app/MindWork AI Studio/Dialogs/ConfirmDialog.razor @@ -1,9 +1,16 @@ @inherits MSGComponentBase - - @this.Message - + @if (!string.IsNullOrWhiteSpace(this.MarkdownBody)) + { + + } + else + { + + @this.Message + + } diff --git a/app/MindWork AI Studio/Dialogs/ConfirmDialog.razor.cs b/app/MindWork AI Studio/Dialogs/ConfirmDialog.razor.cs index f022152e..696d6fa4 100644 --- a/app/MindWork AI Studio/Dialogs/ConfirmDialog.razor.cs +++ b/app/MindWork AI Studio/Dialogs/ConfirmDialog.razor.cs @@ -15,6 +15,12 @@ public partial class ConfirmDialog : MSGComponentBase [Parameter] public string Message { get; set; } = string.Empty; + /// + /// Optional Markdown content rendered instead of using the message property. + /// + [Parameter] + public string MarkdownBody { get; set; } = string.Empty; + private void Cancel() => this.MudDialog.Cancel(); private void Confirm() => this.MudDialog.Close(DialogResult.Ok(true)); diff --git a/app/MindWork AI Studio/Layout/MainLayout.razor.cs b/app/MindWork AI Studio/Layout/MainLayout.razor.cs index 2bac1fd8..ad0bf3e5 100644 --- a/app/MindWork AI Studio/Layout/MainLayout.razor.cs +++ b/app/MindWork AI Studio/Layout/MainLayout.razor.cs @@ -3,6 +3,7 @@ using AIStudio.Settings; using AIStudio.Settings.DataModel; using AIStudio.Tools.AIJobs; using AIStudio.Tools.AssistantSessions; +using AIStudio.Tools.Media; using AIStudio.Tools.PluginSystem; using AIStudio.Tools.Rust; using AIStudio.Tools.Services; @@ -37,6 +38,9 @@ public partial class MainLayout : LayoutComponentBase, IMessageBusReceiver, ILan [Inject] private AssistantSessionService AssistantSessionService { get; init; } = null!; + + [Inject] + private MediaTranscriptionService MediaTranscriptionService { get; init; } = null!; [Inject] private ISnackbar Snackbar { get; init; } = null!; @@ -75,6 +79,7 @@ public partial class MainLayout : LayoutComponentBase, IMessageBusReceiver, ILan protected override async Task OnInitializedAsync() { this.NavigationManager.RegisterLocationChangingHandler(this.OnLocationChanging); + this.MediaTranscriptionService.StateChanged += this.OnMediaImportStateChanged; // // We use the Tauri API (Rust) to get the data and config directories @@ -348,6 +353,16 @@ public partial class MainLayout : LayoutComponentBase, IMessageBusReceiver, ILan { this.navItems = new List(this.GetNavItems()); } + + /// Refreshes navigation activity colors when a media import changes state. + private void OnMediaImportStateChanged(MediaImportOwner owner) + { + _ = this.InvokeAsync(() => + { + this.LoadNavItems(); + this.StateHasChanged(); + }); + } private IEnumerable GetNavItems() { @@ -356,10 +371,15 @@ public partial class MainLayout : LayoutComponentBase, IMessageBusReceiver, ILan var activityIndicatorDarkColor = this.ColorTheme.GetActivityIndicatorDarkColor(); var defaultLightColor = palette.DarkLighten; var defaultDarkColor = palette.GrayLight; - var chatLightColor = this.AIJobService.HasActiveJobs ? activityIndicatorLightColor : defaultLightColor; - var chatDarkColor = this.AIJobService.HasActiveJobs ? activityIndicatorDarkColor : defaultDarkColor; - var assistantsLightColor = this.AssistantSessionService.HasActiveSessions ? activityIndicatorLightColor : defaultLightColor; - var assistantsDarkColor = this.AssistantSessionService.HasActiveSessions ? activityIndicatorDarkColor : defaultDarkColor; + var mediaSnapshots = this.MediaTranscriptionService.GetSnapshots(); + var hasActiveChatMedia = mediaSnapshots.Any(snapshot => snapshot.IsBusy && snapshot.Owner.Kind is MediaImportOwnerKind.CHAT); + var hasActiveAssistantMedia = mediaSnapshots.Any(snapshot => snapshot.IsBusy && snapshot.Owner.Kind is MediaImportOwnerKind.ASSISTANT); + var hasActiveChatWork = this.AIJobService.HasActiveJobs || hasActiveChatMedia; + var hasActiveAssistantWork = this.AssistantSessionService.HasActiveSessions || hasActiveAssistantMedia; + var chatLightColor = hasActiveChatWork ? activityIndicatorLightColor : defaultLightColor; + var chatDarkColor = hasActiveChatWork ? activityIndicatorDarkColor : defaultDarkColor; + var assistantsLightColor = hasActiveAssistantWork ? activityIndicatorLightColor : defaultLightColor; + var assistantsDarkColor = hasActiveAssistantWork ? activityIndicatorDarkColor : defaultDarkColor; yield return new(T("Home"), Icons.Material.Filled.Home, defaultLightColor, defaultDarkColor, Routes.HOME, true); yield return new(T("Chat"), Icons.Material.Filled.Chat, chatLightColor, chatDarkColor, Routes.CHAT, false); @@ -535,6 +555,7 @@ public partial class MainLayout : LayoutComponentBase, IMessageBusReceiver, ILan public void Dispose() { + this.MediaTranscriptionService.StateChanged -= this.OnMediaImportStateChanged; this.MessageBus.Unregister(this); this.mandatoryInfoDialogSemaphore.Dispose(); } 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 4534aaae..59087c7a 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 @@ -306,6 +306,9 @@ UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::AGENDA::NUMBERPARTICIPANTSEXTENSIONS::T81 -- Stop generation UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::ASSISTANTBASE::T1317408357"] = "Generierung stoppen" +-- The media file could not be transcribed. +UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::ASSISTANTBASE::T1543974632"] = "Die Mediendatei konnte nicht transkribiert werden." + -- Reset UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::ASSISTANTBASE::T180921696"] = "Zurücksetzen" @@ -315,6 +318,9 @@ UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::ASSISTANTBASE::T1809312323"] = "Bitte wä -- The assistant failed. The message is: '{0}' UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::ASSISTANTBASE::T1833836281"] = "Der Assistent ist fehlgeschlagen. Die Meldung lautet: „{0}“" +-- The media transcription was canceled. +UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::ASSISTANTBASE::T241403726"] = "Die Transkription des Mediums wurde abgebrochen." + -- This assistant is already running. AI Studio opens the running session instead. UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::ASSISTANTBASE::T2575715765"] = "Dieser Assistent läuft bereits. AI Studio öffnet stattdessen die laufende Sitzung." @@ -2412,6 +2418,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::ATTACHDOCUMENTS::T1358313858"] = "Klicken -- Drop files here to attach them. UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::ATTACHDOCUMENTS::T143112277"] = "Dateien hier ablegen, um sie anzuhängen." +-- The media file could not be transcribed. +UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::ATTACHDOCUMENTS::T1543974632"] = "Die Mediendatei konnte nicht transkribiert werden." + -- Click here to attach files. UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::ATTACHDOCUMENTS::T1875575968"] = "Klicken Sie hier, um Dateien anzuhängen." @@ -2421,6 +2430,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::ATTACHDOCUMENTS::T2178031033"] = "Mediend -- Drag and drop files into the marked area or click here to attach documents: UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::ATTACHDOCUMENTS::T230755331"] = "Ziehen Sie Dateien in den markierten Bereich oder klicken Sie hier, um Dokumente anzuhängen:" +-- The media transcription was canceled. +UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::ATTACHDOCUMENTS::T241403726"] = "Die Transkription des Mediums wurde abgebrochen." + -- Select files to attach UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::ATTACHDOCUMENTS::T2495931372"] = "Dateien zum Anhängen auswählen" @@ -2457,6 +2469,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T1317408357"] = "Generieru -- Save chat UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T1516264254"] = "Chat speichern" +-- The media file could not be transcribed. +UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T1543974632"] = "Die Mediendatei konnte nicht transkribiert werden." + -- Type your input here... UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T1849313532"] = "Geben Sie hier Ihre Eingabe ein..." @@ -2469,6 +2484,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T2036185364"] = "Code" -- Italic UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T2377171085"] = "Kursiv" +-- The media transcription was canceled. +UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T241403726"] = "Die Transkription der Mediendatei wurde abgebrochen." + -- Profile usage is disabled according to your chat template settings. UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T2670286472"] = "Die Profilnutzung ist gemäß den Einstellungen ihrer Chat-Vorlage deaktiviert." @@ -2829,12 +2847,18 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::PROVIDERSELECTION::T4279448758"] = "Nutzt -- Provider UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::PROVIDERSELECTION::T900237532"] = "Anbieter" +-- The media file could not be transcribed. +UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::READFILECONTENT::T1543974632"] = "Die Mediendatei konnte nicht transkribiert werden." + -- Failed to load file content UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::READFILECONTENT::T1989554334"] = "Laden des Dateiinhalts fehlgeschlagen" -- Drop one file here to load its content. UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::READFILECONTENT::T2274562398"] = "Datei hier ablegen, um ihren Inhalt zu laden." +-- The media transcription was canceled. +UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::READFILECONTENT::T241403726"] = "Die Transkription des Mediums wurde abgebrochen." + -- The selected media file will be prepared locally. Its audio will then be uploaded to the configured transcription provider. UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::READFILECONTENT::T2839709466"] = "Die ausgewählte Mediendatei wird lokal vorbereitet. Anschließend wird die Audiospur an den konfigurierten Transkriptionsanbieter hochgeladen." 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 d46812b9..083860e9 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 @@ -306,6 +306,9 @@ UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::AGENDA::NUMBERPARTICIPANTSEXTENSIONS::T81 -- Stop generation UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::ASSISTANTBASE::T1317408357"] = "Stop generation" +-- The media file could not be transcribed. +UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::ASSISTANTBASE::T1543974632"] = "The media file could not be transcribed." + -- Reset UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::ASSISTANTBASE::T180921696"] = "Reset" @@ -315,6 +318,9 @@ UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::ASSISTANTBASE::T1809312323"] = "Please se -- The assistant failed. The message is: '{0}' UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::ASSISTANTBASE::T1833836281"] = "The assistant failed. The message is: '{0}'" +-- The media transcription was canceled. +UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::ASSISTANTBASE::T241403726"] = "The media transcription was canceled." + -- This assistant is already running. AI Studio opens the running session instead. UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::ASSISTANTBASE::T2575715765"] = "This assistant is already running. AI Studio opens the running session instead." @@ -2412,6 +2418,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::ATTACHDOCUMENTS::T1358313858"] = "Click t -- Drop files here to attach them. UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::ATTACHDOCUMENTS::T143112277"] = "Drop files here to attach them." +-- The media file could not be transcribed. +UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::ATTACHDOCUMENTS::T1543974632"] = "The media file could not be transcribed." + -- Click here to attach files. UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::ATTACHDOCUMENTS::T1875575968"] = "Click here to attach files." @@ -2421,6 +2430,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::ATTACHDOCUMENTS::T2178031033"] = "Transcr -- Drag and drop files into the marked area or click here to attach documents: UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::ATTACHDOCUMENTS::T230755331"] = "Drag and drop files into the marked area or click here to attach documents:" +-- The media transcription was canceled. +UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::ATTACHDOCUMENTS::T241403726"] = "The media transcription was canceled." + -- Select files to attach UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::ATTACHDOCUMENTS::T2495931372"] = "Select files to attach" @@ -2457,6 +2469,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T1317408357"] = "Stop gene -- Save chat UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T1516264254"] = "Save chat" +-- The media file could not be transcribed. +UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T1543974632"] = "The media file could not be transcribed." + -- Type your input here... UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T1849313532"] = "Type your input here..." @@ -2469,6 +2484,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T2036185364"] = "Code" -- Italic UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T2377171085"] = "Italic" +-- The media transcription was canceled. +UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T241403726"] = "The media transcription was canceled." + -- Profile usage is disabled according to your chat template settings. UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T2670286472"] = "Profile usage is disabled according to your chat template settings." @@ -2829,12 +2847,18 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::PROVIDERSELECTION::T4279448758"] = "Uses -- Provider UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::PROVIDERSELECTION::T900237532"] = "Provider" +-- The media file could not be transcribed. +UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::READFILECONTENT::T1543974632"] = "The media file could not be transcribed." + -- Failed to load file content UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::READFILECONTENT::T1989554334"] = "Failed to load file content" -- Drop one file here to load its content. UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::READFILECONTENT::T2274562398"] = "Drop one file here to load its content." +-- The media transcription was canceled. +UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::READFILECONTENT::T241403726"] = "The media transcription was canceled." + -- The selected media file will be prepared locally. Its audio will then be uploaded to the configured transcription provider. UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::READFILECONTENT::T2839709466"] = "The selected media file will be prepared locally. Its audio will then be uploaded to the configured transcription provider." diff --git a/app/MindWork AI Studio/Tools/Markdown.cs b/app/MindWork AI Studio/Tools/Markdown.cs index e1f87d9c..c523795b 100644 --- a/app/MindWork AI Studio/Tools/Markdown.cs +++ b/app/MindWork AI Studio/Tools/Markdown.cs @@ -34,6 +34,30 @@ public static class Markdown } }; + /// Escapes arbitrary text for literal display inside Markdown. + public static string EscapeInlineText(string value) + { + if (string.IsNullOrEmpty(value)) + return string.Empty; + + var escaped = new StringBuilder(value.Length); + foreach (var character in value) + { + if (character is '\r' or '\n' or '\t' || char.IsControl(character)) + { + escaped.Append(' '); + continue; + } + + if (character is >= '!' and <= '/' or >= ':' and <= '@' or >= '[' and <= '`' or >= '{' and <= '~') + escaped.Append('\\'); + + escaped.Append(character); + } + + return escaped.ToString(); + } + public static string RemoveSharedIndentation(string value) { if (string.IsNullOrWhiteSpace(value)) diff --git a/app/MindWork AI Studio/wwwroot/changelog/v26.7.3.md b/app/MindWork AI Studio/wwwroot/changelog/v26.7.3.md index 5537ead0..0bed101c 100644 --- a/app/MindWork AI Studio/wwwroot/changelog/v26.7.3.md +++ b/app/MindWork AI Studio/wwwroot/changelog/v26.7.3.md @@ -3,9 +3,10 @@ - Added audio and video transcription for chats and assistants. AI Studio now prepares supported media locally, sends only normalized audio to the configured transcription provider, and attaches the resulting transcript instead of the original media. - Improved the "My Tasks Assistant": you can now provide one or more documents in addition to text or use documents alone when asking to identify tasks. - Improved update guidance for Flatpak installations and added an enterprise option that lets organizations manage updates entirely through their IT department. -- Fixed an issue that could leave AI Studio unresponsive after waking the computer from sleep. -- Fixed enterprise configuration plugins from Windows-created ZIP files not loading correctly on Linux when the ZIP contained plugin files inside a folder. +- Fixed an issue that could leave AI Studio unresponsive after waking the computer from sleep. Yes, we know this was an annoying bug, and we apologize for the inconvenience. +- Fixed enterprise configuration plugins from Windows-created ZIP files may not load correctly on Linux when the ZIP contained plugin files inside a folder. - Fixed voice recording not starting on Linux. +- Fixed being able to switch document analysis policies while an analysis or media transcription was still in progress. - Upgraded Rust to v1.97.0. - Upgraded Tauri to v2.11.5. - Upgraded common dependencies. \ No newline at end of file