mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
More UI cleanups
This commit is contained in:
+43
@@ -0,0 +1,43 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.Extensions.AI;
|
||||
|
||||
namespace Microsoft.AspNetCore.Components.AI;
|
||||
|
||||
/// <summary>
|
||||
/// Default template for rendering ErrorContent. Renders nothing by default
|
||||
/// to prevent the error from crashing the UI. More specific templates can
|
||||
/// override this to display error messages.
|
||||
/// </summary>
|
||||
public class ErrorTemplate : ContentTemplateBase
|
||||
{
|
||||
[CascadingParameter] internal MessageListContext Context { get; set; } = default!;
|
||||
|
||||
public override void Attach(RenderHandle renderHandle)
|
||||
{
|
||||
this.ChildContent = this.RenderError;
|
||||
}
|
||||
|
||||
public override Task SetParametersAsync(ParameterView parameters)
|
||||
{
|
||||
parameters.SetParameterProperties(this);
|
||||
this.Context.RegisterContentTemplate(this);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if this template should handle the given content.
|
||||
/// Matches ErrorContent.
|
||||
/// </summary>
|
||||
public override bool When(ContentContext context)
|
||||
{
|
||||
return context.Content is ErrorContent;
|
||||
}
|
||||
|
||||
private RenderFragment RenderError(ContentContext content) => builder =>
|
||||
{
|
||||
// By default, render nothing.
|
||||
// Specific templates can override to display error messages.
|
||||
};
|
||||
}
|
||||
+4
-28
@@ -35,7 +35,7 @@ public class FunctionCallTemplate : ContentTemplateBase
|
||||
/// </summary>
|
||||
/// <param name="context">The content context.</param>
|
||||
/// <returns>True if this template should render the content.</returns>
|
||||
public new bool When(ContentContext context)
|
||||
public override bool When(ContentContext context)
|
||||
{
|
||||
if (context.Content is not FunctionCallContent call)
|
||||
{
|
||||
@@ -53,32 +53,8 @@ public class FunctionCallTemplate : ContentTemplateBase
|
||||
|
||||
private RenderFragment RenderFunctionCall(ContentContext content) => builder =>
|
||||
{
|
||||
if (content.Content is FunctionCallContent call)
|
||||
{
|
||||
// Get or create the invocation context which tracks call and result
|
||||
var invocation = this.Context.GetOrCreateInvocation(call);
|
||||
|
||||
builder.OpenComponent<CascadingValue<InvocationContext>>(0);
|
||||
builder.AddComponentParameter(1, "Value", invocation);
|
||||
builder.AddComponentParameter(2, "IsFixed", true);
|
||||
builder.AddComponentParameter(3, "ChildContent", (RenderFragment)(innerBuilder =>
|
||||
{
|
||||
// Default fallback rendering - shows function name and loading/result status
|
||||
innerBuilder.OpenElement(0, "div");
|
||||
innerBuilder.AddAttribute(1, "class", "function-call");
|
||||
innerBuilder.AddContent(2, $"Function: {call.Name}");
|
||||
if (invocation.HasResult)
|
||||
{
|
||||
innerBuilder.AddContent(3, " [Result available]");
|
||||
}
|
||||
else
|
||||
{
|
||||
innerBuilder.AddContent(3, " [Loading...]");
|
||||
}
|
||||
|
||||
innerBuilder.CloseElement();
|
||||
}));
|
||||
builder.CloseComponent();
|
||||
}
|
||||
// By default, function calls are not rendered visually.
|
||||
// Custom templates (like WeatherCallTemplate) can override this
|
||||
// behavior for specific functions by registering before this template.
|
||||
};
|
||||
}
|
||||
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
using Microsoft.Extensions.AI;
|
||||
|
||||
namespace Microsoft.AspNetCore.Components.AI;
|
||||
|
||||
/// <summary>
|
||||
/// Default template for FunctionResultContent that renders nothing.
|
||||
/// Function results are internal tool responses and typically don't need
|
||||
/// visual representation in the chat UI.
|
||||
/// </summary>
|
||||
public class FunctionResultTemplate : ContentTemplateBase
|
||||
{
|
||||
[CascadingParameter] internal MessageListContext Context { get; set; } = default!;
|
||||
|
||||
public override void Attach(RenderHandle renderHandle)
|
||||
{
|
||||
// This component never renders anything by itself.
|
||||
this.ChildContent = this.RenderFunctionResult;
|
||||
}
|
||||
|
||||
public override Task SetParametersAsync(ParameterView parameters)
|
||||
{
|
||||
parameters.SetParameterProperties(this);
|
||||
this.Context.RegisterContentTemplate(this);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Only match FunctionResultContent.
|
||||
/// </summary>
|
||||
public override bool When(ContentContext context) => context.Content is FunctionResultContent;
|
||||
|
||||
private RenderFragment RenderFunctionResult(ContentContext content) => builder =>
|
||||
{
|
||||
// By default, function results are not rendered visually.
|
||||
// The result data is typically processed by the agent to generate text responses.
|
||||
};
|
||||
}
|
||||
@@ -21,6 +21,12 @@ public class TextTemplate : ContentTemplateBase
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Only match TextContent, allowing other content templates to handle
|
||||
/// FunctionCallContent, FunctionResultContent, etc.
|
||||
/// </summary>
|
||||
public override bool When(ContentContext context) => context.Content is TextContent;
|
||||
|
||||
private RenderFragment RenderText(ContentContext content) => builder =>
|
||||
{
|
||||
if (content.Content is TextContent textContent)
|
||||
|
||||
+14
-5
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
using Microsoft.Extensions.AI;
|
||||
|
||||
@@ -52,8 +52,10 @@ internal sealed class DefaultMessageTemplate : MessageTemplateBase
|
||||
|
||||
/// <summary>
|
||||
/// Checks if a message has any visible content that should be displayed.
|
||||
/// Messages that only contain FunctionCallContent or FunctionResultContent
|
||||
/// are internal tool messages and should not be rendered as chat bubbles.
|
||||
/// Messages that only contain FunctionResultContent are internal tool messages
|
||||
/// and should not be rendered as chat bubbles.
|
||||
/// FunctionCallContent is considered visible because content templates can render them
|
||||
/// (e.g., WeatherCallTemplate renders weather tool calls as cards).
|
||||
/// </summary>
|
||||
private static bool HasVisibleContent(ChatMessage message)
|
||||
{
|
||||
@@ -70,8 +72,15 @@ internal sealed class DefaultMessageTemplate : MessageTemplateBase
|
||||
return true;
|
||||
}
|
||||
|
||||
// Other content types that are not function calls/results are visible
|
||||
if (content is not FunctionCallContent && content is not FunctionResultContent)
|
||||
// FunctionCallContent is visible - content templates can render them
|
||||
// (e.g., WeatherCallTemplate renders weather tool calls as cards)
|
||||
if (content is FunctionCallContent)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Other content types that are not function results are visible
|
||||
if (content is not FunctionResultContent)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -27,6 +27,14 @@ public partial class Messages : IComponent
|
||||
{
|
||||
builder.OpenComponent<TextTemplate>(0);
|
||||
builder.CloseComponent();
|
||||
builder.OpenComponent<FunctionCallTemplate>(1);
|
||||
builder.CloseComponent();
|
||||
builder.OpenComponent<FunctionResultTemplate>(2);
|
||||
builder.CloseComponent();
|
||||
builder.OpenComponent<ErrorTemplate>(3);
|
||||
builder.CloseComponent();
|
||||
builder.OpenComponent<DataContentTemplate>(4);
|
||||
builder.CloseComponent();
|
||||
};
|
||||
|
||||
public void Attach(RenderHandle renderHandle)
|
||||
|
||||
+4
@@ -28,6 +28,10 @@
|
||||
<ContentTemplates>
|
||||
<TaskProgressTemplate />
|
||||
<TextTemplate />
|
||||
<FunctionCallTemplate />
|
||||
<FunctionResultTemplate />
|
||||
<ErrorTemplate />
|
||||
<DataContentTemplate />
|
||||
</ContentTemplates>
|
||||
</Messages>
|
||||
<AgentLoadingIndicator />
|
||||
|
||||
+5
@@ -20,7 +20,12 @@
|
||||
<div class="chat-content">
|
||||
<Messages>
|
||||
<ContentTemplates>
|
||||
<TextTemplate />
|
||||
<WeatherCallTemplate />
|
||||
<FunctionCallTemplate />
|
||||
<FunctionResultTemplate />
|
||||
<ErrorTemplate />
|
||||
<DataContentTemplate />
|
||||
</ContentTemplates>
|
||||
</Messages>
|
||||
<AgentLoadingIndicator />
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@ public class WeatherCallTemplate : ContentTemplateBase
|
||||
/// Determines if this template should handle the given content.
|
||||
/// Matches FunctionCallContent for the get_weather function.
|
||||
/// </summary>
|
||||
public new bool When(ContentContext context)
|
||||
public override bool When(ContentContext context)
|
||||
{
|
||||
// Only match FunctionCallContent for the get_weather function
|
||||
return context.Content is FunctionCallContent call &&
|
||||
|
||||
+4
@@ -24,6 +24,10 @@
|
||||
<ContentTemplates>
|
||||
<CreatePlanCallTemplate />
|
||||
<TextTemplate />
|
||||
<FunctionCallTemplate />
|
||||
<FunctionResultTemplate />
|
||||
<ErrorTemplate />
|
||||
<DataContentTemplate />
|
||||
</ContentTemplates>
|
||||
</Messages>
|
||||
<AgentLoadingIndicator />
|
||||
|
||||
+4
@@ -52,6 +52,10 @@
|
||||
<Messages>
|
||||
<ContentTemplates>
|
||||
<TextTemplate />
|
||||
<FunctionCallTemplate />
|
||||
<FunctionResultTemplate />
|
||||
<ErrorTemplate />
|
||||
<DataContentTemplate />
|
||||
</ContentTemplates>
|
||||
</Messages>
|
||||
<AgentLoadingIndicator />
|
||||
|
||||
+4
@@ -114,6 +114,10 @@
|
||||
<Messages>
|
||||
<ContentTemplates>
|
||||
<TextTemplate />
|
||||
<FunctionCallTemplate />
|
||||
<FunctionResultTemplate />
|
||||
<ErrorTemplate />
|
||||
<DataContentTemplate />
|
||||
</ContentTemplates>
|
||||
</Messages>
|
||||
<AgentLoadingIndicator />
|
||||
|
||||
+4
@@ -28,6 +28,10 @@
|
||||
<ContentTemplates>
|
||||
<HaikuCallTemplate />
|
||||
<TextTemplate />
|
||||
<FunctionCallTemplate />
|
||||
<FunctionResultTemplate />
|
||||
<ErrorTemplate />
|
||||
<DataContentTemplate />
|
||||
</ContentTemplates>
|
||||
</Messages>
|
||||
<AgentLoadingIndicator />
|
||||
|
||||
@@ -283,6 +283,11 @@ h1:focus {
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
/* Hide empty message bubbles (e.g., function calls with no visual template) */
|
||||
.chat-message:empty {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* User messages - right aligned with blue background */
|
||||
.chat-message.user-message {
|
||||
align-self: flex-end;
|
||||
|
||||
Reference in New Issue
Block a user