From 25cc7275f6f284358874dfb90656ecbcfd317efb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peer=20Sch=C3=BCtt?= <20603780+peerschuett@users.noreply.github.com> Date: Mon, 13 Apr 2026 10:58:43 +0200 Subject: [PATCH] The tool executes correctly and is displayed in the chat correctly. --- .../Assistants/I18N/allTexts.lua | 3 + .../Chat/ContentBlockComponent.razor | 137 ++++++++++-------- .../Chat/ContentBlockComponent.razor.cs | 24 ++- .../ToolDefaultsConfiguration.razor | 2 +- .../ToolDefaultsConfiguration.razor.cs | 4 + 5 files changed, 105 insertions(+), 65 deletions(-) diff --git a/app/MindWork AI Studio/Assistants/I18N/allTexts.lua b/app/MindWork AI Studio/Assistants/I18N/allTexts.lua index 44cef461..e1afa9bb 100644 --- a/app/MindWork AI Studio/Assistants/I18N/allTexts.lua +++ b/app/MindWork AI Studio/Assistants/I18N/allTexts.lua @@ -1705,6 +1705,9 @@ UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T1564757972"] = "Execute -- Yes, regenerate it UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T1603883875"] = "Yes, regenerate it" +-- No result +UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T1684269223"] = "No result" + -- Yes, remove it UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T1820166585"] = "Yes, remove it" diff --git a/app/MindWork AI Studio/Chat/ContentBlockComponent.razor b/app/MindWork AI Studio/Chat/ContentBlockComponent.razor index eb11ca50..4e0402bc 100644 --- a/app/MindWork AI Studio/Chat/ContentBlockComponent.razor +++ b/app/MindWork AI Studio/Chat/ContentBlockComponent.razor @@ -11,9 +11,27 @@ - - @this.Role.ToName() (@this.Time.LocalDateTime) - + + + @this.Role.ToName() (@this.Time.LocalDateTime) + + @if (this.HasToolTrace) + { + + + + + + + + + } + @if (this.Content.FileAttachments.Count > 0) @@ -96,17 +114,64 @@ } else { - @if (this.Role is ChatRole.AI && textContent.ToolInvocations.Count > 0) + @if (this.HasToolTrace && this.showToolTrace) { - - - @foreach (var toolIcon in this.GetDistinctToolIcons()) - { - - } - @this.GetToolTraceTooltip() - - + + + @string.Format(T("Tool Calls ({0})"), textContent.ToolInvocations.Count) + + @foreach (var invocation in textContent.ToolInvocations.OrderBy(x => x.Order)) + { + + + + + + @($"{invocation.Order}. {invocation.ToolName}") + + @this.GetTraceStatusText(invocation) + + + + + + + @if (this.IsToolInvocationExpanded(invocation.Order)) + { + @if (!string.IsNullOrWhiteSpace(invocation.StatusMessage)) + { + @invocation.StatusMessage + } + + @T("Result") + + @this.GetToolInvocationResult(invocation) + + + @T("Arguments") + @if (invocation.Arguments.Count == 0) + { + @T("No arguments") + } + else + { + + @foreach (var argument in invocation.Arguments) + { + + @argument.Key: @argument.Value + + } + + } + } + + } } @@ -136,52 +201,6 @@ @textContent.ToolRuntimeStatus.Message } - - @if (this.Role is ChatRole.AI && textContent.ToolInvocations.Count > 0 && this.showToolTrace) - { - - @string.Format(T("Tool Calls ({0})"), textContent.ToolInvocations.Count) - - @foreach (var invocation in textContent.ToolInvocations.OrderBy(x => x.Order)) - { - - - - @($"{invocation.Order}. {invocation.ToolName}") - - @this.GetTraceStatusText(invocation) - - - - @if (!string.IsNullOrWhiteSpace(invocation.StatusMessage)) - { - @invocation.StatusMessage - } - - @T("Arguments") - @if (invocation.Arguments.Count == 0) - { - @T("No arguments") - } - else - { - - @foreach (var argument in invocation.Arguments) - { - - @argument.Key: @argument.Value - - } - - } - - @T("Result") - - @invocation.Result - - - } - } } } } diff --git a/app/MindWork AI Studio/Chat/ContentBlockComponent.razor.cs b/app/MindWork AI Studio/Chat/ContentBlockComponent.razor.cs index 9e71cf83..84b41232 100644 --- a/app/MindWork AI Studio/Chat/ContentBlockComponent.razor.cs +++ b/app/MindWork AI Studio/Chat/ContentBlockComponent.razor.cs @@ -3,6 +3,7 @@ using AIStudio.Dialogs; using AIStudio.Tools.Services; using AIStudio.Tools.ToolCallingSystem; using Microsoft.AspNetCore.Components; +using MudBlazor; namespace AIStudio.Chat; @@ -105,6 +106,7 @@ public partial class ContentBlockComponent : MSGComponentBase, IAsyncDisposable private bool hasActiveMathContainer; private bool isDisposed; private bool showToolTrace; + private readonly HashSet expandedToolInvocations = []; #region Overrides of ComponentBase @@ -205,6 +207,9 @@ public partial class ContentBlockComponent : MSGComponentBase, IAsyncDisposable hash.Add(text.ToolRuntimeStatus.IsRunning); hash.Add(text.ToolRuntimeStatus.Message); hash.Add(this.showToolTrace); + hash.Add(this.expandedToolInvocations.Count); + foreach (var expandedInvocation in this.expandedToolInvocations.Order()) + hash.Add(expandedInvocation); foreach (var invocation in text.ToolInvocations) { hash.Add(invocation.Order); @@ -234,6 +239,8 @@ public partial class ContentBlockComponent : MSGComponentBase, IAsyncDisposable private string CardClasses => $"my-2 rounded-lg {this.Class}"; + private bool HasToolTrace => this.Role is ChatRole.AI && this.GetToolInvocations().Count > 0; + private CodeBlockTheme CodeColorPalette => this.SettingsManager.IsDarkMode ? CodeBlockTheme.Dark : CodeBlockTheme.Default; private static Color GetTraceColor(ToolInvocationTraceStatus status) => status switch @@ -256,11 +263,6 @@ public partial class ContentBlockComponent : MSGComponentBase, IAsyncDisposable ? textContent.ToolInvocations.OrderBy(x => x.Order).ToList() : []; - private IReadOnlyList GetDistinctToolIcons() => this.GetToolInvocations() - .Select(x => x.ToolIcon) - .Distinct(StringComparer.Ordinal) - .ToList(); - private string GetToolTraceTooltip() { var invocations = this.GetToolInvocations(); @@ -274,6 +276,18 @@ public partial class ContentBlockComponent : MSGComponentBase, IAsyncDisposable private void ToggleToolTrace() => this.showToolTrace = !this.showToolTrace; + private bool IsToolInvocationExpanded(int order) => this.expandedToolInvocations.Contains(order); + + private void ToggleToolInvocation(int order) + { + if (!this.expandedToolInvocations.Add(order)) + this.expandedToolInvocations.Remove(order); + } + + private string GetToolInvocationResult(ToolInvocationTrace invocation) => string.IsNullOrWhiteSpace(invocation.Result) + ? this.T("No result") + : invocation.Result; + private MudMarkdownStyling MarkdownStyling => new() { CodeBlock = { Theme = this.CodeColorPalette }, diff --git a/app/MindWork AI Studio/Components/ToolDefaultsConfiguration.razor b/app/MindWork AI Studio/Components/ToolDefaultsConfiguration.razor index c05fa480..be71c551 100644 --- a/app/MindWork AI Studio/Components/ToolDefaultsConfiguration.razor +++ b/app/MindWork AI Studio/Components/ToolDefaultsConfiguration.razor @@ -8,5 +8,5 @@ { } - + } diff --git a/app/MindWork AI Studio/Components/ToolDefaultsConfiguration.razor.cs b/app/MindWork AI Studio/Components/ToolDefaultsConfiguration.razor.cs index 03d40ca7..0fed200d 100644 --- a/app/MindWork AI Studio/Components/ToolDefaultsConfiguration.razor.cs +++ b/app/MindWork AI Studio/Components/ToolDefaultsConfiguration.razor.cs @@ -25,6 +25,10 @@ public partial class ToolDefaultsConfiguration : MSGComponentBase ? this.T("Choose which tools should be preselected for new chats.") : this.T("Choose which tools should be preselected for new runs of this assistant."); + private bool AreDefaultToolsDisabled => + this.Component is not AIStudio.Tools.Components.CHAT && + !this.SettingsManager.IsToolSelectionVisible(this.Component); + protected override async Task OnInitializedAsync() { this.availableTools = (await this.ToolRegistry.GetCatalogAsync(this.Component))