diff --git a/app/MindWork AI Studio/Assistants/Dynamic/AssistantDynamic.razor b/app/MindWork AI Studio/Assistants/Dynamic/AssistantDynamic.razor index a138dc5b..6f7e91b2 100644 --- a/app/MindWork AI Studio/Assistants/Dynamic/AssistantDynamic.razor +++ b/app/MindWork AI Studio/Assistants/Dynamic/AssistantDynamic.razor @@ -64,5 +64,24 @@ @text.Content } break; + case AssistantUiCompontentType.LIST: + if (component is AssistantList assistantList) + { + var list = assistantList; + + @foreach (var item in list.Items) + { + @if (item.Type == "LINK") + { + @item.Text + } + else + { + @item.Text + } + } + + } + break; } } \ No newline at end of file diff --git a/app/MindWork AI Studio/Plugins/assistants/plugin.lua b/app/MindWork AI Studio/Plugins/assistants/plugin.lua index ca1b6d53..38c46b4a 100644 --- a/app/MindWork AI Studio/Plugins/assistants/plugin.lua +++ b/app/MindWork AI Studio/Plugins/assistants/plugin.lua @@ -109,14 +109,30 @@ ASSISTANT = { { ["Type"] = "HEADING", -- descriptive component for headings ["Props"] = { - ["Text"] = "This is a Section Heading", -- The heading text + ["Text"] = "", -- required ["Level"] = 2 -- Heading level, 1 - 3 } }, { ["Type"] = "TEXT", -- descriptive component for normal text ["Props"] = { - ["Content"] = "This is a paragraph of descriptive text that explains something about the assistant or provides additional information." + ["Content"] = "" + } + }, + { + ["Type"] = "LIST", -- descriptive list component + ["Props"] = { + ["Items"] = { + { + ["Type"] = "LINK", -- required + ["Text"] = "", + ["Href"] = "" -- required + }, + { + ["Type"] = "TEXT", -- required + ["Text"] = "" + } + } } }, } diff --git a/app/MindWork AI Studio/Tools/PluginSystem/Assistants/AssistantComponentFactory.cs b/app/MindWork AI Studio/Tools/PluginSystem/Assistants/AssistantComponentFactory.cs index 32f50c40..5dc67e7d 100644 --- a/app/MindWork AI Studio/Tools/PluginSystem/Assistants/AssistantComponentFactory.cs +++ b/app/MindWork AI Studio/Tools/PluginSystem/Assistants/AssistantComponentFactory.cs @@ -29,6 +29,8 @@ public class AssistantComponentFactory return new AssistantHeading { Props = props, Children = children }; case AssistantUiCompontentType.TEXT: return new AssistantText { Props = props, Children = children }; + case AssistantUiCompontentType.LIST: + return new AssistantList { Props = props, Children = children }; default: LOGGER.LogError($"Unknown assistant component type!\n{type} is not a supported assistant component type"); throw new Exception($"Unknown assistant component type: {type}"); diff --git a/app/MindWork AI Studio/Tools/PluginSystem/Assistants/DataModel/AssistantList.cs b/app/MindWork AI Studio/Tools/PluginSystem/Assistants/DataModel/AssistantList.cs new file mode 100644 index 00000000..f44cbf3d --- /dev/null +++ b/app/MindWork AI Studio/Tools/PluginSystem/Assistants/DataModel/AssistantList.cs @@ -0,0 +1,18 @@ +namespace AIStudio.Tools.PluginSystem.Assistants.DataModel; + +public class AssistantList : AssistantComponentBase +{ + public override AssistantUiCompontentType Type => AssistantUiCompontentType.LIST; + + public Dictionary Props { get; set; } = new(); + + public List Children { get; set; } = new(); + + public List Items + { + get => this.Props.TryGetValue(nameof(this.Items), out var v) && v is List list + ? list + : []; + set => this.Props[nameof(this.Items)] = value; + } +} \ No newline at end of file diff --git a/app/MindWork AI Studio/Tools/PluginSystem/Assistants/DataModel/AssistantListItem.cs b/app/MindWork AI Studio/Tools/PluginSystem/Assistants/DataModel/AssistantListItem.cs new file mode 100644 index 00000000..43bd60e1 --- /dev/null +++ b/app/MindWork AI Studio/Tools/PluginSystem/Assistants/DataModel/AssistantListItem.cs @@ -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; } +} \ No newline at end of file diff --git a/app/MindWork AI Studio/Tools/PluginSystem/Assistants/DataModel/AssistantUiCompontentType.cs b/app/MindWork AI Studio/Tools/PluginSystem/Assistants/DataModel/AssistantUiCompontentType.cs index e5ef6268..9ec6e948 100644 --- a/app/MindWork AI Studio/Tools/PluginSystem/Assistants/DataModel/AssistantUiCompontentType.cs +++ b/app/MindWork AI Studio/Tools/PluginSystem/Assistants/DataModel/AssistantUiCompontentType.cs @@ -10,4 +10,5 @@ public enum AssistantUiCompontentType SWITCH, HEADING, TEXT, + LIST, } \ No newline at end of file diff --git a/app/MindWork AI Studio/Tools/PluginSystem/Assistants/DataModel/ComponentPropSpecs.cs b/app/MindWork AI Studio/Tools/PluginSystem/Assistants/DataModel/ComponentPropSpecs.cs index 0cbc4424..5846dda2 100644 --- a/app/MindWork AI Studio/Tools/PluginSystem/Assistants/DataModel/ComponentPropSpecs.cs +++ b/app/MindWork AI Studio/Tools/PluginSystem/Assistants/DataModel/ComponentPropSpecs.cs @@ -37,5 +37,9 @@ public static class ComponentPropSpecs required: ["Content"], optional: [] ), + [AssistantUiCompontentType.LIST] = new( + required: ["Items"], + optional: [] + ), }; } \ No newline at end of file diff --git a/app/MindWork AI Studio/Tools/PluginSystem/Assistants/PluginAssistants.cs b/app/MindWork AI Studio/Tools/PluginSystem/Assistants/PluginAssistants.cs index ac8167cd..ba8bae8d 100644 --- a/app/MindWork AI Studio/Tools/PluginSystem/Assistants/PluginAssistants.cs +++ b/app/MindWork AI Studio/Tools/PluginSystem/Assistants/PluginAssistants.cs @@ -273,6 +273,12 @@ public sealed class PluginAssistants(bool isInternal, LuaState state, PluginType result = itemList; return true; } + + if (val.TryRead(out var listItemListTable) && this.TryParseListItemList(listItemListTable, out var listItemList)) + { + result = listItemList; + return true; + } result = null!; return false; @@ -316,4 +322,48 @@ public sealed class PluginAssistants(bool isInternal, LuaState state, PluginType return true; } + + private bool TryParseListItem(LuaTable table, out AssistantListItem item) + { + item = new AssistantListItem(); + + if (!table.TryGetValue("Text", out var textVal) || !textVal.TryRead(out var text)) + return false; + + if (!table.TryGetValue("Type", out var typeVal) || !typeVal.TryRead(out var type)) + return false; + + item.Text = text; + item.Type = type; + + if (table.TryGetValue("Href", out var hrefVal) && hrefVal.TryRead(out var href)) + { + item.Href = href; + } + + return true; + } + + private bool TryParseListItemList(LuaTable table, out List items) + { + items = new List(); + + var length = table.ArrayLength; + for (var i = 1; i <= length; i++) + { + var value = table[i]; + + if (value.TryRead(out var subTable) && this.TryParseListItem(subTable, out var item)) + { + items.Add(item); + } + else + { + items = null!; + return false; + } + } + + return true; + } } \ No newline at end of file