Fixed chat provider, profile, & templates not updating live

This commit is contained in:
Thorsten Sommer 2026-06-21 15:59:02 +02:00
parent 740a92b1dc
commit 799ebef587
Signed by untrusted user who does not match committer: tsommer
GPG Key ID: 371BBA77A02C0108
6 changed files with 102 additions and 5 deletions

View File

@ -503,6 +503,36 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
this.currentChatTemplate = this.SettingsManager.GetChatTemplateById(this.currentChatTemplate.Id); this.currentChatTemplate = this.SettingsManager.GetChatTemplateById(this.currentChatTemplate.Id);
} }
private async Task RefreshChatSelectionsAfterConfigurationChange()
{
var previousProvider = this.Provider;
var previousChatTemplate = this.currentChatTemplate;
var chatProviderId = this.ChatThread?.SelectedProvider;
this.Provider = this.SettingsManager.GetChatProviderForLoadedChat(chatProviderId);
if (this.Provider != previousProvider)
await this.ProviderChanged.InvokeAsync(this.Provider);
if (this.ChatThread is null)
{
this.currentProfile = this.SettingsManager.GetPreselectedProfile(Tools.Components.CHAT);
this.currentChatTemplate = this.SettingsManager.GetPreselectedChatTemplate(Tools.Components.CHAT);
}
else
{
this.currentProfile = string.IsNullOrWhiteSpace(this.ChatThread.SelectedProfile)
? this.SettingsManager.GetProfileById(this.currentProfile.Id)
: this.SettingsManager.GetProfileById(this.ChatThread.SelectedProfile);
this.currentChatTemplate = string.IsNullOrWhiteSpace(this.ChatThread.SelectedChatTemplate)
? this.SettingsManager.GetChatTemplateById(this.currentChatTemplate.Id)
: this.SettingsManager.GetChatTemplateById(this.ChatThread.SelectedChatTemplate);
}
if (!this.ComposerState.HasUserDraft && previousChatTemplate != this.currentChatTemplate)
this.ComposerState.ApplyTemplate(this.currentChatTemplate);
}
private IReadOnlyList<DataSourceAgentSelected> GetAgentSelectedDataSources() private IReadOnlyList<DataSourceAgentSelected> GetAgentSelectedDataSources()
{ {
if (this.ChatThread is null) if (this.ChatThread is null)
@ -1082,11 +1112,8 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
break; break;
case Event.CONFIGURATION_CHANGED: case Event.CONFIGURATION_CHANGED:
var previousChatTemplate = this.currentChatTemplate; case Event.PLUGINS_RELOADED:
this.RefreshCurrentProfileAndChatTemplate(); await this.RefreshChatSelectionsAfterConfigurationChange();
if (!this.ComposerState.HasUserDraft && previousChatTemplate != this.currentChatTemplate)
this.ComposerState.ApplyTemplate(this.currentChatTemplate);
this.StateHasChanged(); this.StateHasChanged();
break; break;

View File

@ -32,6 +32,16 @@ public partial class ChatTemplateSelection : MSGComponentBase
private string MarginClass => $"{this.MarginLeft} {this.MarginRight}"; private string MarginClass => $"{this.MarginLeft} {this.MarginRight}";
#region Overrides of ComponentBase
protected override async Task OnInitializedAsync()
{
this.ApplyFilters([], [ Event.CONFIGURATION_CHANGED ]);
await base.OnInitializedAsync();
}
#endregion
private string ChatTemplateIcon(ChatTemplate chatTemplate) private string ChatTemplateIcon(ChatTemplate chatTemplate)
{ {
if (chatTemplate.IsEnterpriseConfiguration) if (chatTemplate.IsEnterpriseConfiguration)
@ -61,4 +71,16 @@ public partial class ChatTemplateSelection : MSGComponentBase
}; };
await this.DialogService.ShowAsync<SettingsDialogChatTemplate>(T("Open Chat Template Options"), dialogParameters, DialogOptions.FULLSCREEN); await this.DialogService.ShowAsync<SettingsDialogChatTemplate>(T("Open Chat Template Options"), dialogParameters, DialogOptions.FULLSCREEN);
} }
#region Overrides of MSGComponentBase
protected override Task ProcessIncomingMessage<T>(ComponentBase? sendingComponent, Event triggeredEvent, T? data) where T : default
{
if (triggeredEvent is Event.CONFIGURATION_CHANGED or Event.PLUGINS_RELOADED)
this.StateHasChanged();
return Task.CompletedTask;
}
#endregion
} }

View File

