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))