added a descriptive list component

This commit is contained in:
krut_ni 2026-02-10 17:06:45 +01:00
parent bc50b3728c
commit de1cf650f4
8 changed files with 120 additions and 2 deletions

View File

@ -64,5 +64,24 @@
<MudText Typo="Typo.body1" Class="mb-3">@text.Content</MudText> <MudText Typo="Typo.body1" Class="mb-3">@text.Content</MudText>
} }
break; break;
case AssistantUiCompontentType.LIST:
if (component is AssistantList assistantList)
{
var list = assistantList;
<MudList T="string" Class="mb-6">
@foreach (var item in list.Items)
{
@if (item.Type == "LINK")
{
<MudListItem T="string" Icon="@Icons.Material.Filled.Link" Target="_blank" Href="@item.Href">@item.Text</MudListItem>
}
else
{
<MudListItem T="string">@item.Text</MudListItem>
}
}
</MudList>
}
break;
} }
} }

View File

@ -109,14 +109,30 @@ ASSISTANT = {
{ {
["Type"] = "HEADING", -- descriptive component for headings ["Type"] = "HEADING", -- descriptive component for headings
["Props"] = { ["Props"] = {
["Text"] = "This is a Section Heading", -- The heading text ["Text"] = "<heading content>", -- required
["Level"] = 2 -- Heading level, 1 - 3 ["Level"] = 2 -- Heading level, 1 - 3
} }
}, },
{ {
["Type"] = "TEXT", -- descriptive component for normal text ["Type"] = "TEXT", -- descriptive component for normal text
["Props"] = { ["Props"] = {
["Content"] = "This is a paragraph of descriptive text that explains something about the assistant or provides additional information." ["Content"] = "<text content>"
}
},
{
["Type"] = "LIST", -- descriptive list component
["Props"] = {
["Items"] = {
{
["Type"] = "LINK", -- required
["Text"] = "<user readable link text>",
["Href"] = "<link>" -- required
},
{
["Type"] = "TEXT", -- required
["Text"] = "<user readable text>"
}
}
} }
}, },
} }

View File

@ -29,6 +29,8 @@ public class AssistantComponentFactory
return new AssistantHeading { Props = props, Children = children }; return new AssistantHeading { Props = props, Children = children };
case AssistantUiCompontentType.TEXT: case AssistantUiCompontentType.TEXT:
return new AssistantText { Props = props, Children = children }; return new AssistantText { Props = props, Children = children };
case AssistantUiCompontentType.LIST:
return new AssistantList { Props = props, Children = children };
default: default:
LOGGER.LogError($"Unknown assistant component type!\n{type} is not a supported assistant component type"); LOGGER.LogError($"Unknown assistant component type!\n{type} is not a supported assistant component type");
throw new Exception($"Unknown assistant component type: {type}"); throw new Exception($"Unknown assistant component type: {type}");

View File

@ -0,0 +1,18 @@
namespace AIStudio.Tools.PluginSystem.Assistants.DataModel;
public class AssistantList : AssistantComponentBase
{
public override AssistantUiCompontentType Type => AssistantUiCompontentType.LIST;
public Dictionary<string, object> Props { get; set; } = new();
public List<IAssistantComponent> Children { get; set; } = new();
public List<AssistantListItem> Items
{
get => this.Props.TryGetValue(nameof(this.Items), out var v) && v is List<AssistantListItem> list
? list
: [];
set => this.Props[nameof(this.Items)] = value;
}
}

View File

@ -0,0 +1,8 @@
namespace AIStudio.Tools.PluginSystem.Assistants.DataModel;
public class AssistantListItem
{
public string Type { get; set; } = "TEXT";
public string Text { get; set; } = string.Empty;
public string? Href { get; set; }
}

View File

@ -10,4 +10,5 @@ public enum AssistantUiCompontentType
SWITCH, SWITCH,
HEADING, HEADING,
TEXT, TEXT,
LIST,
} }

View File

@ -37,5 +37,9 @@ public static class ComponentPropSpecs
required: ["Content"], required: ["Content"],
optional: [] optional: []
), ),
[AssistantUiCompontentType.LIST] = new(
required: ["Items"],
optional: []
),
}; };
} }

View File

@ -274,6 +274,12 @@ public sealed class PluginAssistants(bool isInternal, LuaState state, PluginType
return true; return true;
} }
if (val.TryRead<LuaTable>(out var listItemListTable) && this.TryParseListItemList(listItemListTable, out var listItemList))
{
result = listItemList;
return true;
}
result = null!; result = null!;
return false; return false;
} }
@ -316,4 +322,48 @@ public sealed class PluginAssistants(bool isInternal, LuaState state, PluginType
return true; return true;
} }
private bool TryParseListItem(LuaTable table, out AssistantListItem item)
{
item = new AssistantListItem();
if (!table.TryGetValue("Text", out var textVal) || !textVal.TryRead<string>(out var text))
return false;
if (!table.TryGetValue("Type", out var typeVal) || !typeVal.TryRead<string>(out var type))
return false;
item.Text = text;
item.Type = type;
if (table.TryGetValue("Href", out var hrefVal) && hrefVal.TryRead<string>(out var href))
{
item.Href = href;
}
return true;
}
private bool TryParseListItemList(LuaTable table, out List<AssistantListItem> items)
{
items = new List<AssistantListItem>();
var length = table.ArrayLength;
for (var i = 1; i <= length; i++)
{
var value = table[i];
if (value.TryRead<LuaTable>(out var subTable) && this.TryParseListItem(subTable, out var item))
{
items.Add(item);
}
else
{
items = null!;
return false;
}
}
return true;
}
} }