@ -38,6 +38,16 @@ public partial class ProfileSelection : MSGComponentBase
private string MarginClass => $"{this.MarginLeft} {this.MarginRight}"; private string MarginClass => $"{this.MarginLeft} {this.MarginRight}";
#region Overrides of ComponentBase
protected override async Task OnInitializedAsync()
{
this.ApplyFilters([], [ Event.CONFIGURATION_CHANGED ]);
await base.OnInitializedAsync();
}
#endregion
private string ProfileIcon(Profile profile) private string ProfileIcon(Profile profile)
{ {
if (profile.IsEnterpriseConfiguration) if (profile.IsEnterpriseConfiguration)
@ -57,4 +67,16 @@ public partial class ProfileSelection : MSGComponentBase
var dialogParameters = new DialogParameters(); var dialogParameters = new DialogParameters();
await this.DialogService.ShowAsync<SettingsDialogProfiles>(T("Open Profile Options"), dialogParameters, DialogOptions.FULLSCREEN); await this.DialogService.ShowAsync<SettingsDialogProfiles>(T("Open Profile Options"), dialogParameters, DialogOptions.FULLSCREEN);
} }
#region Overrides of MSGComponentBase
protected override Task ProcessIncomingMessage<T>(ComponentBase? sendingComponent, Event triggeredEvent, T? data) where T : default
{
if (triggeredEvent is Event.CONFIGURATION_CHANGED or Event.PLUGINS_RELOADED)
this.StateHasChanged();
return Task.CompletedTask;
}
#endregion
} }

View File

@ -26,6 +26,16 @@ public partial class ProviderSelection : MSGComponentBase
[Inject] [Inject]
private ILogger<ProviderSelection> Logger { get; init; } = null!; private ILogger<ProviderSelection> Logger { get; init; } = null!;
#region Overrides of ComponentBase
protected override async Task OnInitializedAsync()
{
this.ApplyFilters([], [ Event.CONFIGURATION_CHANGED ]);
await base.OnInitializedAsync();
}
#endregion
private async Task SelectionChanged(AIStudio.Settings.Provider provider) private async Task SelectionChanged(AIStudio.Settings.Provider provider)
{ {
this.ProviderSettings = provider; this.ProviderSettings = provider;
@ -62,4 +72,16 @@ public partial class ProviderSelection : MSGComponentBase
break; break;
} }
} }
#region Overrides of MSGComponentBase
protected override Task ProcessIncomingMessage<T>(ComponentBase? sendingComponent, Event triggeredEvent, T? data) where T : default
{
if (triggeredEvent is Event.CONFIGURATION_CHANGED or Event.PLUGINS_RELOADED)
this.StateHasChanged();
return Task.CompletedTask;
}
#endregion
} }

View File

@ -65,6 +65,9 @@ public abstract class SettingsDialogBase : MSGComponentBase
switch (triggeredEvent) switch (triggeredEvent)
{ {
case Event.CONFIGURATION_CHANGED: case Event.CONFIGURATION_CHANGED:
case Event.PLUGINS_RELOADED:
this.UpdateProviders();
this.UpdateEmbeddingProviders();
this.StateHasChanged(); this.StateHasChanged();
break; break;
} }

View File

@ -5,5 +5,6 @@
- Added support for organization-managed provider confidence settings. Configuration plugins can now set confidence presets, custom confidence schemes, and an app-wide minimum confidence level. - Added support for organization-managed provider confidence settings. Configuration plugins can now set confidence presets, custom confidence schemes, and an app-wide minimum confidence level.
- Added support for organization-trusted providers in data source security checks. Configuration plugins can now mark specific provider instances as trusted for data source usage and local embedding warnings. - Added support for organization-trusted providers in data source security checks. Configuration plugins can now mark specific provider instances as trusted for data source usage and local embedding warnings.
- Changed provider confidence settings to appear in their own settings panel, because they apply to LLM, embedding, and transcription providers. - Changed provider confidence settings to appear in their own settings panel, because they apply to LLM, embedding, and transcription providers.
- Fixed chat provider, profile, and template selections not updating live after configuration plugins were changed.
- Fixed organization-managed chat templates not showing the correct icon in the chat template selection menu. - Fixed organization-managed chat templates not showing the correct icon in the chat template selection menu.
- Fixed self-hosted provider API keys sometimes being stored under a localized name. AI Studio now uses a stable key name, keeps correct entries working, and automatically migrates known localized entries for LLM, transcription, and embedding providers. Organizations using configuration plugins do not need to change their plugins; affected users who still see an invalid API key warning should open the provider, transcription, or embedding settings and update the API key once. - Fixed self-hosted provider API keys sometimes being stored under a localized name. AI Studio now uses a stable key name, keeps correct entries working, and automatically migrates known localized entries for LLM, transcription, and embedding providers. Organizations using configuration plugins do not need to change their plugins; affected users who still see an invalid API key warning should open the provider, transcription, or embedding settings and update the API key once.