mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-03-29 15:31:37 +00:00
moved helper functions into corrisponding data classes
This commit is contained in:
parent
d1ece556a6
commit
5e683d0114
@ -423,8 +423,8 @@ else
|
|||||||
var format = datePicker.GetDateFormat();
|
var format = datePicker.GetDateFormat();
|
||||||
|
|
||||||
<MudPaper Class="d-flex" Elevation="0">
|
<MudPaper Class="d-flex" Elevation="0">
|
||||||
<MudDatePicker Date="@this.ParseDatePickerValue(this.assistantState.Dates[datePicker.Name], format)"
|
<MudDatePicker Date="@datePicker.ParseValue(this.assistantState.Dates[datePicker.Name])"
|
||||||
DateChanged="@((DateTime? value) => this.SetDatePickerValue(datePicker.Name, value, format))"
|
DateChanged="@((DateTime? value) => this.assistantState.Dates[datePicker.Name] = datePicker.FormatValue(value))"
|
||||||
Label="@datePicker.Label"
|
Label="@datePicker.Label"
|
||||||
Color="@AssistantComponentPropHelper.GetColor(datePicker.Color, Color.Primary)"
|
Color="@AssistantComponentPropHelper.GetColor(datePicker.Color, Color.Primary)"
|
||||||
Placeholder="@datePicker.Placeholder"
|
Placeholder="@datePicker.Placeholder"
|
||||||
@ -446,8 +446,8 @@ else
|
|||||||
var format = dateRangePicker.GetDateFormat();
|
var format = dateRangePicker.GetDateFormat();
|
||||||
|
|
||||||
<MudPaper Class="d-flex" Elevation="0">
|
<MudPaper Class="d-flex" Elevation="0">
|
||||||
<MudDateRangePicker DateRange="@this.ParseDateRangePickerValue(this.assistantState.DateRanges[dateRangePicker.Name], format)"
|
<MudDateRangePicker DateRange="@dateRangePicker.ParseValue(this.assistantState.DateRanges[dateRangePicker.Name])"
|
||||||
DateRangeChanged="@(value => this.SetDateRangePickerValue(dateRangePicker.Name, value, format))"
|
DateRangeChanged="@(value => this.assistantState.DateRanges[dateRangePicker.Name] = dateRangePicker.FormatValue(value))"
|
||||||
Label="@dateRangePicker.Label"
|
Label="@dateRangePicker.Label"
|
||||||
Color="@AssistantComponentPropHelper.GetColor(dateRangePicker.Color, Color.Primary)"
|
Color="@AssistantComponentPropHelper.GetColor(dateRangePicker.Color, Color.Primary)"
|
||||||
PlaceholderStart="@dateRangePicker.PlaceholderStart"
|
PlaceholderStart="@dateRangePicker.PlaceholderStart"
|
||||||
@ -470,8 +470,8 @@ else
|
|||||||
var format = timePicker.GetTimeFormat();
|
var format = timePicker.GetTimeFormat();
|
||||||
|
|
||||||
<MudPaper Class="d-flex" Elevation="0">
|
<MudPaper Class="d-flex" Elevation="0">
|
||||||
<MudTimePicker Time="@this.ParseTimePickerValue(this.assistantState.Times[timePicker.Name], format)"
|
<MudTimePicker Time="@timePicker.ParseValue(this.assistantState.Times[timePicker.Name])"
|
||||||
TimeChanged="@((TimeSpan? value) => this.SetTimePickerValue(timePicker.Name, value, format))"
|
TimeChanged="@((TimeSpan? value) => this.assistantState.Times[timePicker.Name] = timePicker.FormatValue(value))"
|
||||||
Label="@timePicker.Label"
|
Label="@timePicker.Label"
|
||||||
Color="@AssistantComponentPropHelper.GetColor(timePicker.Color, Color.Primary)"
|
Color="@AssistantComponentPropHelper.GetColor(timePicker.Color, Color.Primary)"
|
||||||
Placeholder="@timePicker.Placeholder"
|
Placeholder="@timePicker.Placeholder"
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
using System.Globalization;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using AIStudio.Dialogs.Settings;
|
using AIStudio.Dialogs.Settings;
|
||||||
using AIStudio.Settings;
|
using AIStudio.Settings;
|
||||||
@ -40,31 +39,29 @@ public partial class AssistantDynamic : AssistantBaseCore<SettingsDialogDynamic>
|
|||||||
private readonly HashSet<string> executingButtonActions = [];
|
private readonly HashSet<string> executingButtonActions = [];
|
||||||
private readonly HashSet<string> executingSwitchActions = [];
|
private readonly HashSet<string> executingSwitchActions = [];
|
||||||
private string pluginPath = string.Empty;
|
private string pluginPath = string.Empty;
|
||||||
private const string PLUGIN_SCHEME = "plugin://";
|
|
||||||
private const string ASSISTANT_QUERY_KEY = "assistantId";
|
private const string ASSISTANT_QUERY_KEY = "assistantId";
|
||||||
private static readonly CultureInfo INVARIANT_CULTURE = CultureInfo.InvariantCulture;
|
|
||||||
private static readonly string[] FALLBACK_DATE_FORMATS = ["yyyy-MM-dd", "dd.MM.yyyy", "MM/dd/yyyy"];
|
#region Implementation of AssistantBase
|
||||||
private static readonly string[] FALLBACK_TIME_FORMATS = ["HH:mm", "HH:mm:ss", "hh:mm tt", "h:mm tt"];
|
|
||||||
|
|
||||||
protected override void OnInitialized()
|
protected override void OnInitialized()
|
||||||
{
|
{
|
||||||
var assistantPlugin = this.ResolveAssistantPlugin();
|
var pluginAssistant = this.ResolveAssistantPlugin();
|
||||||
if (assistantPlugin is null)
|
if (pluginAssistant is null)
|
||||||
{
|
{
|
||||||
this.Logger.LogWarning("AssistantDynamic could not resolve a registered assistant plugin.");
|
this.Logger.LogWarning("AssistantDynamic could not resolve a registered assistant plugin.");
|
||||||
base.OnInitialized();
|
base.OnInitialized();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.assistantPlugin = assistantPlugin;
|
this.assistantPlugin = pluginAssistant;
|
||||||
this.RootComponent = assistantPlugin.RootComponent;
|
this.RootComponent = pluginAssistant.RootComponent;
|
||||||
this.title = assistantPlugin.AssistantTitle;
|
this.title = pluginAssistant.AssistantTitle;
|
||||||
this.description = assistantPlugin.AssistantDescription;
|
this.description = pluginAssistant.AssistantDescription;
|
||||||
this.systemPrompt = assistantPlugin.SystemPrompt;
|
this.systemPrompt = pluginAssistant.SystemPrompt;
|
||||||
this.submitText = assistantPlugin.SubmitText;
|
this.submitText = pluginAssistant.SubmitText;
|
||||||
this.allowProfiles = assistantPlugin.AllowProfiles;
|
this.allowProfiles = pluginAssistant.AllowProfiles;
|
||||||
this.showFooterProfileSelection = !assistantPlugin.HasEmbeddedProfileSelection;
|
this.showFooterProfileSelection = !pluginAssistant.HasEmbeddedProfileSelection;
|
||||||
this.pluginPath = assistantPlugin.PluginPath;
|
this.pluginPath = pluginAssistant.PluginPath;
|
||||||
|
|
||||||
var rootComponent = this.RootComponent;
|
var rootComponent = this.RootComponent;
|
||||||
if (rootComponent is not null)
|
if (rootComponent is not null)
|
||||||
@ -75,19 +72,40 @@ public partial class AssistantDynamic : AssistantBaseCore<SettingsDialogDynamic>
|
|||||||
base.OnInitialized();
|
base.OnInitialized();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void ResetForm()
|
||||||
|
{
|
||||||
|
this.assistantState.Clear();
|
||||||
|
|
||||||
|
var rootComponent = this.RootComponent;
|
||||||
|
if (rootComponent is not null)
|
||||||
|
this.InitializeComponentState(rootComponent.Children);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool MightPreselectValues()
|
||||||
|
{
|
||||||
|
// Dynamic assistants have arbitrary fields supplied via plugins, so there
|
||||||
|
// isn't a built-in settings section to prefill values. Always return
|
||||||
|
// false to keep the plugin-specified defaults.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Implementation of dynamic plugin init
|
||||||
|
|
||||||
private PluginAssistants? ResolveAssistantPlugin()
|
private PluginAssistants? ResolveAssistantPlugin()
|
||||||
{
|
{
|
||||||
var assistantPlugins = PluginFactory.RunningPlugins.OfType<PluginAssistants>()
|
var pluginAssistants = PluginFactory.RunningPlugins.OfType<PluginAssistants>()
|
||||||
.Where(plugin => this.SettingsManager.IsPluginEnabled(plugin))
|
.Where(plugin => this.SettingsManager.IsPluginEnabled(plugin))
|
||||||
.ToList();
|
.ToList();
|
||||||
if (assistantPlugins.Count == 0)
|
if (pluginAssistants.Count == 0)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
var requestedPluginId = this.TryGetAssistantIdFromQuery();
|
var requestedPluginId = this.TryGetAssistantIdFromQuery();
|
||||||
if (requestedPluginId is not { } id) return assistantPlugins.First();
|
if (requestedPluginId is not { } id) return pluginAssistants.First();
|
||||||
|
|
||||||
var requestedPlugin = assistantPlugins.FirstOrDefault(p => p.Id == id);
|
var requestedPlugin = pluginAssistants.FirstOrDefault(p => p.Id == id);
|
||||||
return requestedPlugin ?? assistantPlugins.First();
|
return requestedPlugin ?? pluginAssistants.First();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Guid? TryGetAssistantIdFromQuery()
|
private Guid? TryGetAssistantIdFromQuery()
|
||||||
@ -111,22 +129,7 @@ public partial class AssistantDynamic : AssistantBaseCore<SettingsDialogDynamic>
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void ResetForm()
|
#endregion
|
||||||
{
|
|
||||||
this.assistantState.Clear();
|
|
||||||
|
|
||||||
var rootComponent = this.RootComponent;
|
|
||||||
if (rootComponent is not null)
|
|
||||||
this.InitializeComponentState(rootComponent.Children);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override bool MightPreselectValues()
|
|
||||||
{
|
|
||||||
// Dynamic assistants have arbitrary fields supplied via plugins, so there
|
|
||||||
// isn't a built-in settings section to prefill values. Always return
|
|
||||||
// false to keep the plugin-specified defaults.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private string ResolveImageSource(AssistantImage image)
|
private string ResolveImageSource(AssistantImage image)
|
||||||
{
|
{
|
||||||
@ -136,53 +139,11 @@ public partial class AssistantDynamic : AssistantBaseCore<SettingsDialogDynamic>
|
|||||||
if (this.imageCache.TryGetValue(image.Src, out var cached) && !string.IsNullOrWhiteSpace(cached))
|
if (this.imageCache.TryGetValue(image.Src, out var cached) && !string.IsNullOrWhiteSpace(cached))
|
||||||
return cached;
|
return cached;
|
||||||
|
|
||||||
var resolved = image.Src;
|
var resolved = image.ResolveSource(this.pluginPath);
|
||||||
|
|
||||||
if (resolved.StartsWith(PLUGIN_SCHEME, StringComparison.OrdinalIgnoreCase) && !string.IsNullOrWhiteSpace(this.pluginPath))
|
|
||||||
{
|
|
||||||
var relative = resolved[PLUGIN_SCHEME.Length..].TrimStart('/', '\\').Replace('/', Path.DirectorySeparatorChar).Replace('\\', Path.DirectorySeparatorChar);
|
|
||||||
var filePath = Path.Join(this.pluginPath, relative);
|
|
||||||
if (File.Exists(filePath))
|
|
||||||
{
|
|
||||||
var mime = GetImageMimeType(filePath);
|
|
||||||
var data = Convert.ToBase64String(File.ReadAllBytes(filePath));
|
|
||||||
resolved = $"data:{mime};base64,{data}";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
resolved = string.Empty;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (Uri.TryCreate(resolved, UriKind.Absolute, out var uri))
|
|
||||||
{
|
|
||||||
if (uri.Scheme is not ("http" or "https" or "data"))
|
|
||||||
resolved = string.Empty;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
resolved = string.Empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.imageCache[image.Src] = resolved;
|
this.imageCache[image.Src] = resolved;
|
||||||
return resolved;
|
return resolved;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string GetImageMimeType(string path)
|
|
||||||
{
|
|
||||||
var extension = Path.GetExtension(path).TrimStart('.').ToLowerInvariant();
|
|
||||||
return extension switch
|
|
||||||
{
|
|
||||||
"svg" => "image/svg+xml",
|
|
||||||
"png" => "image/png",
|
|
||||||
"jpg" => "image/jpeg",
|
|
||||||
"jpeg" => "image/jpeg",
|
|
||||||
"gif" => "image/gif",
|
|
||||||
"webp" => "image/webp",
|
|
||||||
"bmp" => "image/bmp",
|
|
||||||
_ => "image/png",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<string> CollectUserPromptAsync()
|
private async Task<string> CollectUserPromptAsync()
|
||||||
{
|
{
|
||||||
if (this.assistantPlugin?.HasCustomPromptBuilder != true) return this.CollectUserPromptFallback();
|
if (this.assistantPlugin?.HasCustomPromptBuilder != true) return this.CollectUserPromptFallback();
|
||||||
@ -216,10 +177,7 @@ public partial class AssistantDynamic : AssistantBaseCore<SettingsDialogDynamic>
|
|||||||
{
|
{
|
||||||
var prompt = string.Empty;
|
var prompt = string.Empty;
|
||||||
var rootComponent = this.RootComponent;
|
var rootComponent = this.RootComponent;
|
||||||
if (rootComponent is null)
|
return rootComponent is null ? prompt : this.CollectUserPromptFallback(rootComponent.Children);
|
||||||
return prompt;
|
|
||||||
|
|
||||||
return this.CollectUserPromptFallback(rootComponent.Children);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InitializeComponentState(IEnumerable<IAssistantComponent> components)
|
private void InitializeComponentState(IEnumerable<IAssistantComponent> components)
|
||||||
@ -236,15 +194,12 @@ public partial class AssistantDynamic : AssistantBaseCore<SettingsDialogDynamic>
|
|||||||
|
|
||||||
private static string MergeClass(string customClass, string fallback)
|
private static string MergeClass(string customClass, string fallback)
|
||||||
{
|
{
|
||||||
var trimmedCustom = customClass?.Trim() ?? string.Empty;
|
var trimmedCustom = customClass.Trim();
|
||||||
var trimmedFallback = fallback?.Trim() ?? string.Empty;
|
var trimmedFallback = fallback.Trim();
|
||||||
if (string.IsNullOrEmpty(trimmedCustom))
|
if (string.IsNullOrEmpty(trimmedCustom))
|
||||||
return trimmedFallback;
|
return trimmedFallback;
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(trimmedFallback))
|
return string.IsNullOrEmpty(trimmedFallback) ? trimmedCustom : $"{trimmedCustom} {trimmedFallback}";
|
||||||
return trimmedCustom;
|
|
||||||
|
|
||||||
return $"{trimmedCustom} {trimmedFallback}";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private string? GetOptionalStyle(string? style) => string.IsNullOrWhiteSpace(style) ? null : style;
|
private string? GetOptionalStyle(string? style) => string.IsNullOrWhiteSpace(style) ? null : style;
|
||||||
@ -423,7 +378,7 @@ public partial class AssistantDynamic : AssistantBaseCore<SettingsDialogDynamic>
|
|||||||
|
|
||||||
private string? ValidateProfileSelection(AssistantProfileSelection profileSelection, Profile? profile)
|
private string? ValidateProfileSelection(AssistantProfileSelection profileSelection, Profile? profile)
|
||||||
{
|
{
|
||||||
if (profile != default && profile != Profile.NO_PROFILE) return null;
|
if (profile != null && profile != Profile.NO_PROFILE) return null;
|
||||||
return !string.IsNullOrWhiteSpace(profileSelection.ValidationMessage) ? profileSelection.ValidationMessage : this.T("Please select one of your profiles.");
|
return !string.IsNullOrWhiteSpace(profileSelection.ValidationMessage) ? profileSelection.ValidationMessage : this.T("Please select one of your profiles.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -451,124 +406,4 @@ public partial class AssistantDynamic : AssistantBaseCore<SettingsDialogDynamic>
|
|||||||
|
|
||||||
return prompt.ToString();
|
return prompt.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private DateTime? ParseDatePickerValue(string? value, string? format)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrWhiteSpace(value))
|
|
||||||
return null;
|
|
||||||
|
|
||||||
if (TryParseDate(value, format, out var parsedDate))
|
|
||||||
return parsedDate;
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SetDatePickerValue(string fieldName, DateTime? value, string? format)
|
|
||||||
{
|
|
||||||
this.assistantState.Dates[fieldName] = value.HasValue ? FormatDate(value.Value, format) : string.Empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
private DateRange? ParseDateRangePickerValue(string? value, string? format)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrWhiteSpace(value))
|
|
||||||
return null;
|
|
||||||
|
|
||||||
var parts = value.Split(" - ", 2, StringSplitOptions.TrimEntries);
|
|
||||||
if (parts.Length != 2)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
if (!TryParseDate(parts[0], format, out var start) || !TryParseDate(parts[1], format, out var end))
|
|
||||||
return null;
|
|
||||||
|
|
||||||
return new DateRange(start, end);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SetDateRangePickerValue(string fieldName, DateRange? value, string? format)
|
|
||||||
{
|
|
||||||
if (value?.Start is null || value.End is null)
|
|
||||||
{
|
|
||||||
this.assistantState.DateRanges[fieldName] = string.Empty;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.assistantState.DateRanges[fieldName] = $"{FormatDate(value.Start.Value, format)} - {FormatDate(value.End.Value, format)}";
|
|
||||||
}
|
|
||||||
|
|
||||||
private TimeSpan? ParseTimePickerValue(string? value, string? format)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrWhiteSpace(value))
|
|
||||||
return null;
|
|
||||||
|
|
||||||
if (TryParseTime(value, format, out var parsedTime))
|
|
||||||
return parsedTime;
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SetTimePickerValue(string fieldName, TimeSpan? value, string? format)
|
|
||||||
{
|
|
||||||
this.assistantState.Times[fieldName] = value.HasValue ? FormatTime(value.Value, format) : string.Empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static bool TryParseDate(string value, string? format, out DateTime parsedDate)
|
|
||||||
{
|
|
||||||
if (!string.IsNullOrWhiteSpace(format) &&
|
|
||||||
DateTime.TryParseExact(value, format, INVARIANT_CULTURE, DateTimeStyles.AllowWhiteSpaces, out parsedDate))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (DateTime.TryParseExact(value, FALLBACK_DATE_FORMATS, INVARIANT_CULTURE, DateTimeStyles.AllowWhiteSpaces, out parsedDate))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return DateTime.TryParse(value, INVARIANT_CULTURE, DateTimeStyles.AllowWhiteSpaces, out parsedDate);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static bool TryParseTime(string value, string? format, out TimeSpan parsedTime)
|
|
||||||
{
|
|
||||||
if (!string.IsNullOrWhiteSpace(format) &&
|
|
||||||
DateTime.TryParseExact(value, format, INVARIANT_CULTURE, DateTimeStyles.AllowWhiteSpaces, out var dateTime))
|
|
||||||
{
|
|
||||||
parsedTime = dateTime.TimeOfDay;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (DateTime.TryParseExact(value, FALLBACK_TIME_FORMATS, INVARIANT_CULTURE, DateTimeStyles.AllowWhiteSpaces, out dateTime))
|
|
||||||
{
|
|
||||||
parsedTime = dateTime.TimeOfDay;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TimeSpan.TryParse(value, INVARIANT_CULTURE, out parsedTime))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
parsedTime = default;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string FormatDate(DateTime value, string? format)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return value.ToString(string.IsNullOrWhiteSpace(format) ? "yyyy-MM-dd" : format, INVARIANT_CULTURE);
|
|
||||||
}
|
|
||||||
catch (FormatException)
|
|
||||||
{
|
|
||||||
return value.ToString("yyyy-MM-dd", INVARIANT_CULTURE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string FormatTime(TimeSpan value, string? format)
|
|
||||||
{
|
|
||||||
var dateTime = DateTime.Today.Add(value);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return dateTime.ToString(string.IsNullOrWhiteSpace(format) ? "HH:mm" : format, INVARIANT_CULTURE);
|
|
||||||
}
|
|
||||||
catch (FormatException)
|
|
||||||
{
|
|
||||||
return dateTime.ToString("HH:mm", INVARIANT_CULTURE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -70,10 +70,8 @@ internal sealed class AssistantColorPicker : StatefulAssistantComponentBase
|
|||||||
|
|
||||||
public override string UserPromptFallback(AssistantState state)
|
public override string UserPromptFallback(AssistantState state)
|
||||||
{
|
{
|
||||||
var userInput = string.Empty;
|
|
||||||
|
|
||||||
var promptFragment = $"context:{Environment.NewLine}{this.UserPrompt}{Environment.NewLine}---{Environment.NewLine}";
|
var promptFragment = $"context:{Environment.NewLine}{this.UserPrompt}{Environment.NewLine}---{Environment.NewLine}";
|
||||||
if (state.Colors.TryGetValue(this.Name, out userInput) && !string.IsNullOrWhiteSpace(userInput))
|
if (state.Colors.TryGetValue(this.Name, out var userInput) && !string.IsNullOrWhiteSpace(userInput))
|
||||||
promptFragment += $"user prompt:{Environment.NewLine}{userInput}";
|
promptFragment += $"user prompt:{Environment.NewLine}{userInput}";
|
||||||
|
|
||||||
return promptFragment;
|
return promptFragment;
|
||||||
|
|||||||
@ -1,7 +1,12 @@
|
|||||||
|
using System.Globalization;
|
||||||
|
|
||||||
namespace AIStudio.Tools.PluginSystem.Assistants.DataModel;
|
namespace AIStudio.Tools.PluginSystem.Assistants.DataModel;
|
||||||
|
|
||||||
internal sealed class AssistantDatePicker : StatefulAssistantComponentBase
|
internal sealed class AssistantDatePicker : StatefulAssistantComponentBase
|
||||||
{
|
{
|
||||||
|
private static readonly CultureInfo INVARIANT_CULTURE = CultureInfo.InvariantCulture;
|
||||||
|
private static readonly string[] FALLBACK_DATE_FORMATS = ["dd.MM.yyyy", "yyyy-MM-dd", "MM/dd/yyyy"];
|
||||||
|
|
||||||
public override AssistantComponentType Type => AssistantComponentType.DATE_PICKER;
|
public override AssistantComponentType Type => AssistantComponentType.DATE_PICKER;
|
||||||
public override Dictionary<string, object> Props { get; set; } = new();
|
public override Dictionary<string, object> Props { get; set; } = new();
|
||||||
public override List<IAssistantComponent> Children { get; set; } = new();
|
public override List<IAssistantComponent> Children { get; set; } = new();
|
||||||
@ -76,10 +81,8 @@ internal sealed class AssistantDatePicker : StatefulAssistantComponentBase
|
|||||||
|
|
||||||
public override string UserPromptFallback(AssistantState state)
|
public override string UserPromptFallback(AssistantState state)
|
||||||
{
|
{
|
||||||
var userInput = string.Empty;
|
|
||||||
|
|
||||||
var promptFragment = $"context:{Environment.NewLine}{this.UserPrompt}{Environment.NewLine}---{Environment.NewLine}";
|
var promptFragment = $"context:{Environment.NewLine}{this.UserPrompt}{Environment.NewLine}---{Environment.NewLine}";
|
||||||
if (state.Dates.TryGetValue(this.Name, out userInput) && !string.IsNullOrWhiteSpace(userInput))
|
if (state.Dates.TryGetValue(this.Name, out var userInput) && !string.IsNullOrWhiteSpace(userInput))
|
||||||
promptFragment += $"user prompt:{Environment.NewLine}{userInput}";
|
promptFragment += $"user prompt:{Environment.NewLine}{userInput}";
|
||||||
|
|
||||||
return promptFragment;
|
return promptFragment;
|
||||||
@ -88,4 +91,38 @@ internal sealed class AssistantDatePicker : StatefulAssistantComponentBase
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
public string GetDateFormat() => string.IsNullOrWhiteSpace(this.DateFormat) ? "yyyy-MM-dd" : this.DateFormat;
|
public string GetDateFormat() => string.IsNullOrWhiteSpace(this.DateFormat) ? "yyyy-MM-dd" : this.DateFormat;
|
||||||
|
|
||||||
|
public DateTime? ParseValue(string? value)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(value))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return TryParseDate(value, this.GetDateFormat(), out var parsedDate) ? parsedDate : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string FormatValue(DateTime? value) => value.HasValue ? FormatDate(value.Value, this.GetDateFormat()) : string.Empty;
|
||||||
|
|
||||||
|
private static bool TryParseDate(string value, string? format, out DateTime parsedDate)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrWhiteSpace(format) &&
|
||||||
|
DateTime.TryParseExact(value, format, INVARIANT_CULTURE, DateTimeStyles.AllowWhiteSpaces, out parsedDate))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return DateTime.TryParseExact(value, FALLBACK_DATE_FORMATS, INVARIANT_CULTURE, DateTimeStyles.AllowWhiteSpaces, out parsedDate) ||
|
||||||
|
DateTime.TryParse(value, INVARIANT_CULTURE, DateTimeStyles.AllowWhiteSpaces, out parsedDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string FormatDate(DateTime value, string? format)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return value.ToString(string.IsNullOrWhiteSpace(format) ? FALLBACK_DATE_FORMATS[0] : format, INVARIANT_CULTURE);
|
||||||
|
}
|
||||||
|
catch (FormatException)
|
||||||
|
{
|
||||||
|
return value.ToString(FALLBACK_DATE_FORMATS[0], INVARIANT_CULTURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,13 @@
|
|||||||
|
using System.Globalization;
|
||||||
|
using MudBlazor;
|
||||||
|
|
||||||
namespace AIStudio.Tools.PluginSystem.Assistants.DataModel;
|
namespace AIStudio.Tools.PluginSystem.Assistants.DataModel;
|
||||||
|
|
||||||
internal sealed class AssistantDateRangePicker : StatefulAssistantComponentBase
|
internal sealed class AssistantDateRangePicker : StatefulAssistantComponentBase
|
||||||
{
|
{
|
||||||
|
private static readonly CultureInfo INVARIANT_CULTURE = CultureInfo.InvariantCulture;
|
||||||
|
private static readonly string[] FALLBACK_DATE_FORMATS = ["dd.MM.yyyy", "yyyy-MM-dd" , "MM/dd/yyyy"];
|
||||||
|
|
||||||
public override AssistantComponentType Type => AssistantComponentType.DATE_RANGE_PICKER;
|
public override AssistantComponentType Type => AssistantComponentType.DATE_RANGE_PICKER;
|
||||||
public override Dictionary<string, object> Props { get; set; } = new();
|
public override Dictionary<string, object> Props { get; set; } = new();
|
||||||
public override List<IAssistantComponent> Children { get; set; } = new();
|
public override List<IAssistantComponent> Children { get; set; } = new();
|
||||||
@ -82,10 +88,8 @@ internal sealed class AssistantDateRangePicker : StatefulAssistantComponentBase
|
|||||||
|
|
||||||
public override string UserPromptFallback(AssistantState state)
|
public override string UserPromptFallback(AssistantState state)
|
||||||
{
|
{
|
||||||
var userInput = string.Empty;
|
|
||||||
|
|
||||||
var promptFragment = $"context:{Environment.NewLine}{this.UserPrompt}{Environment.NewLine}---{Environment.NewLine}";
|
var promptFragment = $"context:{Environment.NewLine}{this.UserPrompt}{Environment.NewLine}---{Environment.NewLine}";
|
||||||
if (state.DateRanges.TryGetValue(this.Name, out userInput) && !string.IsNullOrWhiteSpace(userInput))
|
if (state.DateRanges.TryGetValue(this.Name, out var userInput) && !string.IsNullOrWhiteSpace(userInput))
|
||||||
promptFragment += $"user prompt:{Environment.NewLine}{userInput}";
|
promptFragment += $"user prompt:{Environment.NewLine}{userInput}";
|
||||||
|
|
||||||
return promptFragment;
|
return promptFragment;
|
||||||
@ -94,4 +98,53 @@ internal sealed class AssistantDateRangePicker : StatefulAssistantComponentBase
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
public string GetDateFormat() => string.IsNullOrWhiteSpace(this.DateFormat) ? "yyyy-MM-dd" : this.DateFormat;
|
public string GetDateFormat() => string.IsNullOrWhiteSpace(this.DateFormat) ? "yyyy-MM-dd" : this.DateFormat;
|
||||||
|
|
||||||
|
public DateRange? ParseValue(string? value)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(value))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
var format = this.GetDateFormat();
|
||||||
|
var parts = value.Split(" - ", 2, StringSplitOptions.TrimEntries);
|
||||||
|
if (parts.Length != 2)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (!TryParseDate(parts[0], format, out var start) || !TryParseDate(parts[1], format, out var end))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return new DateRange(start, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string FormatValue(DateRange? value)
|
||||||
|
{
|
||||||
|
if (value?.Start is null || value.End is null)
|
||||||
|
return string.Empty;
|
||||||
|
|
||||||
|
var format = this.GetDateFormat();
|
||||||
|
return $"{FormatDate(value.Start.Value, format)} - {FormatDate(value.End.Value, format)}";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool TryParseDate(string value, string? format, out DateTime parsedDate)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrWhiteSpace(format) &&
|
||||||
|
DateTime.TryParseExact(value, format, INVARIANT_CULTURE, DateTimeStyles.AllowWhiteSpaces, out parsedDate))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return DateTime.TryParseExact(value, FALLBACK_DATE_FORMATS, INVARIANT_CULTURE, DateTimeStyles.AllowWhiteSpaces, out parsedDate) ||
|
||||||
|
DateTime.TryParse(value, INVARIANT_CULTURE, DateTimeStyles.AllowWhiteSpaces, out parsedDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string FormatDate(DateTime value, string? format)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return value.ToString(string.IsNullOrWhiteSpace(format) ? FALLBACK_DATE_FORMATS[0] : format, INVARIANT_CULTURE);
|
||||||
|
}
|
||||||
|
catch (FormatException)
|
||||||
|
{
|
||||||
|
return value.ToString(FALLBACK_DATE_FORMATS[0], INVARIANT_CULTURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -112,14 +112,12 @@ internal sealed class AssistantDropdown : StatefulAssistantComponentBase
|
|||||||
|
|
||||||
public override string UserPromptFallback(AssistantState state)
|
public override string UserPromptFallback(AssistantState state)
|
||||||
{
|
{
|
||||||
var userInput = string.Empty;
|
|
||||||
|
|
||||||
var promptFragment = $"{Environment.NewLine}context:{Environment.NewLine}{this.UserPrompt}{Environment.NewLine}---{Environment.NewLine}";
|
var promptFragment = $"{Environment.NewLine}context:{Environment.NewLine}{this.UserPrompt}{Environment.NewLine}---{Environment.NewLine}";
|
||||||
if (this.IsMultiselect && state.MultiSelect.TryGetValue(this.Name, out var selections))
|
if (this.IsMultiselect && state.MultiSelect.TryGetValue(this.Name, out var selections))
|
||||||
{
|
{
|
||||||
promptFragment += $"user prompt:{Environment.NewLine}{string.Join(Environment.NewLine, selections.OrderBy(static value => value, StringComparer.Ordinal))}";
|
promptFragment += $"user prompt:{Environment.NewLine}{string.Join(Environment.NewLine, selections.OrderBy(static value => value, StringComparer.Ordinal))}";
|
||||||
}
|
}
|
||||||
else if (state.SingleSelect.TryGetValue(this.Name, out userInput))
|
else if (state.SingleSelect.TryGetValue(this.Name, out var userInput))
|
||||||
{
|
{
|
||||||
promptFragment += $"user prompt:{Environment.NewLine}{userInput}";
|
promptFragment += $"user prompt:{Environment.NewLine}{userInput}";
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
using System.Text;
|
||||||
using AIStudio.Assistants.Dynamic;
|
using AIStudio.Assistants.Dynamic;
|
||||||
|
|
||||||
namespace AIStudio.Tools.PluginSystem.Assistants.DataModel;
|
namespace AIStudio.Tools.PluginSystem.Assistants.DataModel;
|
||||||
@ -30,15 +31,15 @@ internal sealed class AssistantFileContentReader : StatefulAssistantComponentBas
|
|||||||
|
|
||||||
public override string UserPromptFallback(AssistantState state)
|
public override string UserPromptFallback(AssistantState state)
|
||||||
{
|
{
|
||||||
var promptFragment = string.Empty;
|
var promptFragment = new StringBuilder();
|
||||||
|
|
||||||
if (state.FileContent.TryGetValue(this.Name, out var fileState))
|
if (state.FileContent.TryGetValue(this.Name, out var fileState))
|
||||||
promptFragment += $"{Environment.NewLine}context:{Environment.NewLine}{this.UserPrompt}{Environment.NewLine}---{Environment.NewLine}";
|
promptFragment.Append($"context:{Environment.NewLine}{this.UserPrompt}{Environment.NewLine}---{Environment.NewLine}");
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(fileState?.Content))
|
if (!string.IsNullOrWhiteSpace(fileState?.Content))
|
||||||
promptFragment += $"user prompt:{Environment.NewLine}{fileState.Content}";
|
promptFragment.Append($"user prompt:{Environment.NewLine}{fileState.Content}");
|
||||||
|
|
||||||
return promptFragment;
|
return promptFragment.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@ -2,6 +2,8 @@ namespace AIStudio.Tools.PluginSystem.Assistants.DataModel;
|
|||||||
|
|
||||||
internal sealed class AssistantImage : AssistantComponentBase
|
internal sealed class AssistantImage : AssistantComponentBase
|
||||||
{
|
{
|
||||||
|
private const string PLUGIN_SCHEME = "plugin://";
|
||||||
|
|
||||||
public override AssistantComponentType Type => AssistantComponentType.IMAGE;
|
public override AssistantComponentType Type => AssistantComponentType.IMAGE;
|
||||||
public override Dictionary<string, object> Props { get; set; } = new();
|
public override Dictionary<string, object> Props { get; set; } = new();
|
||||||
public override List<IAssistantComponent> Children { get; set; } = new();
|
public override List<IAssistantComponent> Children { get; set; } = new();
|
||||||
@ -35,4 +37,48 @@ internal sealed class AssistantImage : AssistantComponentBase
|
|||||||
get => AssistantComponentPropHelper.ReadString(this.Props, nameof(this.Style));
|
get => AssistantComponentPropHelper.ReadString(this.Props, nameof(this.Style));
|
||||||
set => AssistantComponentPropHelper.WriteString(this.Props, nameof(this.Style), value);
|
set => AssistantComponentPropHelper.WriteString(this.Props, nameof(this.Style), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string ResolveSource(string pluginPath)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(this.Src))
|
||||||
|
return string.Empty;
|
||||||
|
|
||||||
|
var resolved = this.Src;
|
||||||
|
|
||||||
|
if (resolved.StartsWith(PLUGIN_SCHEME, StringComparison.OrdinalIgnoreCase) && !string.IsNullOrWhiteSpace(pluginPath))
|
||||||
|
{
|
||||||
|
var relative = resolved[PLUGIN_SCHEME.Length..]
|
||||||
|
.TrimStart('/', '\\')
|
||||||
|
.Replace('/', Path.DirectorySeparatorChar)
|
||||||
|
.Replace('\\', Path.DirectorySeparatorChar);
|
||||||
|
var filePath = Path.Join(pluginPath, relative);
|
||||||
|
if (!File.Exists(filePath))
|
||||||
|
return string.Empty;
|
||||||
|
|
||||||
|
var mime = GetImageMimeType(filePath);
|
||||||
|
var data = Convert.ToBase64String(File.ReadAllBytes(filePath));
|
||||||
|
return $"data:{mime};base64,{data}";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Uri.TryCreate(resolved, UriKind.Absolute, out var uri))
|
||||||
|
return string.Empty;
|
||||||
|
|
||||||
|
return uri.Scheme is "http" or "https" or "data" ? resolved : string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetImageMimeType(string path)
|
||||||
|
{
|
||||||
|
var extension = Path.GetExtension(path).TrimStart('.').ToLowerInvariant();
|
||||||
|
return extension switch
|
||||||
|
{
|
||||||
|
"svg" => "image/svg+xml",
|
||||||
|
"png" => "image/png",
|
||||||
|
"jpg" => "image/jpeg",
|
||||||
|
"jpeg" => "image/jpeg",
|
||||||
|
"gif" => "image/gif",
|
||||||
|
"webp" => "image/webp",
|
||||||
|
"bmp" => "image/bmp",
|
||||||
|
_ => "image/png",
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -97,10 +97,8 @@ public sealed class AssistantSwitch : StatefulAssistantComponentBase
|
|||||||
|
|
||||||
public override string UserPromptFallback(AssistantState state)
|
public override string UserPromptFallback(AssistantState state)
|
||||||
{
|
{
|
||||||
var userDecision = false;
|
|
||||||
|
|
||||||
var promptFragment = $"{Environment.NewLine}context:{Environment.NewLine}{this.UserPrompt}{Environment.NewLine}---{Environment.NewLine}";
|
var promptFragment = $"{Environment.NewLine}context:{Environment.NewLine}{this.UserPrompt}{Environment.NewLine}---{Environment.NewLine}";
|
||||||
state.Bools.TryGetValue(this.Name, out userDecision);
|
state.Bools.TryGetValue(this.Name, out var userDecision);
|
||||||
promptFragment += $"user decision: {userDecision}";
|
promptFragment += $"user decision: {userDecision}";
|
||||||
|
|
||||||
return promptFragment;
|
return promptFragment;
|
||||||
|
|||||||
@ -108,10 +108,8 @@ internal sealed class AssistantTextArea : StatefulAssistantComponentBase
|
|||||||
|
|
||||||
public override string UserPromptFallback(AssistantState state)
|
public override string UserPromptFallback(AssistantState state)
|
||||||
{
|
{
|
||||||
var userInput = string.Empty;
|
|
||||||
|
|
||||||
var promptFragment = $"context:{Environment.NewLine}{this.UserPrompt}{Environment.NewLine}---{Environment.NewLine}";
|
var promptFragment = $"context:{Environment.NewLine}{this.UserPrompt}{Environment.NewLine}---{Environment.NewLine}";
|
||||||
if (state.Text.TryGetValue(this.Name, out userInput) && !string.IsNullOrWhiteSpace(userInput))
|
if (state.Text.TryGetValue(this.Name, out var userInput) && !string.IsNullOrWhiteSpace(userInput))
|
||||||
promptFragment += $"user prompt:{Environment.NewLine}{userInput}";
|
promptFragment += $"user prompt:{Environment.NewLine}{userInput}";
|
||||||
|
|
||||||
return promptFragment;
|
return promptFragment;
|
||||||
|
|||||||
@ -1,7 +1,12 @@
|
|||||||
|
using System.Globalization;
|
||||||
|
|
||||||
namespace AIStudio.Tools.PluginSystem.Assistants.DataModel;
|
namespace AIStudio.Tools.PluginSystem.Assistants.DataModel;
|
||||||
|
|
||||||
internal sealed class AssistantTimePicker : StatefulAssistantComponentBase
|
internal sealed class AssistantTimePicker : StatefulAssistantComponentBase
|
||||||
{
|
{
|
||||||
|
private static readonly CultureInfo INVARIANT_CULTURE = CultureInfo.InvariantCulture;
|
||||||
|
private static readonly string[] FALLBACK_TIME_FORMATS = ["HH:mm", "HH:mm:ss", "hh:mm tt", "h:mm tt"];
|
||||||
|
|
||||||
public override AssistantComponentType Type => AssistantComponentType.TIME_PICKER;
|
public override AssistantComponentType Type => AssistantComponentType.TIME_PICKER;
|
||||||
public override Dictionary<string, object> Props { get; set; } = new();
|
public override Dictionary<string, object> Props { get; set; } = new();
|
||||||
public override List<IAssistantComponent> Children { get; set; } = new();
|
public override List<IAssistantComponent> Children { get; set; } = new();
|
||||||
@ -82,10 +87,8 @@ internal sealed class AssistantTimePicker : StatefulAssistantComponentBase
|
|||||||
|
|
||||||
public override string UserPromptFallback(AssistantState state)
|
public override string UserPromptFallback(AssistantState state)
|
||||||
{
|
{
|
||||||
var userInput = string.Empty;
|
|
||||||
|
|
||||||
var promptFragment = $"context:{Environment.NewLine}{this.UserPrompt}{Environment.NewLine}---{Environment.NewLine}";
|
var promptFragment = $"context:{Environment.NewLine}{this.UserPrompt}{Environment.NewLine}---{Environment.NewLine}";
|
||||||
if (state.Times.TryGetValue(this.Name, out userInput) && !string.IsNullOrWhiteSpace(userInput))
|
if (state.Times.TryGetValue(this.Name, out var userInput) && !string.IsNullOrWhiteSpace(userInput))
|
||||||
promptFragment += $"user prompt:{Environment.NewLine}{userInput}";
|
promptFragment += $"user prompt:{Environment.NewLine}{userInput}";
|
||||||
|
|
||||||
return promptFragment;
|
return promptFragment;
|
||||||
@ -100,4 +103,45 @@ internal sealed class AssistantTimePicker : StatefulAssistantComponentBase
|
|||||||
|
|
||||||
return this.AmPm ? "hh:mm tt" : "HH:mm";
|
return this.AmPm ? "hh:mm tt" : "HH:mm";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TimeSpan? ParseValue(string? value)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(value))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return TryParseTime(value, this.GetTimeFormat(), out var parsedTime) ? parsedTime : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string FormatValue(TimeSpan? value) => value.HasValue ? FormatTime(value.Value, this.GetTimeFormat()) : string.Empty;
|
||||||
|
|
||||||
|
private static bool TryParseTime(string value, string? format, out TimeSpan parsedTime)
|
||||||
|
{
|
||||||
|
if ((!string.IsNullOrWhiteSpace(format) &&
|
||||||
|
DateTime.TryParseExact(value, format, INVARIANT_CULTURE, DateTimeStyles.AllowWhiteSpaces, out var dateTime)) ||
|
||||||
|
DateTime.TryParseExact(value, FALLBACK_TIME_FORMATS, INVARIANT_CULTURE, DateTimeStyles.AllowWhiteSpaces, out dateTime))
|
||||||
|
{
|
||||||
|
parsedTime = dateTime.TimeOfDay;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TimeSpan.TryParse(value, INVARIANT_CULTURE, out parsedTime))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
parsedTime = TimeSpan.Zero;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string FormatTime(TimeSpan value, string? format)
|
||||||
|
{
|
||||||
|
var dateTime = DateTime.Today.Add(value);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return dateTime.ToString(string.IsNullOrWhiteSpace(format) ? FALLBACK_TIME_FORMATS[0] : format, INVARIANT_CULTURE);
|
||||||
|
}
|
||||||
|
catch (FormatException)
|
||||||
|
{
|
||||||
|
return dateTime.ToString(FALLBACK_TIME_FORMATS[0], INVARIANT_CULTURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
using System.Text;
|
||||||
using AIStudio.Assistants.Dynamic;
|
using AIStudio.Assistants.Dynamic;
|
||||||
|
|
||||||
namespace AIStudio.Tools.PluginSystem.Assistants.DataModel;
|
namespace AIStudio.Tools.PluginSystem.Assistants.DataModel;
|
||||||
@ -48,17 +49,18 @@ internal sealed class AssistantWebContentReader : StatefulAssistantComponentBase
|
|||||||
|
|
||||||
public override string UserPromptFallback(AssistantState state)
|
public override string UserPromptFallback(AssistantState state)
|
||||||
{
|
{
|
||||||
var promptFragment = string.Empty;
|
var promptFragment = new StringBuilder();
|
||||||
|
|
||||||
if (state.WebContent.TryGetValue(this.Name, out var webState))
|
if (state.WebContent.TryGetValue(this.Name, out var webState))
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrWhiteSpace(this.UserPrompt))
|
if (!string.IsNullOrWhiteSpace(this.UserPrompt))
|
||||||
promptFragment = $"{Environment.NewLine}context:{Environment.NewLine}{this.UserPrompt}{Environment.NewLine}---{Environment.NewLine}";
|
promptFragment.Append($"context:{Environment.NewLine}{this.UserPrompt}{Environment.NewLine}---{Environment.NewLine}");
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(webState.Content))
|
if (!string.IsNullOrWhiteSpace(webState.Content))
|
||||||
promptFragment = $"user prompt:{Environment.NewLine}{webState.Content}";
|
promptFragment.Append($"user prompt:{Environment.NewLine}{webState.Content}");
|
||||||
}
|
}
|
||||||
|
|
||||||
return promptFragment;
|
return promptFragment.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user