feat: внедрение RazorConsole TUI с runtime-управлением MCP-инструментами
- Добавлен RazorConsole.Core для интерактивного TUI-дашборда - ToolRegistryService: живое включение/отключение модулей и отдельных методов - InMemoryLogSink: кольцевой буфер логов с фильтрацией по модулю - TUI: 3 таба (Overview, Logs, Settings) - IToolModule: generic-интерфейс для легкого добавления новых MCP-модулей - Guard-проверка TryCheckEnabled() во всех существующих инструментах
This commit is contained in:
69
LazyBear.MCP/TUI/TuiHostedService.cs
Normal file
69
LazyBear.MCP/TUI/TuiHostedService.cs
Normal file
@@ -0,0 +1,69 @@
|
||||
using LazyBear.MCP.Services.ToolRegistry;
|
||||
using LazyBear.MCP.TUI.Components;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using RazorConsole.Core;
|
||||
|
||||
namespace LazyBear.MCP.TUI;
|
||||
|
||||
/// <summary>
|
||||
/// Запускает RazorConsole TUI как IHostedService в отдельном потоке,
|
||||
/// чтобы не блокировать ASP.NET Core pipeline.
|
||||
/// </summary>
|
||||
public sealed class TuiHostedService(IServiceProvider services, ILogger<TuiHostedService> logger) : IHostedService
|
||||
{
|
||||
private Thread? _tuiThread;
|
||||
private CancellationTokenSource? _cts;
|
||||
|
||||
public Task StartAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
_cts = new CancellationTokenSource();
|
||||
|
||||
// Регистрируем все IToolModule-модули в ToolRegistryService
|
||||
var registry = services.GetRequiredService<ToolRegistryService>();
|
||||
foreach (var module in services.GetServices<IToolModule>())
|
||||
{
|
||||
registry.RegisterModule(module);
|
||||
}
|
||||
|
||||
_tuiThread = new Thread(RunTui)
|
||||
{
|
||||
IsBackground = true,
|
||||
Name = "RazorConsole-TUI"
|
||||
};
|
||||
_tuiThread.Start();
|
||||
|
||||
logger.LogInformation("TUI запущен в фоновом потоке");
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task StopAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
_cts?.Cancel();
|
||||
logger.LogInformation("TUI остановлен");
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private void RunTui()
|
||||
{
|
||||
try
|
||||
{
|
||||
var host = Host.CreateDefaultBuilder()
|
||||
.UseRazorConsole<App>(configure: configure =>
|
||||
{
|
||||
configure.ConfigureServices((_, svc) =>
|
||||
{
|
||||
// Пробрасываем ключевые Singleton из основного DI-контейнера в TUI-контейнер
|
||||
svc.AddSingleton(services.GetRequiredService<ToolRegistryService>());
|
||||
svc.AddSingleton(services.GetRequiredService<Services.Logging.InMemoryLogSink>());
|
||||
});
|
||||
})
|
||||
.Build();
|
||||
|
||||
host.Run();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.LogError(ex, "Ошибка в потоке TUI");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user