← All source files

V5 / f52bca255516

Lilith.Schedules.cs

Lilith/Agent/Lilith.Schedules.cs

Changed in this version
CS
namespace Lilith.Agent;

public partial class Lilith
{
    public async Task StopSchedulingAsync()
    {
        _scheduleStop.Cancel();
        if (_schedulePump is not null) await _schedulePump;
    }

    private async Task DetectSchedulesAsync(CancellationToken ct)
    {
        using var timer = new PeriodicTimer(TimeSpan.FromSeconds(1));
        try
        {
            while (await timer.WaitForNextTickAsync(ct))
                try { Schedules.Tick(); }
                catch (Exception ex) { Logger.SystemWriteLine("Schedule detection failed: " + ex.Message, global::Lilith.Core.Logging.LogColors.Red); }
        }
        catch (OperationCanceledException) when (ct.IsCancellationRequested) { }
    }

    private async Task PumpSchedulesAsync(CancellationToken ct)
    {
        using var timer = new PeriodicTimer(TimeSpan.FromSeconds(1));
        try
        {
            while (await timer.WaitForNextTickAsync(ct))
            {
                try
                {
                    // Detection runs separately; delivery must own conversation and narration access.
                    if (!await _operation.WaitAsync(0, ct)) continue;
                    try { await DeliverScheduleEventsAsync(ct); }
                    finally { _operation.Release(); }
                }
                catch (OperationCanceledException) when (ct.IsCancellationRequested) { break; }
                catch (Exception ex) { Logger.SystemWriteLine("Scheduler: " + ex.Message, global::Lilith.Core.Logging.LogColors.Red); }
            }
        }
        catch (OperationCanceledException) when (ct.IsCancellationRequested) { }
    }

    private Task DeliverScheduleEventsAsync(CancellationToken ct) =>
        global::Lilith.Core.Scheduling.ScheduleDelivery.DrainAsync(Client,
            (text, token) => _tts is null ? Task.CompletedTask : _tts.SpeakAsync(text, token), ct);

    public async Task ApproveScheduleAsync(string id, CancellationToken ct = default)
    {
        using var operation = EnterOperation("Boot before approving schedule changes.");
        string reply = Schedules.Approve(id).ToReply();
        Logger.SystemWriteLine(reply);
        if (_tts is not null) await _tts.SpeakAsync(reply, ct);
    }

    public void RejectSchedule(string id)
    {
        using var operation = EnterOperation("Boot before rejecting schedule changes.");
        Schedules.Reject(id);
        Logger.SystemWriteLine("Schedule proposal rejected.");
    }
}