using Microsoft.Extensions.AI; using Spectre.Console; using AnchorCli.OpenRouter; namespace AnchorCli; /// /// Handles context compaction when the conversation approaches token limits. /// internal sealed class ContextCompactionService { private readonly ContextCompactor _compactor; private readonly List _history; private readonly TokenTracker _tokenTracker; public ContextCompactionService( ContextCompactor compactor, List history, TokenTracker tokenTracker) { _compactor = compactor; _history = history; _tokenTracker = tokenTracker; } /// /// Checks if compaction is needed and performs it if so. /// Returns true if compaction was performed. /// public async Task TryCompactAsync() { if (!_tokenTracker.ShouldCompact()) { return false; } var pct = _tokenTracker.ContextUsagePercent; AnsiConsole.MarkupLine( $"[yellow]⚠ Context at {pct:F0}% — compacting conversation history...[/]"); bool compacted = await AnsiConsole.Status() .Spinner(Spinner.Known.BouncingBar) .SpinnerStyle(Style.Parse("yellow")) .StartAsync("Compacting context...", async ctx => await _compactor.TryCompactAsync(_history, default)); if (compacted) { AnsiConsole.MarkupLine( $"[green]✓ Context compacted ({_history.Count} messages remaining)[/]"); } else { AnsiConsole.MarkupLine( "[dim grey] (compaction skipped — not enough history to compress)[/]"); } AnsiConsole.WriteLine(); return compacted; } }