mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-10-05 01:49:41 +00:00
First review
This commit is contained in:
1 parent
0e63f93696
commit
ad6b700978
10 files changed
+108
-99
No files matched your search
@@ -17,10 +17,15 @@
|
||||
@for (var index = 0; index < this.attachmentsToRelink.Count; index++)
|
||||
{
|
||||
var currentIndex = index;
|
||||
<MudTextField T="string" Value="@this.attachmentsToRelink[index].ReplacementPath"
|
||||
ValueChanged="@(value => this.attachmentsToRelink[currentIndex] = (this.attachmentsToRelink[currentIndex].OriginalPath, value))"
|
||||
Label="@string.Format(T("Relink attachment: {0}"), this.attachmentsToRelink[index].OriginalPath)"
|
||||
HelperText="@T("Enter an absolute path to an existing local file before saving.")" Variant="Variant.Outlined" Class="mb-2" />
|
||||
<MudStack Row="true" AlignItems="AlignItems.Center" Class="mb-2">
|
||||
<MudTextField T="string" Value="@this.attachmentsToRelink[index].ReplacementPath"
|
||||
ValueChanged="@(value => this.UpdateRelinkPath(currentIndex, value))"
|
||||
Label="@string.Format(T("Relink attachment: {0}"), this.attachmentsToRelink[index].OriginalPath)"
|
||||
HelperText="@T("Enter an absolute path to an existing local file, or remove this attachment.")" Variant="Variant.Outlined" />
|
||||
<MudTooltip Text="@T("Remove this attachment")">
|
||||
<MudIconButton Icon="@Icons.Material.Filled.Delete" Color="Color.Error" OnClick="@(() => this.RemoveAttachmentToRelink(currentIndex))" />
|
||||
</MudTooltip>
|
||||
</MudStack>
|
||||
}
|
||||
}
|
||||
@* A drop anywhere in this dialog belongs to the dialog, not to the page behind it: *@
|
||||
|
||||
@@ -200,33 +200,9 @@ public partial class ChatTemplateDialog : MSGComponentBase
|
||||
|
||||
private async Task ImportConfiguration(LuaTable table)
|
||||
{
|
||||
ConfigurationImportFields.ValidateExportId(table);
|
||||
ConfigurationImportFields.String(table, "Name");
|
||||
ConfigurationImportFields.String(table, "SystemPrompt");
|
||||
ConfigurationImportFields.String(table, "PredefinedUserPrompt", required: false);
|
||||
ConfigurationImportFields.Bool(table, "AllowProfileUsage");
|
||||
var messages = ConfigurationImportFields.Table(table, "ExampleConversation");
|
||||
for (var index = 1; index <= messages.ArrayLength; index++)
|
||||
{
|
||||
if (messages[index].Type is not LuaValueType.Table || !messages[index].TryRead<LuaTable>(out var message))
|
||||
throw new FormatException("An example conversation entry is not a table.");
|
||||
ConfigurationImportFields.Enum<ChatRole>(message, "Role");
|
||||
if (string.IsNullOrWhiteSpace(ConfigurationImportFields.String(message, "Content")))
|
||||
throw new FormatException("An example conversation message is empty.");
|
||||
}
|
||||
if (table.TryGetValue("ToolIds", out _))
|
||||
ConfigurationImportFields.Strings(table, "ToolIds");
|
||||
if (table.TryGetValue("DataSourceOptions", out _))
|
||||
{
|
||||
var options = ConfigurationImportFields.Table(table, "DataSourceOptions");
|
||||
ConfigurationImportFields.Bool(options, "DisableDataSources");
|
||||
ConfigurationImportFields.Bool(options, "AutomaticDataSourceSelection");
|
||||
ConfigurationImportFields.Bool(options, "AutomaticValidation");
|
||||
if (options.TryGetValue("PreselectedDataSourceIds", out _))
|
||||
ConfigurationImportFields.Strings(options, "PreselectedDataSourceIds");
|
||||
}
|
||||
ConfigurationSnippetImportValidation.Validate("CHAT_TEMPLATES", table);
|
||||
if (!ChatTemplate.TryParseChatTemplateTable(0, table, Guid.Empty, string.Empty, out var parsed) || parsed is not ChatTemplate template)
|
||||
throw new FormatException("The chat template fields are malformed.");
|
||||
throw new FormatException(T("The chat template fields are malformed."));
|
||||
var paths = ConfigurationImportFields.Strings(table, "FileAttachments");
|
||||
var validAttachments = new HashSet<FileAttachment>();
|
||||
var toRelink = new List<(string OriginalPath, string ReplacementPath)>();
|
||||
@@ -260,8 +236,18 @@ public partial class ChatTemplateDialog : MSGComponentBase
|
||||
var availableToolIds = (await this.ToolRegistry.GetCatalogAsync(AIStudio.Tools.Components.CHAT))
|
||||
.Select(item => item.Definition.Id).ToHashSet(StringComparer.Ordinal);
|
||||
var missingTools = this.selectedToolIds.Where(id => !availableToolIds.Contains(id)).ToList();
|
||||
var missing = missingSources.Select(id => $"data source {id}").Concat(missingTools.Select(id => $"tool {id}")).ToList();
|
||||
return missing.Count == 0 ? string.Empty : $"Unavailable references: {string.Join(", ", missing)}. Review the selection before saving.";
|
||||
var missing = missingSources.Select(ConfigurationImportFields.MissingDataSourceReference)
|
||||
.Concat(missingTools.Select(ConfigurationImportFields.MissingToolReference)).ToList();
|
||||
return ConfigurationImportFields.UnavailableReferencesIssue(missing);
|
||||
}
|
||||
|
||||
private void UpdateRelinkPath(int index, string path) => this.attachmentsToRelink[index] = (this.attachmentsToRelink[index].OriginalPath, path);
|
||||
|
||||
private void RemoveAttachmentToRelink(int index)
|
||||
{
|
||||
this.attachmentsToRelink.RemoveAt(index);
|
||||
if (this.attachmentsToRelink.Count == 0)
|
||||
this.relinkIssue = string.Empty;
|
||||
}
|
||||
|
||||
private void SetSelectedToolIds(HashSet<string> toolIds) => this.selectedToolIds = toolIds;
|
||||
@@ -365,15 +351,16 @@ public partial class ChatTemplateDialog : MSGComponentBase
|
||||
if (this.IsReadOnly)
|
||||
return;
|
||||
|
||||
// Only check the relinked attachments here. They are added right before closing, so that a
|
||||
// failed save does not leave a path behind which the user changes afterward:
|
||||
this.relinkIssue = string.Empty;
|
||||
foreach (var (originalPath, replacementPath) in this.attachmentsToRelink)
|
||||
{
|
||||
if (!ConfigurationImportFields.IsExistingLocalFile(replacementPath))
|
||||
{
|
||||
this.relinkIssue = string.Format(T("Relink the missing attachment '{0}' to an existing local file before saving."), originalPath);
|
||||
this.relinkIssue = string.Format(T("Relink the missing attachment '{0}' to an existing local file or remove it before saving."), originalPath);
|
||||
return;
|
||||
}
|
||||
this.fileAttachments.Add(FileAttachment.FromPath(replacementPath));
|
||||
}
|
||||
|
||||
await this.form.Validate();
|
||||
@@ -386,6 +373,10 @@ public partial class ChatTemplateDialog : MSGComponentBase
|
||||
if (this.isInlineEditOnGoing)
|
||||
return;
|
||||
|
||||
foreach (var (_, replacementPath) in this.attachmentsToRelink)
|
||||
this.fileAttachments.Add(FileAttachment.FromPath(replacementPath));
|
||||
this.attachmentsToRelink.Clear();
|
||||
|
||||
// Use the data model to store the chat template.
|
||||
// We just return this data to the parent component:
|
||||
var addedChatTemplateSettings = this.CreateChatTemplateSettings();
|
||||
|
||||
@@ -196,22 +196,14 @@ public partial class DataSourceERI_V1Dialog : MSGComponentBase, ISecretId
|
||||
|
||||
private Task ImportConfiguration(LuaTable table)
|
||||
{
|
||||
ConfigurationImportFields.ValidateExportId(table);
|
||||
if (ConfigurationImportFields.String(table, "Type") != "ERI_V1")
|
||||
throw new FormatException("This data source is not an ERI v1 data source.");
|
||||
ConfigurationSnippetImportValidation.Validate("DATA_SOURCES", table);
|
||||
var name = ConfigurationImportFields.String(table, "Name");
|
||||
var hostname = ConfigurationImportFields.String(table, "Hostname");
|
||||
var port = ConfigurationImportFields.Int(table, "Port");
|
||||
if (port is < 1 or > 65535)
|
||||
throw new FormatException("The 'Port' field must be between 1 and 65535.");
|
||||
var authMethod = ConfigurationImportFields.Enum<AuthMethod>(table, "AuthMethod");
|
||||
if (authMethod is AuthMethod.KERBEROS)
|
||||
throw new FormatException("Kerberos data sources cannot be imported from configuration snippets.");
|
||||
var securityPolicy = ConfigurationImportFields.Enum<DataSourceSecurity>(table, "SecurityPolicy");
|
||||
var retrievalId = ConfigurationImportFields.String(table, "SelectedRetrievalId");
|
||||
var maxMatches = ConfigurationImportFields.Int(table, "MaxMatches", 10);
|
||||
if (maxMatches is < 1 or > ushort.MaxValue)
|
||||
throw new FormatException("The 'MaxMatches' field is outside the allowed range.");
|
||||
var secretName = authMethod switch
|
||||
{
|
||||
AuthMethod.TOKEN => "Token",
|
||||
|
||||
@@ -75,13 +75,13 @@ public partial class DocumentAnalysisPolicyDialog : MSGComponentBase
|
||||
|
||||
var missing = new List<string>();
|
||||
if (!string.IsNullOrWhiteSpace(this.providerId) && this.SettingsManager.GetAllProviders().All(provider => provider.Id != this.providerId))
|
||||
missing.Add($"provider {this.providerId}");
|
||||
missing.Add(ConfigurationImportFields.MissingProviderReference(this.providerId));
|
||||
if (!string.IsNullOrWhiteSpace(this.profileId) && this.profileId != Profile.NO_PROFILE.Id && this.SettingsManager.ConfigurationData.Profiles.All(profile => profile.Id != this.profileId))
|
||||
missing.Add($"profile {this.profileId}");
|
||||
missing.Add(ConfigurationImportFields.MissingProfileReference(this.profileId));
|
||||
var availableToolIds = (await this.ToolRegistry.GetCatalogAsync(AIStudio.Tools.Components.DOCUMENT_ANALYSIS_ASSISTANT))
|
||||
.Select(item => item.Definition.Id).ToHashSet(StringComparer.Ordinal);
|
||||
missing.AddRange(this.allowedToolIds.Where(id => !availableToolIds.Contains(id)).Select(id => $"tool {id}"));
|
||||
this.referenceIssue = missing.Count == 0 ? string.Empty : $"Unavailable references: {string.Join(", ", missing)}. Review the selections before saving.";
|
||||
missing.AddRange(this.allowedToolIds.Where(id => !availableToolIds.Contains(id)).Select(ConfigurationImportFields.MissingToolReference));
|
||||
this.referenceIssue = ConfigurationImportFields.UnavailableReferencesIssue(missing);
|
||||
this.form.ResetValidation();
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user