mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-03-29 19:11:38 +00:00
added a new color picker component to the lua parsing
This commit is contained in:
parent
fc3b46a2d8
commit
a5149e460f
@ -135,5 +135,28 @@
|
||||
</MudList>
|
||||
}
|
||||
break;
|
||||
case AssistantComponentType.COLOR_PICKER:
|
||||
if (component is AssistantColorPicker assistantColorPicker)
|
||||
{
|
||||
var colorPicker = assistantColorPicker;
|
||||
var variant = this.GetPickerVariant(colorPicker.PickerVariant);
|
||||
var elevation = variant == PickerVariant.Static ? 6 : 0;
|
||||
var rounded = variant == PickerVariant.Static;
|
||||
|
||||
<MudItem Class="d-flex">
|
||||
<MudColorPicker @bind-Text="@this.colorPickerFields[colorPicker.Name]"
|
||||
Label="@colorPicker.Label"
|
||||
Placeholder="@colorPicker.Placeholder"
|
||||
ShowAlpha="@colorPicker.ShowAlpha"
|
||||
ShowToolbar="@colorPicker.ShowToolbar"
|
||||
ShowModeSwitch="@colorPicker.ShowModeSwitch"
|
||||
PickerVariant="@variant"
|
||||
Rounded="@rounded"
|
||||
Elevation="@elevation"
|
||||
Style="@($"color: {this.colorPickerFields[colorPicker.Name]};")"
|
||||
Class="@MergeClass(colorPicker.Class, "mb-3")"/>
|
||||
</MudItem>
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -45,6 +45,7 @@ public partial class AssistantDynamic : AssistantBaseCore<SettingsDialogDynamic>
|
||||
private Dictionary<string, bool> switchFields = new();
|
||||
private Dictionary<string, WebContentState> webContentFields = new();
|
||||
private Dictionary<string, FileContentState> fileContentFields = new();
|
||||
private Dictionary<string, string> colorPickerFields = new();
|
||||
private readonly Dictionary<string, string> imageCache = new();
|
||||
private string pluginPath = string.Empty;
|
||||
private const string PLUGIN_SCHEME = "plugin://";
|
||||
@ -111,6 +112,12 @@ public partial class AssistantDynamic : AssistantBaseCore<SettingsDialogDynamic>
|
||||
this.fileContentFields.Add(fileContent.Name, new FileContentState());
|
||||
}
|
||||
break;
|
||||
case AssistantComponentType.COLOR_PICKER:
|
||||
if (component is AssistantColorPicker assistantColorPicker)
|
||||
{
|
||||
this.colorPickerFields.Add(assistantColorPicker.Name, assistantColorPicker.Placeholder);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -167,6 +174,11 @@ public partial class AssistantDynamic : AssistantBaseCore<SettingsDialogDynamic>
|
||||
{
|
||||
entry.Value.Content = string.Empty;
|
||||
}
|
||||
|
||||
foreach (var entry in this.colorPickerFields)
|
||||
{
|
||||
this.colorPickerFields[entry.Key] = string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool MightPreselectValues()
|
||||
@ -256,6 +268,8 @@ public partial class AssistantDynamic : AssistantBaseCore<SettingsDialogDynamic>
|
||||
fields[entry.Key] = entry.Value.Content ?? string.Empty;
|
||||
foreach (var entry in this.fileContentFields)
|
||||
fields[entry.Key] = entry.Value.Content ?? string.Empty;
|
||||
foreach (var entry in this.colorPickerFields)
|
||||
fields[entry.Key] = entry.Value ?? string.Empty;
|
||||
|
||||
input["fields"] = fields;
|
||||
|
||||
@ -282,6 +296,9 @@ public partial class AssistantDynamic : AssistantBaseCore<SettingsDialogDynamic>
|
||||
case AssistantFileContentReader fileContent:
|
||||
this.AddMetaEntry(meta, fileContent.Name, component.Type, null, fileContent.UserPrompt);
|
||||
break;
|
||||
case AssistantColorPicker colorPicker:
|
||||
this.AddMetaEntry(meta, colorPicker.Name, component.Type, colorPicker.Label, colorPicker.UserPrompt);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -391,6 +408,16 @@ public partial class AssistantDynamic : AssistantBaseCore<SettingsDialogDynamic>
|
||||
}
|
||||
}
|
||||
break;
|
||||
case AssistantComponentType.COLOR_PICKER:
|
||||
if (component is AssistantColorPicker colorPicker)
|
||||
{
|
||||
prompt += $"context:{Environment.NewLine}{colorPicker.UserPrompt}{Environment.NewLine}---{Environment.NewLine}";
|
||||
if (this.inputFields.TryGetValue(colorPicker.Name, out userInput))
|
||||
{
|
||||
prompt += $"user prompt:{Environment.NewLine}{userInput}";
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
prompt += $"{userInput}{Environment.NewLine}";
|
||||
break;
|
||||
@ -414,8 +441,16 @@ public partial class AssistantDynamic : AssistantBaseCore<SettingsDialogDynamic>
|
||||
}
|
||||
|
||||
private string? GetOptionalStyle(string? style) => string.IsNullOrWhiteSpace(style) ? null : style;
|
||||
|
||||
private string? ValidateProfileSelection(AssistantProfileSelection profileSelection, Profile profile)
|
||||
|
||||
private PickerVariant GetPickerVariant(string pickerVariant) => pickerVariant.ToLowerInvariant() switch
|
||||
{
|
||||
"dialog" => PickerVariant.Dialog,
|
||||
"static" => PickerVariant.Static,
|
||||
"inline" => PickerVariant.Inline,
|
||||
_ => PickerVariant.Static
|
||||
};
|
||||
|
||||
private string? ValidateProfileSelection(AssistantProfileSelection profileSelection, Profile? profile)
|
||||
{
|
||||
if (profile == default || profile == Profile.NO_PROFILE)
|
||||
{
|
||||
|
||||
@ -12,6 +12,7 @@ Supported types (matching the Blazor UI components):
|
||||
- `TEXT_AREA`: any user input field with `Name`, `Label`, `UserPrompt`, `PrefillText`, `IsSingleLine`, `ReadOnly`.
|
||||
- `DROPDOWN`: selects between variants; `Props` must include `Name`, `Label`, `Default`, `Items`, and optionally `ValueType` plus `UserPrompt`.
|
||||
- `SWITCH`: boolean option; requires `Name`, `Label`, `Value`, `LabelOn`, `LabelOff`, and may include `UserPrompt`.
|
||||
- `COLOR_PICKER`: color input based on `MudColorPicker`; requires `Name`, `Label`, and may include `Placeholder`, `ShowAlpha`, `ShowToolbar`, `ShowModeSwitch`, `PickerVariant`, `UserPrompt`, `Class`, `Style`.
|
||||
- `PROVIDER_SELECTION` / `PROFILE_SELECTION`: hooks into the shared provider/profile selectors.
|
||||
- `WEB_CONTENT_READER`: renders `ReadWebContent`; include `Name`, `UserPrompt`, `Preselect`, `PreselectContentCleanerAgent`.
|
||||
- `FILE_CONTENT_READER`: renders `ReadFileContent`; include `Name`, `UserPrompt`.
|
||||
@ -31,7 +32,7 @@ user prompt:
|
||||
<value extracted from the component>
|
||||
```
|
||||
|
||||
For switches the “value” is the boolean `true/false`; for readers it is the fetched/selected content. Always provide a meaningful `UserPrompt` so the final concatenated prompt remains coherent from the LLM’s perspective.
|
||||
For switches the “value” is the boolean `true/false`; for readers it is the fetched/selected content; for color pickers it is the selected color text (for example `#FFAA00` or `rgba(...)`, depending on the picker mode). Always provide a meaningful `UserPrompt` so the final concatenated prompt remains coherent from the LLM’s perspective.
|
||||
|
||||
### Advanced: BuildPrompt (optional)
|
||||
If you want full control over prompt composition, define `ASSISTANT.BuildPrompt` as a Lua function. When present, AI Studio calls it and uses its return value as the final user prompt. The default prompt assembly is skipped.
|
||||
@ -46,8 +47,9 @@ The function receives a single `input` table with:
|
||||
- `input.fields`: values keyed by component `Name`
|
||||
- Text area, dropdown, and readers are strings
|
||||
- Switch is a boolean
|
||||
- Color picker is the selected color as a string
|
||||
- `input.meta`: per-component metadata keyed by component `Name`
|
||||
- `Type` (string, e.g. `TEXT_AREA`, `DROPDOWN`, `SWITCH`)
|
||||
- `Type` (string, e.g. `TEXT_AREA`, `DROPDOWN`, `SWITCH`, `COLOR_PICKER`)
|
||||
- `Label` (string, when provided)
|
||||
- `UserPrompt` (string, when provided)
|
||||
- `input.profile`: selected profile data
|
||||
@ -63,7 +65,7 @@ input = {
|
||||
},
|
||||
meta = {
|
||||
["<Name>"] = {
|
||||
Type = "<TEXT_AREA|DROPDOWN|SWITCH|WEB_CONTENT_READER|FILE_CONTENT_READER>",
|
||||
Type = "<TEXT_AREA|DROPDOWN|SWITCH|WEB_CONTENT_READER|FILE_CONTENT_READER|COLOR_PICKER>",
|
||||
Label = "<string?>",
|
||||
UserPrompt = "<string?>"
|
||||
},
|
||||
@ -103,6 +105,8 @@ ASSISTANT.BuildPrompt = function(input)
|
||||
local value = input.fields[name]
|
||||
if meta.Type == "SWITCH" then
|
||||
table.insert(parts, name .. ": " .. tostring(value))
|
||||
elseif meta.Type == "COLOR_PICKER" and value and value ~= "" then
|
||||
table.insert(parts, name .. ": " .. value)
|
||||
elseif value and value ~= "" then
|
||||
table.insert(parts, name .. ": " .. value)
|
||||
end
|
||||
@ -111,6 +115,37 @@ ASSISTANT.BuildPrompt = function(input)
|
||||
end
|
||||
```
|
||||
|
||||
### `COLOR_PICKER` reference
|
||||
- Use `Type = "COLOR_PICKER"` to render a MudBlazor color picker.
|
||||
- Required props:
|
||||
- `Name`: unique state key used in prompt assembly and `BuildPrompt(input.fields)`.
|
||||
- `Label`: visible field label.
|
||||
- Optional props:
|
||||
- `Placeholder`: default color hex string (e.g. `#FF10FF`) or initial hint text.
|
||||
- `ShowAlpha`: defaults to `true`; enables alpha channel editing.
|
||||
- `ShowToolbar`: defaults to `true`; shows picker/grid/palette toolbar.
|
||||
- `ShowModeSwitch`: defaults to `true`; allows switching between HEX/RGB(A)/HSL modes.
|
||||
- `PickerVariant`: one of `DIALOG`, `INLINE`, `STATIC`; invalid or omitted values fall back to `STATIC`.
|
||||
- `UserPrompt`: prompt context text for the selected color.
|
||||
- `Class`, `Style`: forwarded to the rendered component for layout/styling.
|
||||
|
||||
Example:
|
||||
```lua
|
||||
{
|
||||
["Type"] = "COLOR_PICKER",
|
||||
["Props"] = {
|
||||
["Name"] = "accentColor",
|
||||
["Label"] = "Accent color",
|
||||
["Placeholder"] = "#FFAA00",
|
||||
["ShowAlpha"] = false,
|
||||
["ShowToolbar"] = true,
|
||||
["ShowModeSwitch"] = true,
|
||||
["PickerVariant"] = "STATIC",
|
||||
["UserPrompt"] = "Use this as the accent color for the generated design."
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Using `profile` inside BuildPrompt
|
||||
Profiles are optional user context (e.g., "NeedToKnow" and "Actions"). You can inject this directly into the user prompt if you want the LLM to always see it.
|
||||
|
||||
|
||||
@ -168,6 +168,19 @@ ASSISTANT = {
|
||||
["UserPrompt"] = "<help text reminding the user what kind of file they should load>"
|
||||
}
|
||||
},
|
||||
{
|
||||
["Type"] = "COLOR_PICKER",
|
||||
["Props"] = {
|
||||
["Name"] = "<unique identifier of this component>", -- required
|
||||
["Label"] = "<heading of your component>", -- required
|
||||
["Placeholder"] = "<use this as a default color property with HEX code (e.g '#FFFF12') or just show hints to the user>",
|
||||
["ShowAlpha"] = true, -- weather alpha channels are shown
|
||||
["ShowToolbar"] = true, -- weather the toolbar to toggle between picker, grid or palette is shown
|
||||
["ShowModeSwitch"] = true, -- weather switch to toggle between RGB(A), HEX or HSL color mode is shown
|
||||
["PickerVariant"] = "<DIALOG | INLINE | STATIC (default)>",
|
||||
["UserPrompt"] = "<help text reminding the user what kind of file they should load>",
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
@ -39,6 +39,8 @@ public class AssistantComponentFactory
|
||||
return new AssistantFileContentReader { Props = props, Children = children };
|
||||
case AssistantComponentType.IMAGE:
|
||||
return new AssistantImage { Props = props, Children = children };
|
||||
case AssistantComponentType.COLOR_PICKER:
|
||||
return new AssistantColorPicker { 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}");
|
||||
|
||||
@ -0,0 +1,67 @@
|
||||
namespace AIStudio.Tools.PluginSystem.Assistants.DataModel;
|
||||
|
||||
internal sealed class AssistantColorPicker : AssistantComponentBase
|
||||
{
|
||||
public override AssistantComponentType Type => AssistantComponentType.COLOR_PICKER;
|
||||
public override Dictionary<string, object> Props { get; set; } = new();
|
||||
public override List<IAssistantComponent> Children { get; set; } = new();
|
||||
|
||||
public string Name
|
||||
{
|
||||
get => AssistantComponentPropHelper.ReadString(this.Props, nameof(this.Name));
|
||||
set => AssistantComponentPropHelper.WriteString(this.Props, nameof(this.Name), value);
|
||||
}
|
||||
public string Label
|
||||
{
|
||||
get => AssistantComponentPropHelper.ReadString(this.Props, nameof(this.Label));
|
||||
set => AssistantComponentPropHelper.WriteString(this.Props, nameof(this.Label), value);
|
||||
}
|
||||
|
||||
public string Placeholder
|
||||
{
|
||||
get => AssistantComponentPropHelper.ReadString(this.Props, nameof(this.Placeholder));
|
||||
set => AssistantComponentPropHelper.WriteString(this.Props, nameof(this.Placeholder), value);
|
||||
}
|
||||
|
||||
public bool ShowAlpha
|
||||
{
|
||||
get => !this.Props.TryGetValue(nameof(this.ShowAlpha), out var val) || val is true;
|
||||
set => this.Props[nameof(this.ShowAlpha)] = value;
|
||||
}
|
||||
|
||||
public bool ShowToolbar
|
||||
{
|
||||
get => !this.Props.TryGetValue(nameof(this.ShowToolbar), out var val) || val is true;
|
||||
set => this.Props[nameof(this.ShowToolbar)] = value;
|
||||
}
|
||||
|
||||
public bool ShowModeSwitch
|
||||
{
|
||||
get => !this.Props.TryGetValue(nameof(this.ShowModeSwitch), out var val) || val is true;
|
||||
set => this.Props[nameof(this.ShowModeSwitch)] = value;
|
||||
}
|
||||
|
||||
public string PickerVariant
|
||||
{
|
||||
get => AssistantComponentPropHelper.ReadString(this.Props, nameof(this.PickerVariant));
|
||||
set => AssistantComponentPropHelper.WriteString(this.Props, nameof(this.PickerVariant), value);
|
||||
}
|
||||
|
||||
public string UserPrompt
|
||||
{
|
||||
get => AssistantComponentPropHelper.ReadString(this.Props, nameof(this.UserPrompt));
|
||||
set => AssistantComponentPropHelper.WriteString(this.Props, nameof(this.UserPrompt), value);
|
||||
}
|
||||
|
||||
public string Class
|
||||
{
|
||||
get => AssistantComponentPropHelper.ReadString(this.Props, nameof(this.Class));
|
||||
set => AssistantComponentPropHelper.WriteString(this.Props, nameof(this.Class), value);
|
||||
}
|
||||
|
||||
public string Style
|
||||
{
|
||||
get => AssistantComponentPropHelper.ReadString(this.Props, nameof(this.Style));
|
||||
set => AssistantComponentPropHelper.WriteString(this.Props, nameof(this.Style), value);
|
||||
}
|
||||
}
|
||||
@ -15,4 +15,5 @@ public enum AssistantComponentType
|
||||
WEB_CONTENT_READER,
|
||||
FILE_CONTENT_READER,
|
||||
IMAGE,
|
||||
COLOR_PICKER,
|
||||
}
|
||||
|
||||
@ -57,5 +57,9 @@ public static class ComponentPropSpecs
|
||||
required: ["Src"],
|
||||
optional: ["Alt", "Caption", "Class", "Style"]
|
||||
),
|
||||
[AssistantComponentType.COLOR_PICKER] = new(
|
||||
required: ["Name", "Label"],
|
||||
optional: ["Placeholder", "ShowAlpha", "ShowToolbar", "ShowModeSwitch", "PickerVariant", "UserPrompt", "Class", "Style"]
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user