mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-10-14 06:33:47 +00:00
Add workspaces & persistent chats (#23)
This commit is contained in:
1 parent
29263660fc
commit
59d0321625
43 files changed
+1392
-66
No files matched your search
@@ -10,4 +10,8 @@ public enum Event
|
||||
// Update events:
|
||||
USER_SEARCH_FOR_UPDATE,
|
||||
UPDATE_AVAILABLE,
|
||||
|
||||
// Chat events:
|
||||
HAS_CHAT_UNSAVED_CHANGES,
|
||||
RESET_CHAT_STATE,
|
||||
}
|
||||
@@ -5,4 +5,6 @@ namespace AIStudio.Tools;
|
||||
public interface IMessageBusReceiver
|
||||
{
|
||||
public Task ProcessMessage<T>(ComponentBase? sendingComponent, Event triggeredEvent, T? data);
|
||||
|
||||
public Task<TResult?> ProcessMessageWithResult<TPayload, TResult>(ComponentBase? sendingComponent, Event triggeredEvent, TPayload? data);
|
||||
}
|
||||
@@ -20,6 +20,8 @@ public abstract class MSGComponentBase : ComponentBase, IDisposable, IMessageBus
|
||||
#region Implementation of IMessageBusReceiver
|
||||
|
||||
public abstract Task ProcessMessage<T>(ComponentBase? sendingComponent, Event triggeredEvent, T? data);
|
||||
|
||||
public abstract Task<TResult?> ProcessMessageWithResult<TPayload, TResult>(ComponentBase? sendingComponent, Event triggeredEvent, TPayload? data);
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -37,6 +39,11 @@ public abstract class MSGComponentBase : ComponentBase, IDisposable, IMessageBus
|
||||
await this.MessageBus.SendMessage(this, triggeredEvent, data);
|
||||
}
|
||||
|
||||
protected async Task<TResult?> SendMessageWithResult<TPayload, TResult>(Event triggeredEvent, TPayload? data)
|
||||
{
|
||||
return await this.MessageBus.SendMessageUseFirstResult<TPayload, TResult>(this, triggeredEvent, data);
|
||||
}
|
||||
|
||||
protected void ApplyFilters(ComponentBase[] components, Event[] events)
|
||||
{
|
||||
this.MessageBus.ApplyFilters(this, components, events);
|
||||
|
||||
@@ -64,4 +64,23 @@ public sealed class MessageBus
|
||||
this.sendingSemaphore.Release();
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<TResult?> SendMessageUseFirstResult<TPayload, TResult>(ComponentBase? sendingComponent, Event triggeredEvent, TPayload? data = default)
|
||||
{
|
||||
foreach (var (receiver, componentFilter) in this.componentFilters)
|
||||
{
|
||||
if (componentFilter.Length > 0 && sendingComponent is not null && !componentFilter.Contains(sendingComponent))
|
||||
continue;
|
||||
|
||||
var eventFilter = this.componentEvents[receiver];
|
||||
if (eventFilter.Length == 0 || eventFilter.Contains(triggeredEvent))
|
||||
{
|
||||
var result = await receiver.ProcessMessageWithResult<TPayload, TResult>(sendingComponent, triggeredEvent, data);
|
||||
if (result is not null)
|
||||
return (TResult) result;
|
||||
}
|
||||
}
|
||||
|
||||
return default;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
using AIStudio.Settings;
|
||||
|
||||
namespace AIStudio.Tools;
|
||||
|
||||
public class TemporaryChatService(SettingsManager settingsManager) : BackgroundService
|
||||
{
|
||||
private static readonly TimeSpan CHECK_INTERVAL = TimeSpan.FromDays(1);
|
||||
private static bool IS_INITIALIZED;
|
||||
|
||||
#region Overrides of BackgroundService
|
||||
|
||||
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
||||
{
|
||||
while (!stoppingToken.IsCancellationRequested && !IS_INITIALIZED)
|
||||
await Task.Delay(TimeSpan.FromSeconds(3), stoppingToken);
|
||||
|
||||
await settingsManager.LoadSettings();
|
||||
if(settingsManager.ConfigurationData.WorkspaceStorageTemporaryMaintenancePolicy is WorkspaceStorageTemporaryMaintenancePolicy.NO_AUTOMATIC_MAINTENANCE)
|
||||
{
|
||||
Console.WriteLine("Automatic maintenance of temporary chat storage is disabled. Exiting maintenance service.");
|
||||
return;
|
||||
}
|
||||
|
||||
await this.StartMaintenance();
|
||||
while (!stoppingToken.IsCancellationRequested)
|
||||
{
|
||||
await Task.Delay(CHECK_INTERVAL, stoppingToken);
|
||||
await this.StartMaintenance();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private Task StartMaintenance()
|
||||
{
|
||||
var temporaryDirectories = Path.Join(SettingsManager.DataDirectory, "tempChats");
|
||||
if(!Directory.Exists(temporaryDirectories))
|
||||
return Task.CompletedTask;
|
||||
|
||||
foreach (var tempChatDirPath in Directory.EnumerateDirectories(temporaryDirectories))
|
||||
{
|
||||
var chatPath = Path.Join(tempChatDirPath, "thread.json");
|
||||
var chatMetadata = new FileInfo(chatPath);
|
||||
if (!chatMetadata.Exists)
|
||||
continue;
|
||||
|
||||
var lastWriteTime = chatMetadata.LastWriteTimeUtc;
|
||||
var deleteChat = settingsManager.ConfigurationData.WorkspaceStorageTemporaryMaintenancePolicy switch
|
||||
{
|
||||
WorkspaceStorageTemporaryMaintenancePolicy.DELETE_OLDER_THAN_7_DAYS => DateTime.UtcNow - lastWriteTime > TimeSpan.FromDays(7),
|
||||
WorkspaceStorageTemporaryMaintenancePolicy.DELETE_OLDER_THAN_30_DAYS => DateTime.UtcNow - lastWriteTime > TimeSpan.FromDays(30),
|
||||
WorkspaceStorageTemporaryMaintenancePolicy.DELETE_OLDER_THAN_90_DAYS => DateTime.UtcNow - lastWriteTime > TimeSpan.FromDays(90),
|
||||
WorkspaceStorageTemporaryMaintenancePolicy.DELETE_OLDER_THAN_180_DAYS => DateTime.UtcNow - lastWriteTime > TimeSpan.FromDays(180),
|
||||
WorkspaceStorageTemporaryMaintenancePolicy.DELETE_OLDER_THAN_365_DAYS => DateTime.UtcNow - lastWriteTime > TimeSpan.FromDays(365),
|
||||
|
||||
WorkspaceStorageTemporaryMaintenancePolicy.NO_AUTOMATIC_MAINTENANCE => false,
|
||||
_ => false,
|
||||
};
|
||||
|
||||
if(deleteChat)
|
||||
Directory.Delete(tempChatDirPath, true);
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
IS_INITIALIZED = true;
|
||||
}
|
||||
}
|
||||
@@ -14,10 +14,11 @@ public sealed class UpdateService : BackgroundService, IMessageBusReceiver
|
||||
private static ISnackbar? SNACKBAR;
|
||||
|
||||
private readonly SettingsManager settingsManager;
|
||||
private readonly TimeSpan updateInterval;
|
||||
private readonly MessageBus messageBus;
|
||||
private readonly Rust rust;
|
||||
|
||||
private TimeSpan updateInterval;
|
||||
|
||||
public UpdateService(MessageBus messageBus, SettingsManager settingsManager, Rust rust)
|
||||
{
|
||||
this.settingsManager = settingsManager;
|
||||
@@ -26,8 +27,16 @@ public sealed class UpdateService : BackgroundService, IMessageBusReceiver
|
||||
|
||||
this.messageBus.RegisterComponent(this);
|
||||
this.ApplyFilters([], [ Event.USER_SEARCH_FOR_UPDATE ]);
|
||||
|
||||
this.updateInterval = settingsManager.ConfigurationData.UpdateBehavior switch
|
||||
}
|
||||
|
||||
#region Overrides of BackgroundService
|
||||
|
||||
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
||||
{
|
||||
while (!stoppingToken.IsCancellationRequested && !IS_INITIALIZED)
|
||||
await Task.Delay(TimeSpan.FromSeconds(3), stoppingToken);
|
||||
|
||||
this.updateInterval = this.settingsManager.ConfigurationData.UpdateBehavior switch
|
||||
{
|
||||
UpdateBehavior.NO_CHECK => Timeout.InfiniteTimeSpan,
|
||||
UpdateBehavior.ONCE_STARTUP => Timeout.InfiniteTimeSpan,
|
||||
@@ -38,21 +47,11 @@ public sealed class UpdateService : BackgroundService, IMessageBusReceiver
|
||||
|
||||
_ => TimeSpan.FromHours(1)
|
||||
};
|
||||
}
|
||||
|
||||
#region Overrides of BackgroundService
|
||||
|
||||
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
||||
{
|
||||
while (!stoppingToken.IsCancellationRequested && !IS_INITIALIZED)
|
||||
{
|
||||
await Task.Delay(TimeSpan.FromSeconds(1), stoppingToken);
|
||||
}
|
||||
|
||||
await this.settingsManager.LoadSettings();
|
||||
if(this.settingsManager.ConfigurationData.UpdateBehavior != UpdateBehavior.NO_CHECK)
|
||||
await this.CheckForUpdate();
|
||||
|
||||
if(this.settingsManager.ConfigurationData.UpdateBehavior is UpdateBehavior.NO_CHECK)
|
||||
return;
|
||||
|
||||
await this.CheckForUpdate();
|
||||
while (!stoppingToken.IsCancellationRequested)
|
||||
{
|
||||
await Task.Delay(this.updateInterval, stoppingToken);
|
||||
@@ -73,6 +72,11 @@ public sealed class UpdateService : BackgroundService, IMessageBusReceiver
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public Task<TResult?> ProcessMessageWithResult<TPayload, TResult>(ComponentBase? sendingComponent, Event triggeredEvent, TPayload? data)
|
||||
{
|
||||
return Task.FromResult<TResult?>(default);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
Reference in new issue
Block a user