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:
+46
-13
@@ -23,9 +23,10 @@ internal sealed class DefaultMessageTemplate : MessageTemplateBase
|
||||
if (messageContext.ChatMessage is not null)
|
||||
{
|
||||
var getRenderContents = messageContext.RenderContents();
|
||||
// Return a render fragment that checks visibility at render time
|
||||
// This is important because message contents may change during streaming
|
||||
return CreateRenderMessage(
|
||||
messageContext.ChatMessage.Role,
|
||||
messageContext.ChatMessage.MessageId,
|
||||
messageContext.ChatMessage,
|
||||
getRenderContents);
|
||||
}
|
||||
else
|
||||
@@ -44,29 +45,61 @@ internal sealed class DefaultMessageTemplate : MessageTemplateBase
|
||||
}
|
||||
|
||||
return CreateRenderMessage(
|
||||
this._buffer[0].Role,
|
||||
this._buffer[0].MessageId,
|
||||
this._buffer[0],
|
||||
getRenderContents);
|
||||
}
|
||||
}
|
||||
|
||||
/// <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.
|
||||
/// </summary>
|
||||
private static bool HasVisibleContent(ChatMessage message)
|
||||
{
|
||||
if (message.Contents.Count == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (var content in message.Contents)
|
||||
{
|
||||
// TextContent is visible
|
||||
if (content is TextContent textContent && !string.IsNullOrWhiteSpace(textContent.Text))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Other content types that are not function calls/results are visible
|
||||
if (content is not FunctionCallContent && content is not FunctionResultContent)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static RenderFragment CreateRenderMessage(
|
||||
ChatRole role,
|
||||
string? messageId,
|
||||
ChatMessage message,
|
||||
RenderFragment getRenderContents)
|
||||
{
|
||||
var roleClass = $"{role}-message";
|
||||
var roleClass = $"{message.Role}-message";
|
||||
return builder =>
|
||||
{
|
||||
// Check visibility at render time, not at template creation time
|
||||
// This is important because message contents may change during streaming
|
||||
if (!HasVisibleContent(message))
|
||||
{
|
||||
return; // Don't render messages without visible content
|
||||
}
|
||||
|
||||
builder.OpenElement(0, "div");
|
||||
if (!string.IsNullOrEmpty(messageId))
|
||||
if (!string.IsNullOrEmpty(message.MessageId))
|
||||
{
|
||||
builder.AddAttribute(1, "id", messageId);
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.AddAttribute(2, "class", $"chat-message {roleClass}");
|
||||
builder.AddAttribute(1, "id", message.MessageId);
|
||||
}
|
||||
builder.AddAttribute(2, "class", $"chat-message {roleClass}");
|
||||
builder.AddContent(3, getRenderContents);
|
||||
builder.CloseElement();
|
||||
};
|
||||
|
||||
@@ -79,15 +79,19 @@ internal sealed partial class MessageList : IComponent, IDisposable
|
||||
// Track all render keys to detect duplicates
|
||||
var allRenderKeys = new HashSet<string?>();
|
||||
|
||||
// Open container div for message list with flex layout
|
||||
builder.OpenElement(0, "div");
|
||||
builder.AddAttribute(1, "class", "messages-container");
|
||||
|
||||
foreach (var message in this.MessageListContext.AgentBoundaryContext.CompletedMessages)
|
||||
{
|
||||
var renderKey = GetUniqueRenderKey(message);
|
||||
|
||||
// Calling GetTemplate will stop template collection on the first message if it
|
||||
// was still ongoing.
|
||||
builder.OpenComponent<ContentBlock>(0);
|
||||
builder.OpenComponent<ContentBlock>(2);
|
||||
builder.SetKey(renderKey);
|
||||
builder.AddComponentParameter(1, "ChildContent", this.MessageListContext.GetTemplate(message));
|
||||
builder.AddComponentParameter(3, "ChildContent", this.MessageListContext.GetTemplate(message));
|
||||
builder.CloseComponent();
|
||||
}
|
||||
|
||||
@@ -95,11 +99,14 @@ internal sealed partial class MessageList : IComponent, IDisposable
|
||||
{
|
||||
var renderKey = GetUniqueRenderKey(message);
|
||||
|
||||
builder.OpenComponent<ContentBlock>(1);
|
||||
builder.OpenComponent<ContentBlock>(4);
|
||||
builder.SetKey(renderKey);
|
||||
builder.AddComponentParameter(1, "ChildContent", this.MessageListContext.GetTemplate(message));
|
||||
builder.AddComponentParameter(5, "ChildContent", this.MessageListContext.GetTemplate(message));
|
||||
builder.CloseComponent();
|
||||
}
|
||||
|
||||
// Close container div
|
||||
builder.CloseElement();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
+2
-25
@@ -55,35 +55,12 @@
|
||||
}
|
||||
|
||||
.chat-input-container {
|
||||
padding: 1.5rem 2rem 2rem;
|
||||
padding: 1rem 2rem 1.5rem;
|
||||
border-top: 1px solid #e5e5e5;
|
||||
background: white;
|
||||
}
|
||||
|
||||
::deep .agent-suggestions {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.5rem;
|
||||
justify-content: flex-start;
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
|
||||
::deep .suggestion-button {
|
||||
padding: 0.5rem 1rem;
|
||||
background: white;
|
||||
border: 1px solid #d1d1d1;
|
||||
border-radius: 1rem;
|
||||
cursor: pointer;
|
||||
font-size: 0.875rem;
|
||||
color: #424242;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
::deep .suggestion-button:hover {
|
||||
background: #f0f0f0;
|
||||
border-color: #0078d4;
|
||||
color: #0078d4;
|
||||
}
|
||||
|
||||
.agentic-chat-demo {
|
||||
height: 100%;
|
||||
@@ -92,6 +69,6 @@
|
||||
}
|
||||
|
||||
.chat-container {
|
||||
padding: 20px;
|
||||
padding: 0 2rem 1.5rem;
|
||||
border-top: 1px solid #e0e0e0;
|
||||
}
|
||||
|
||||
@@ -92,7 +92,6 @@ h1:focus {
|
||||
align-items: flex-end;
|
||||
gap: 12px;
|
||||
width: 100%;
|
||||
padding: 16px;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
@@ -200,7 +199,6 @@ h1:focus {
|
||||
.agent-loading-indicator {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
padding: 12px 16px;
|
||||
}
|
||||
|
||||
.agent-loading-indicator .agent-loading-dots {
|
||||
@@ -222,7 +220,7 @@ h1:focus {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
padding: 8px 16px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.agent-suggestions .suggestion-button {
|
||||
@@ -267,3 +265,45 @@ h1:focus {
|
||||
border-top: 1px solid #e5e7eb;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
/* Chat message styles */
|
||||
.messages-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.chat-message {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
max-width: 80%;
|
||||
padding: 12px 16px;
|
||||
border-radius: 8px;
|
||||
border: 1px solid #e5e7eb;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
/* User messages - right aligned with blue background */
|
||||
.chat-message.user-message {
|
||||
align-self: flex-end;
|
||||
background-color: #2563eb;
|
||||
color: white;
|
||||
border-color: #2563eb;
|
||||
}
|
||||
|
||||
/* Assistant messages - left aligned with light gray background */
|
||||
.chat-message.assistant-message {
|
||||
align-self: flex-start;
|
||||
background-color: #f3f4f6;
|
||||
color: #1f2937;
|
||||
border-color: #e5e7eb;
|
||||
}
|
||||
|
||||
/* Tool messages - left aligned, styled similar to assistant */
|
||||
.chat-message.tool-message {
|
||||
align-self: flex-start;
|
||||
background-color: #fef3c7;
|
||||
color: #92400e;
|
||||
border-color: #fcd34d;
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user