Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/MindWork AI Studio/Assistants/AssistantBase.razor
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@

@if (this.AllowProfiles && this.ShowProfileSelection)
{
<ProfileSelection MarginLeft="" @bind-CurrentProfile="@this.CurrentProfile"/>
<ProfileSelection MarginLeft="" @bind-SelectedProfileIds="@this.CurrentProfileIds"/>
}

@* No selection where the assistant's own rules already name the tools: *@
Expand Down
15 changes: 9 additions & 6 deletions app/MindWork AI Studio/Assistants/AssistantBase.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ protected override async Task OnInitializedAsync()

this.MightPreselectValues();
this.ProviderSettings = this.SettingsManager.GetPreselectedProvider(this.Component);
this.CurrentProfile = this.SettingsManager.GetPreselectedProfile(this.Component);
this.CurrentProfileIds = this.SettingsManager.GetPreselectedProfiles(this.Component).Select(profile => profile.Id).ToHashSet(StringComparer.OrdinalIgnoreCase);
this.CurrentChatTemplate = this.SettingsManager.GetPreselectedChatTemplate(this.Component);
this.SelectedToolIds = this.SettingsManager.GetDefaultToolIds(this.Component);
await this.OnDefaultsAppliedAsync();
Expand Down Expand Up @@ -362,7 +362,7 @@ protected void CreateChatThread()
{
IncludeDateTime = false,
SelectedProvider = this.ProviderSettings.Id,
SelectedProfile = this.AllowProfiles ? this.CurrentProfile.Id : Profile.NO_PROFILE.Id,
SelectedProfileIds = this.AllowProfiles ? [..this.CurrentProfileIds] : [],
SystemPrompt = this.SystemPrompt,
WorkspaceId = Guid.Empty,
ChatId = Guid.NewGuid(),
Expand All @@ -379,7 +379,7 @@ protected Guid CreateChatThread(Guid workspaceId, string name)
{
IncludeDateTime = false,
SelectedProvider = this.ProviderSettings.Id,
SelectedProfile = this.AllowProfiles ? this.CurrentProfile.Id : Profile.NO_PROFILE.Id,
SelectedProfileIds = this.AllowProfiles ? [..this.CurrentProfileIds] : [],
SystemPrompt = this.SystemPrompt,
WorkspaceId = workspaceId,
ChatId = chatId,
Expand All @@ -400,7 +400,7 @@ private Task RefreshProviderSelectionFromConfigurationAsync()
protected virtual void ResetProviderAndProfileSelection()
{
this.ProviderSettings = this.SettingsManager.GetPreselectedProvider(this.Component);
this.CurrentProfile = this.SettingsManager.GetPreselectedProfile(this.Component);
this.CurrentProfileIds = this.SettingsManager.GetPreselectedProfiles(this.Component).Select(profile => profile.Id).ToHashSet(StringComparer.OrdinalIgnoreCase);
this.CurrentChatTemplate = this.SettingsManager.GetPreselectedChatTemplate(this.Component);
this.SelectedToolIds = this.SettingsManager.GetDefaultToolIds(this.Component);
}
Expand Down Expand Up @@ -936,7 +936,10 @@ private async Task AttachAssistantSession(AssistantSessionSnapshot snapshot, boo
this.IsProcessing = snapshot.IsActive;

if (!snapshot.IsActive)
{
this.CancellationTokenSource = null;
this.CurrentProfileIds = this.SettingsManager.GetPreselectedProfiles(this.Component).Select(profile => profile.Id).ToHashSet(StringComparer.OrdinalIgnoreCase);
}

if (restoreClientOnlyContent)
await this.OnAssistantSessionAttachedAsync(snapshot);
Expand Down Expand Up @@ -975,7 +978,7 @@ private Dictionary<string, IAssistantSessionSnapshotField> CaptureAssistantSessi
var state = new AssistantSessionStateWriter();
state.Set(PROVIDER_SETTINGS_STATE_KEY, this.ProviderSettings);
state.Set(INPUT_IS_VALID_STATE_KEY, this.InputIsValid);
state.Set(CURRENT_PROFILE_STATE_KEY, this.CurrentProfile);
state.SetHashSet(CURRENT_PROFILE_IDS_STATE_KEY, this.CurrentProfileIds);
state.Set(CURRENT_CHAT_TEMPLATE_STATE_KEY, this.CurrentChatTemplate);
state.Set(CHAT_THREAD_STATE_KEY, this.ChatThread);
state.Set(LAST_USER_PROMPT_STATE_KEY, this.LastUserPrompt);
Expand Down Expand Up @@ -1003,7 +1006,7 @@ private void ImportAssistantSessionState(IReadOnlyDictionary<string, IAssistantS
var reader = new AssistantSessionStateReader(state, this.Title);
reader.Restore(PROVIDER_SETTINGS_STATE_KEY, value => this.ProviderSettings = value);
reader.Restore(INPUT_IS_VALID_STATE_KEY, value => this.InputIsValid = value);
reader.Restore(CURRENT_PROFILE_STATE_KEY, value => this.CurrentProfile = value);
reader.Restore(CURRENT_PROFILE_IDS_STATE_KEY, value => this.CurrentProfileIds = value.ToHashSet(StringComparer.OrdinalIgnoreCase));
reader.Restore(CURRENT_CHAT_TEMPLATE_STATE_KEY, value => this.CurrentChatTemplate = value);
reader.Restore(CHAT_THREAD_STATE_KEY, value => this.ChatThread = value);
reader.Restore(LAST_USER_PROMPT_STATE_KEY, value => this.LastUserPrompt = value);
Expand Down
4 changes: 2 additions & 2 deletions app/MindWork AI Studio/Assistants/AssistantLowerBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public abstract class AssistantLowerBase : MSGComponentBase

protected static readonly AssistantSessionStateKey<AIStudio.Settings.Provider> PROVIDER_SETTINGS_STATE_KEY = new(nameof(ProviderSettings));
protected static readonly AssistantSessionStateKey<bool> INPUT_IS_VALID_STATE_KEY = new(nameof(InputIsValid));
protected static readonly AssistantSessionStateKey<Profile> CURRENT_PROFILE_STATE_KEY = new(nameof(CurrentProfile));
protected static readonly AssistantSessionStateKey<HashSet<string>> CURRENT_PROFILE_IDS_STATE_KEY = new(nameof(CurrentProfileIds));
protected static readonly AssistantSessionStateKey<ChatTemplate> CURRENT_CHAT_TEMPLATE_STATE_KEY = new(nameof(CurrentChatTemplate));
protected static readonly AssistantSessionStateKey<ChatThread?> CHAT_THREAD_STATE_KEY = new(nameof(ChatThread));
protected static readonly AssistantSessionStateKey<IContent?> LAST_USER_PROMPT_STATE_KEY = new(nameof(LastUserPrompt));
Expand All @@ -26,7 +26,7 @@ public abstract class AssistantLowerBase : MSGComponentBase

protected AIStudio.Settings.Provider ProviderSettings = Settings.Provider.NONE;
protected bool InputIsValid;
protected Profile CurrentProfile = Profile.NO_PROFILE;
protected HashSet<string> CurrentProfileIds = [];
protected ChatTemplate CurrentChatTemplate = ChatTemplate.NO_CHAT_TEMPLATE;
protected ChatThread? ChatThread;
protected IContent? LastUserPrompt;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ private static string BuildUserPrompt(string fileName, string fileContent)
{
IncludeDateTime = false,
SelectedProvider = this.ProviderSettings.Id,
SelectedProfile = Profile.NO_PROFILE.Id,
SelectedProfileIds = [],
SelectedToolIds = [..this.SelectedToolIds],
SystemPrompt = this.SystemPrompt,
WorkspaceId = Guid.Empty,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
<DirectChatLauncherForm WorkspaceName="@this.launcherWorkspaceName"
WorkspaceNameChanged="@this.LauncherWorkspaceNameChanged"
@bind-ProviderId="@this.launcherProviderId"
@bind-ProfileId="@this.launcherProfileId"
@bind-ProfileIds="@this.launcherProfileIds"
@bind-ChatTemplateId="@this.launcherChatTemplateId"
@bind-DataSourceIds="@this.launcherDataSourceIds"
@bind-ToolIds="@this.launcherToolIds"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ Transform user-provided requirements into transparent assistant behavior.
private string descriptionSuggestion = string.Empty;
private string launcherWorkspaceName = string.Empty;
private string launcherProviderId = string.Empty;
private string launcherProfileId = string.Empty;
private HashSet<string>? launcherProfileIds;
private string launcherChatTemplateId = string.Empty;
private IEnumerable<string> launcherDataSourceIds = [];
private HashSet<string> launcherToolIds = [];
Expand Down Expand Up @@ -137,7 +137,7 @@ Transform user-provided requirements into transparent assistant behavior.
private static readonly AssistantSessionStateKey<string> DESCRIPTION_SUGGESTION_STATE_KEY = new(nameof(descriptionSuggestion));
private static readonly AssistantSessionStateKey<string> LAUNCHER_WORKSPACE_NAME_STATE_KEY = new(nameof(launcherWorkspaceName));
private static readonly AssistantSessionStateKey<string> LAUNCHER_PROVIDER_ID_STATE_KEY = new(nameof(launcherProviderId));
private static readonly AssistantSessionStateKey<string> LAUNCHER_PROFILE_ID_STATE_KEY = new(nameof(launcherProfileId));
private static readonly AssistantSessionStateKey<HashSet<string>?> LAUNCHER_PROFILE_IDS_STATE_KEY = new(nameof(launcherProfileIds));
private static readonly AssistantSessionStateKey<string> LAUNCHER_CHAT_TEMPLATE_ID_STATE_KEY = new(nameof(launcherChatTemplateId));
private static readonly AssistantSessionStateKey<List<string>> LAUNCHER_DATA_SOURCE_IDS_STATE_KEY = new(nameof(launcherDataSourceIds));
private static readonly AssistantSessionStateKey<HashSet<string>> LAUNCHER_TOOL_IDS_STATE_KEY = new(nameof(launcherToolIds));
Expand Down Expand Up @@ -243,7 +243,7 @@ protected override void ResetForm()
this.descriptionSuggestion = string.Empty;
this.launcherWorkspaceName = string.Empty;
this.launcherProviderId = string.Empty;
this.launcherProfileId = string.Empty;
this.launcherProfileIds = null;
this.launcherChatTemplateId = string.Empty;
this.launcherDataSourceIds = [];
this.launcherToolIds = [];
Expand Down Expand Up @@ -280,7 +280,7 @@ protected override void CaptureCustomAssistantSessionState(AssistantSessionState
state.Set(DESCRIPTION_SUGGESTION_STATE_KEY, this.descriptionSuggestion);
state.Set(LAUNCHER_WORKSPACE_NAME_STATE_KEY, this.launcherWorkspaceName);
state.Set(LAUNCHER_PROVIDER_ID_STATE_KEY, this.launcherProviderId);
state.Set(LAUNCHER_PROFILE_ID_STATE_KEY, this.launcherProfileId);
state.Set(LAUNCHER_PROFILE_IDS_STATE_KEY, this.launcherProfileIds);
state.Set(LAUNCHER_CHAT_TEMPLATE_ID_STATE_KEY, this.launcherChatTemplateId);
state.SetList(LAUNCHER_DATA_SOURCE_IDS_STATE_KEY, this.launcherDataSourceIds);
state.SetHashSet(LAUNCHER_TOOL_IDS_STATE_KEY, this.launcherToolIds);
Expand Down Expand Up @@ -322,7 +322,7 @@ protected override void RestoreCustomAssistantSessionState(AssistantSessionState
state.Restore(DESCRIPTION_SUGGESTION_STATE_KEY, value => this.descriptionSuggestion = value);
state.Restore(LAUNCHER_WORKSPACE_NAME_STATE_KEY, value => this.launcherWorkspaceName = value);
state.Restore(LAUNCHER_PROVIDER_ID_STATE_KEY, value => this.launcherProviderId = value);
state.Restore(LAUNCHER_PROFILE_ID_STATE_KEY, value => this.launcherProfileId = value);
state.Restore(LAUNCHER_PROFILE_IDS_STATE_KEY, value => this.launcherProfileIds = value);
state.Restore(LAUNCHER_CHAT_TEMPLATE_ID_STATE_KEY, value => this.launcherChatTemplateId = value);
state.Restore(LAUNCHER_DATA_SOURCE_IDS_STATE_KEY, value => this.launcherDataSourceIds = value);
state.Restore(LAUNCHER_TOOL_IDS_STATE_KEY, value => this.launcherToolIds = ToolSelectionRules.NormalizeSelection(value));
Expand Down Expand Up @@ -553,7 +553,7 @@ private string GetSelectedAssistantComponentTypes()
return new(
this.launcherWorkspaceName.Trim(),
NullIfEmpty(this.launcherProviderId),
NullIfEmpty(this.launcherProfileId),
this.launcherProfileIds?.Order(StringComparer.OrdinalIgnoreCase).ToArray(),
NullIfEmpty(this.launcherChatTemplateId),
dataSourceIds.Length == 0 ? null : dataSourceIds,
toolIds.Length == 0 ? null : toolIds);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ internal sealed class AssistantBuilderChatLaunchMetadata
{
public string WorkspaceName { get; init; } = string.Empty;
public string? ProviderId { get; init; }
public string? ProfileId { get; init; }
public string[]? ProfileIds { get; init; }
public string? ChatTemplateId { get; init; }
public string[]? DataSourceIds { get; init; }
public string[]? ToolIds { get; init; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ private static bool IsValidChatLaunchMetadata(AssistantBuilderChatLaunchMetadata
return false;

if (!IsOptionalGuid(launch.ProviderId, allowEmpty: false) ||
!IsOptionalGuid(launch.ProfileId, allowEmpty: true) ||
!IsOptionalGuidList(launch.ProfileIds, allowEmptyList: true) ||
!IsOptionalGuid(launch.ChatTemplateId, allowEmpty: true))
return false;

Expand All @@ -154,6 +154,11 @@ toolIds is null ||
private static bool IsOptionalGuid(string? value, bool allowEmpty) => value is null ||
Guid.TryParse(value, out var parsed) && (allowEmpty || parsed != Guid.Empty);

private static bool IsOptionalGuidList(string[]? values, bool allowEmptyList) => values is null ||
(allowEmptyList || values.Length > 0) &&
values.All(value => Guid.TryParse(value, out var parsed) && parsed != Guid.Empty) &&
values.Distinct(StringComparer.OrdinalIgnoreCase).Count() == values.Length;

/// <summary>
/// Reads the first complete JSON object out of a model answer that may carry text around it.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ else

<ConfigurationProviderSelection Component="Components.DOCUMENT_ANALYSIS_ASSISTANT" Data="@this.availableLLMProviders" Disabled="@(() => this.IsNoPolicySelectedOrProtected)" SelectedValue="@(() => this.policyPreselectedProviderId)" SelectionUpdate="@this.PolicyPreselectedProviderWasChanged" ExplicitMinimumConfidence="@this.GetPolicyMinimumConfidenceLevel()"/>

<ConfigurationSelect OptionDescription="@T("Preselect a profile")" Disabled="@(() => this.IsNoPolicySelected)" SelectedValue="@(() => this.policyPreselectedProfile)" Data="@ConfigurationSelectDataFactory.GetComponentProfilesData(this.SettingsManager.ConfigurationData.Profiles)" SelectionUpdateAsync="@(async selection => await this.PolicyPreselectedProfileWasChangedAsync(selection))" OptionHelp="@T("Choose whether the policy should use the app default profile, no profile, or a specific profile.")"/>
<ProfilePreselectionConfiguration OptionDescription="@T("Preselect profiles")" Disabled="@(() => this.IsNoPolicySelected)" SelectedProfileIds="@(() => this.policyPreselectedProfileIds)" SelectionUpdateAsync="@this.PolicyPreselectedProfilesWereChangedAsync" OptionHelp="@T("Use the app default profiles, no profiles, or a custom selection that completely replaces the app default.")"/>

<MudTextSwitch Disabled="@(this.IsNoPolicySelected || (this.selectedPolicy?.IsEnterpriseConfiguration ?? true))" Label="@T("Would you like to protect this policy so that you cannot accidentally edit or delete it?")" Value="@this.policyIsProtected" ValueChanged="async state => await this.PolicyProtectionWasChanged(state)" LabelOn="@T("Yes, protect this policy")" LabelOff="@T("No, the policy can be edited")" />

Expand Down
Loading