mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2025-02-05 16:49:06 +00:00
Remember chat provider (#217)
This commit is contained in:
parent
ba6b8d2b3c
commit
0d104f5abc
@ -166,6 +166,7 @@ public abstract partial class AssistantBase : ComponentBase, IMessageBusReceiver
|
|||||||
{
|
{
|
||||||
this.chatThread = new()
|
this.chatThread = new()
|
||||||
{
|
{
|
||||||
|
SelectedProvider = this.providerSettings.Id,
|
||||||
WorkspaceId = Guid.Empty,
|
WorkspaceId = Guid.Empty,
|
||||||
ChatId = Guid.NewGuid(),
|
ChatId = Guid.NewGuid(),
|
||||||
Name = string.Empty,
|
Name = string.Empty,
|
||||||
@ -185,6 +186,7 @@ public abstract partial class AssistantBase : ComponentBase, IMessageBusReceiver
|
|||||||
var chatId = Guid.NewGuid();
|
var chatId = Guid.NewGuid();
|
||||||
this.chatThread = new()
|
this.chatThread = new()
|
||||||
{
|
{
|
||||||
|
SelectedProvider = this.providerSettings.Id,
|
||||||
WorkspaceId = workspaceId,
|
WorkspaceId = workspaceId,
|
||||||
ChatId = chatId,
|
ChatId = chatId,
|
||||||
Name = name,
|
Name = name,
|
||||||
@ -236,7 +238,12 @@ public abstract partial class AssistantBase : ComponentBase, IMessageBusReceiver
|
|||||||
Content = aiText,
|
Content = aiText,
|
||||||
};
|
};
|
||||||
|
|
||||||
this.chatThread?.Blocks.Add(this.resultingContentBlock);
|
if (this.chatThread is not null)
|
||||||
|
{
|
||||||
|
this.chatThread.Blocks.Add(this.resultingContentBlock);
|
||||||
|
this.chatThread.SelectedProvider = this.providerSettings.Id;
|
||||||
|
}
|
||||||
|
|
||||||
this.isProcessing = true;
|
this.isProcessing = true;
|
||||||
this.StateHasChanged();
|
this.StateHasChanged();
|
||||||
|
|
||||||
@ -284,7 +291,9 @@ public abstract partial class AssistantBase : ComponentBase, IMessageBusReceiver
|
|||||||
switch (destination)
|
switch (destination)
|
||||||
{
|
{
|
||||||
case Tools.Components.CHAT:
|
case Tools.Components.CHAT:
|
||||||
MessageBus.INSTANCE.DeferMessage(this, sendToData.Event, this.ConvertToChatThread);
|
var convertedChatThread = this.ConvertToChatThread;
|
||||||
|
convertedChatThread = convertedChatThread with { SelectedProvider = this.providerSettings.Id };
|
||||||
|
MessageBus.INSTANCE.DeferMessage(this, sendToData.Event, convertedChatThread);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -15,6 +15,11 @@ public sealed record ChatThread
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public Guid WorkspaceId { get; set; }
|
public Guid WorkspaceId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Specifies the provider selected for the chat thread.
|
||||||
|
/// </summary>
|
||||||
|
public string SelectedProvider { get; set; } = string.Empty;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The name of the chat thread. Usually generated by an AI model or manually edited by the user.
|
/// The name of the chat thread. Usually generated by an AI model or manually edited by the user.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -64,7 +64,6 @@ public partial class Chat : MSGComponentBase, IAsyncDisposable
|
|||||||
// Configure the spellchecking for the user input:
|
// Configure the spellchecking for the user input:
|
||||||
this.SettingsManager.InjectSpellchecking(USER_INPUT_ATTRIBUTES);
|
this.SettingsManager.InjectSpellchecking(USER_INPUT_ATTRIBUTES);
|
||||||
|
|
||||||
this.providerSettings = this.SettingsManager.GetPreselectedProvider(Tools.Components.CHAT);
|
|
||||||
this.currentProfile = this.SettingsManager.GetPreselectedProfile(Tools.Components.CHAT);
|
this.currentProfile = this.SettingsManager.GetPreselectedProfile(Tools.Components.CHAT);
|
||||||
var deferredContent = MessageBus.INSTANCE.CheckDeferredMessages<ChatThread>(Event.SEND_TO_CHAT).FirstOrDefault();
|
var deferredContent = MessageBus.INSTANCE.CheckDeferredMessages<ChatThread>(Event.SEND_TO_CHAT).FirstOrDefault();
|
||||||
if (deferredContent is not null)
|
if (deferredContent is not null)
|
||||||
@ -107,6 +106,7 @@ public partial class Chat : MSGComponentBase, IAsyncDisposable
|
|||||||
this.mustLoadChat = true;
|
this.mustLoadChat = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.SelectProviderWhenLoadingChat();
|
||||||
await base.OnInitializedAsync();
|
await base.OnInitializedAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,7 +115,12 @@ public partial class Chat : MSGComponentBase, IAsyncDisposable
|
|||||||
if (firstRender && this.chatThread is not null && this.mustStoreChat)
|
if (firstRender && this.chatThread is not null && this.mustStoreChat)
|
||||||
{
|
{
|
||||||
this.mustStoreChat = false;
|
this.mustStoreChat = false;
|
||||||
|
|
||||||
|
if(this.workspaces is not null)
|
||||||
|
await this.workspaces.StoreChat(this.chatThread);
|
||||||
|
else
|
||||||
await WorkspaceBehaviour.StoreChat(this.chatThread);
|
await WorkspaceBehaviour.StoreChat(this.chatThread);
|
||||||
|
|
||||||
this.currentWorkspaceId = this.chatThread.WorkspaceId;
|
this.currentWorkspaceId = this.chatThread.WorkspaceId;
|
||||||
this.currentWorkspaceName = await WorkspaceBehaviour.LoadWorkspaceName(this.chatThread.WorkspaceId);
|
this.currentWorkspaceName = await WorkspaceBehaviour.LoadWorkspaceName(this.chatThread.WorkspaceId);
|
||||||
}
|
}
|
||||||
@ -126,7 +131,10 @@ public partial class Chat : MSGComponentBase, IAsyncDisposable
|
|||||||
this.chatThread = await WorkspaceBehaviour.LoadChat(this.loadChat);
|
this.chatThread = await WorkspaceBehaviour.LoadChat(this.loadChat);
|
||||||
|
|
||||||
if(this.chatThread is not null)
|
if(this.chatThread is not null)
|
||||||
|
{
|
||||||
this.currentWorkspaceName = await WorkspaceBehaviour.LoadWorkspaceName(this.chatThread.WorkspaceId);
|
this.currentWorkspaceName = await WorkspaceBehaviour.LoadWorkspaceName(this.chatThread.WorkspaceId);
|
||||||
|
this.SelectProviderWhenLoadingChat();
|
||||||
|
}
|
||||||
|
|
||||||
this.StateHasChanged();
|
this.StateHasChanged();
|
||||||
}
|
}
|
||||||
@ -197,6 +205,7 @@ public partial class Chat : MSGComponentBase, IAsyncDisposable
|
|||||||
{
|
{
|
||||||
this.chatThread = new()
|
this.chatThread = new()
|
||||||
{
|
{
|
||||||
|
SelectedProvider = this.providerSettings.Id,
|
||||||
WorkspaceId = this.currentWorkspaceId,
|
WorkspaceId = this.currentWorkspaceId,
|
||||||
ChatId = Guid.NewGuid(),
|
ChatId = Guid.NewGuid(),
|
||||||
Name = threadName,
|
Name = threadName,
|
||||||
@ -394,6 +403,19 @@ public partial class Chat : MSGComponentBase, IAsyncDisposable
|
|||||||
this.hasUnsavedChanges = false;
|
this.hasUnsavedChanges = false;
|
||||||
this.userInput = string.Empty;
|
this.userInput = string.Empty;
|
||||||
|
|
||||||
|
switch (this.SettingsManager.ConfigurationData.Chat.AddChatProviderBehavior)
|
||||||
|
{
|
||||||
|
case AddChatProviderBehavior.ADDED_CHATS_USE_DEFAULT_PROVIDER:
|
||||||
|
this.providerSettings = this.SettingsManager.GetPreselectedProvider(Tools.Components.CHAT);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
case AddChatProviderBehavior.ADDED_CHATS_USE_LATEST_PROVIDER:
|
||||||
|
if(this.providerSettings == default)
|
||||||
|
this.providerSettings = this.SettingsManager.GetPreselectedProvider(Tools.Components.CHAT);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (!useSameWorkspace)
|
if (!useSameWorkspace)
|
||||||
{
|
{
|
||||||
this.chatThread = null;
|
this.chatThread = null;
|
||||||
@ -404,6 +426,7 @@ public partial class Chat : MSGComponentBase, IAsyncDisposable
|
|||||||
{
|
{
|
||||||
this.chatThread = new()
|
this.chatThread = new()
|
||||||
{
|
{
|
||||||
|
SelectedProvider = this.providerSettings.Id,
|
||||||
WorkspaceId = this.currentWorkspaceId,
|
WorkspaceId = this.currentWorkspaceId,
|
||||||
ChatId = Guid.NewGuid(),
|
ChatId = Guid.NewGuid(),
|
||||||
Name = string.Empty,
|
Name = string.Empty,
|
||||||
@ -487,6 +510,8 @@ public partial class Chat : MSGComponentBase, IAsyncDisposable
|
|||||||
this.currentWorkspaceId = this.chatThread?.WorkspaceId ?? Guid.Empty;
|
this.currentWorkspaceId = this.chatThread?.WorkspaceId ?? Guid.Empty;
|
||||||
this.currentWorkspaceName = this.chatThread is null ? string.Empty : await WorkspaceBehaviour.LoadWorkspaceName(this.chatThread.WorkspaceId);
|
this.currentWorkspaceName = this.chatThread is null ? string.Empty : await WorkspaceBehaviour.LoadWorkspaceName(this.chatThread.WorkspaceId);
|
||||||
|
|
||||||
|
this.SelectProviderWhenLoadingChat();
|
||||||
|
|
||||||
this.userInput = string.Empty;
|
this.userInput = string.Empty;
|
||||||
if (this.SettingsManager.ConfigurationData.Chat.ShowLatestMessageAfterLoading)
|
if (this.SettingsManager.ConfigurationData.Chat.ShowLatestMessageAfterLoading)
|
||||||
{
|
{
|
||||||
@ -506,6 +531,27 @@ public partial class Chat : MSGComponentBase, IAsyncDisposable
|
|||||||
this.chatThread = null;
|
this.chatThread = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void SelectProviderWhenLoadingChat()
|
||||||
|
{
|
||||||
|
var chatProvider = this.chatThread?.SelectedProvider;
|
||||||
|
switch (this.SettingsManager.ConfigurationData.Chat.LoadingProviderBehavior)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case LoadingChatProviderBehavior.USE_CHAT_PROVIDER_IF_AVAILABLE:
|
||||||
|
this.providerSettings = this.SettingsManager.GetPreselectedProvider(Tools.Components.CHAT, chatProvider);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LoadingChatProviderBehavior.ALWAYS_USE_DEFAULT_CHAT_PROVIDER:
|
||||||
|
this.providerSettings = this.SettingsManager.GetPreselectedProvider(Tools.Components.CHAT);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LoadingChatProviderBehavior.ALWAYS_USE_LATEST_CHAT_PROVIDER:
|
||||||
|
if(this.providerSettings == default)
|
||||||
|
this.providerSettings = this.SettingsManager.GetPreselectedProvider(Tools.Components.CHAT);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#region Overrides of MSGComponentBase
|
#region Overrides of MSGComponentBase
|
||||||
|
|
||||||
public override async Task ProcessIncomingMessage<T>(ComponentBase? sendingComponent, Event triggeredEvent, T? data) where T : default
|
public override async Task ProcessIncomingMessage<T>(ComponentBase? sendingComponent, Event triggeredEvent, T? data) where T : default
|
||||||
|
@ -193,6 +193,9 @@
|
|||||||
<ExpansionPanel HeaderIcon="@Icons.Material.Filled.Chat" HeaderText="Chat Options">
|
<ExpansionPanel HeaderIcon="@Icons.Material.Filled.Chat" HeaderText="Chat Options">
|
||||||
<ConfigurationSelect OptionDescription="Shortcut to send input" SelectedValue="@(() => this.SettingsManager.ConfigurationData.Chat.ShortcutSendBehavior)" Data="@ConfigurationSelectDataFactory.GetSendBehaviorData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.Chat.ShortcutSendBehavior = selectedValue)" OptionHelp="Do you want to use any shortcut to send your input?"/>
|
<ConfigurationSelect OptionDescription="Shortcut to send input" SelectedValue="@(() => this.SettingsManager.ConfigurationData.Chat.ShortcutSendBehavior)" Data="@ConfigurationSelectDataFactory.GetSendBehaviorData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.Chat.ShortcutSendBehavior = selectedValue)" OptionHelp="Do you want to use any shortcut to send your input?"/>
|
||||||
<ConfigurationOption OptionDescription="Show the latest message after loading?" LabelOn="Latest message is shown, after loading a chat" LabelOff="First (oldest) message is shown, after loading a chat" State="@(() => this.SettingsManager.ConfigurationData.Chat.ShowLatestMessageAfterLoading)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.Chat.ShowLatestMessageAfterLoading = updatedState)" OptionHelp="When enabled, the latest message is shown after loading a chat. When disabled, the first (oldest) message is shown."/>
|
<ConfigurationOption OptionDescription="Show the latest message after loading?" LabelOn="Latest message is shown, after loading a chat" LabelOff="First (oldest) message is shown, after loading a chat" State="@(() => this.SettingsManager.ConfigurationData.Chat.ShowLatestMessageAfterLoading)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.Chat.ShowLatestMessageAfterLoading = updatedState)" OptionHelp="When enabled, the latest message is shown after loading a chat. When disabled, the first (oldest) message is shown."/>
|
||||||
|
<ConfigurationSelect OptionDescription="Provider selection when creating new chats" SelectedValue="@(() => this.SettingsManager.ConfigurationData.Chat.AddChatProviderBehavior)" Data="@ConfigurationSelectDataFactory.GetAddChatProviderBehavior()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.Chat.AddChatProviderBehavior = selectedValue)" OptionHelp="Control how the LLM provider for added chats is selected."/>
|
||||||
|
<ConfigurationSelect OptionDescription="Provider selection when loading a chat and sending assistant results to chat" SelectedValue="@(() => this.SettingsManager.ConfigurationData.Chat.LoadingProviderBehavior)" Data="@ConfigurationSelectDataFactory.GetLoadingChatProviderBehavior()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.Chat.LoadingProviderBehavior = selectedValue)" OptionHelp="Control how the LLM provider for loaded chats is selected and when assistant results are sent to chat."/>
|
||||||
|
|
||||||
<MudPaper Class="pa-3 mb-8 border-dashed border rounded-lg">
|
<MudPaper Class="pa-3 mb-8 border-dashed border rounded-lg">
|
||||||
<ConfigurationOption OptionDescription="Preselect chat options?" LabelOn="Chat options are preselected" LabelOff="No chat options are preselected" State="@(() => this.SettingsManager.ConfigurationData.Chat.PreselectOptions)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.Chat.PreselectOptions = updatedState)" OptionHelp="When enabled, you can preselect chat options. This is might be useful when you prefer a specific provider."/>
|
<ConfigurationOption OptionDescription="Preselect chat options?" LabelOn="Chat options are preselected" LabelOff="No chat options are preselected" State="@(() => this.SettingsManager.ConfigurationData.Chat.PreselectOptions)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.Chat.PreselectOptions = updatedState)" OptionHelp="When enabled, you can preselect chat options. This is might be useful when you prefer a specific provider."/>
|
||||||
<ConfigurationProviderSelection Data="@this.availableProviders" Disabled="@(() => !this.SettingsManager.ConfigurationData.Chat.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.Chat.PreselectedProvider)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.Chat.PreselectedProvider = selectedValue)"/>
|
<ConfigurationProviderSelection Data="@this.availableProviders" Disabled="@(() => !this.SettingsManager.ConfigurationData.Chat.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.Chat.PreselectedProvider)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.Chat.PreselectedProvider = selectedValue)"/>
|
||||||
|
@ -25,6 +25,19 @@ public readonly record struct ConfigurationSelectData<T>(string Name, T Value);
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static class ConfigurationSelectDataFactory
|
public static class ConfigurationSelectDataFactory
|
||||||
{
|
{
|
||||||
|
public static IEnumerable<ConfigurationSelectData<LoadingChatProviderBehavior>> GetLoadingChatProviderBehavior()
|
||||||
|
{
|
||||||
|
yield return new("When possible, use the LLM provider which was used for each chat in the first place", LoadingChatProviderBehavior.USE_CHAT_PROVIDER_IF_AVAILABLE);
|
||||||
|
yield return new("Use the latest LLM provider, which was used before; use the default chat provider initially", LoadingChatProviderBehavior.ALWAYS_USE_LATEST_CHAT_PROVIDER);
|
||||||
|
yield return new("Always use the default chat provider when loading chats", LoadingChatProviderBehavior.ALWAYS_USE_DEFAULT_CHAT_PROVIDER);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IEnumerable<ConfigurationSelectData<AddChatProviderBehavior>> GetAddChatProviderBehavior()
|
||||||
|
{
|
||||||
|
yield return new("Use the latest LLM provider, which was used before; use the default chat provider initially", AddChatProviderBehavior.ADDED_CHATS_USE_LATEST_PROVIDER);
|
||||||
|
yield return new("Always use the default chat provider for new chats", AddChatProviderBehavior.ADDED_CHATS_USE_DEFAULT_PROVIDER);
|
||||||
|
}
|
||||||
|
|
||||||
public static IEnumerable<ConfigurationSelectData<SendBehavior>> GetSendBehaviorData()
|
public static IEnumerable<ConfigurationSelectData<SendBehavior>> GetSendBehaviorData()
|
||||||
{
|
{
|
||||||
yield return new("No key is sending the input", SendBehavior.NO_KEY_IS_SENDING);
|
yield return new("No key is sending the input", SendBehavior.NO_KEY_IS_SENDING);
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
namespace AIStudio.Settings.DataModel;
|
||||||
|
|
||||||
|
public enum AddChatProviderBehavior
|
||||||
|
{
|
||||||
|
ADDED_CHATS_USE_DEFAULT_PROVIDER = 0,
|
||||||
|
ADDED_CHATS_USE_LATEST_PROVIDER,
|
||||||
|
}
|
@ -7,6 +7,16 @@ public sealed class DataChat
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public SendBehavior ShortcutSendBehavior { get; set; } = SendBehavior.ENTER_IS_SENDING;
|
public SendBehavior ShortcutSendBehavior { get; set; } = SendBehavior.ENTER_IS_SENDING;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Defines the provider behavior for loading a chat.
|
||||||
|
/// </summary>
|
||||||
|
public LoadingChatProviderBehavior LoadingProviderBehavior { get; set; } = LoadingChatProviderBehavior.USE_CHAT_PROVIDER_IF_AVAILABLE;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Defines the provider behavior when adding a chat.
|
||||||
|
/// </summary>
|
||||||
|
public AddChatProviderBehavior AddChatProviderBehavior { get; set; } = AddChatProviderBehavior.ADDED_CHATS_USE_LATEST_PROVIDER;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Preselect any chat options?
|
/// Preselect any chat options?
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -0,0 +1,8 @@
|
|||||||
|
namespace AIStudio.Settings.DataModel;
|
||||||
|
|
||||||
|
public enum LoadingChatProviderBehavior
|
||||||
|
{
|
||||||
|
USE_CHAT_PROVIDER_IF_AVAILABLE = 0,
|
||||||
|
ALWAYS_USE_DEFAULT_CHAT_PROVIDER,
|
||||||
|
ALWAYS_USE_LATEST_CHAT_PROVIDER,
|
||||||
|
}
|
@ -131,7 +131,7 @@ public sealed class SettingsManager(ILogger<SettingsManager> logger)
|
|||||||
return minimumLevel;
|
return minimumLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Provider GetPreselectedProvider(Tools.Components component)
|
public Provider GetPreselectedProvider(Tools.Components component, string? chatProviderId = null)
|
||||||
{
|
{
|
||||||
var minimumLevel = this.GetMinimumConfidenceLevel(component);
|
var minimumLevel = this.GetMinimumConfidenceLevel(component);
|
||||||
|
|
||||||
@ -139,6 +139,14 @@ public sealed class SettingsManager(ILogger<SettingsManager> logger)
|
|||||||
if (this.ConfigurationData.Providers.Count == 1 && this.ConfigurationData.Providers[0].UsedLLMProvider.GetConfidence(this).Level >= minimumLevel)
|
if (this.ConfigurationData.Providers.Count == 1 && this.ConfigurationData.Providers[0].UsedLLMProvider.GetConfidence(this).Level >= minimumLevel)
|
||||||
return this.ConfigurationData.Providers[0];
|
return this.ConfigurationData.Providers[0];
|
||||||
|
|
||||||
|
// When there is a chat provider, and it has a confidence level that is high enough, we return it:
|
||||||
|
if (chatProviderId is not null && !string.IsNullOrWhiteSpace(chatProviderId))
|
||||||
|
{
|
||||||
|
var chatProvider = this.ConfigurationData.Providers.FirstOrDefault(x => x.Id == chatProviderId);
|
||||||
|
if (chatProvider.UsedLLMProvider.GetConfidence(this).Level >= minimumLevel)
|
||||||
|
return chatProvider;
|
||||||
|
}
|
||||||
|
|
||||||
// When there is a component-preselected provider, and it has a confidence level that is high enough, we return it:
|
// When there is a component-preselected provider, and it has a confidence level that is high enough, we return it:
|
||||||
var preselectedProvider = component.PreselectedProvider(this);
|
var preselectedProvider = component.PreselectedProvider(this);
|
||||||
if(preselectedProvider != default && preselectedProvider.UsedLLMProvider.GetConfidence(this).Level >= minimumLevel)
|
if(preselectedProvider != default && preselectedProvider.UsedLLMProvider.GetConfidence(this).Level >= minimumLevel)
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
# v0.9.21, build 196 (2024-11-xx xx:xx UTC)
|
# v0.9.21, build 196 (2024-11-xx xx:xx UTC)
|
||||||
|
- Added: Chats remember which LLM provider was used. This is useful to continue exactly where you left off.
|
||||||
|
- Added options for how to decide which LLM provider should be chosen when creating new chats and when loading chats. When you want the previous behavior restored (always use the default chat provider), you can configure this behavior as well.
|
||||||
- Fixed the missed workspace title when loading the today's bias.
|
- Fixed the missed workspace title when loading the today's bias.
|
||||||
- Fixed auto-save when sending assistant results to a new chat.
|
- Fixed auto-save when sending assistant results to a new chat.
|
Loading…
Reference in New Issue
Block a user