1
0

refactor: apply Single Responsibility Principle to Program.cs and ReplLoop.cs

extracted responsibilities from Program.cs (208→46 lines) and ReplLoop.cs (274→174 lines) into focused service classes: HeaderRenderer, SessionManager, ApplicationStartup, ResponseStreamer, SpinnerService, UsageDisplayer, and ContextCompactionService. Each class now has a single, well-defined responsibility, improving testability and maintainability.
This commit is contained in:
2026-03-11 16:59:06 +01:00
parent ccfa7e1b9d
commit 1e943e6566
10 changed files with 791 additions and 408 deletions

48
UsageDisplayer.cs Normal file
View File

@@ -0,0 +1,48 @@
using Spectre.Console;
namespace AnchorCli.OpenRouter;
/// <summary>
/// Displays token usage and cost information to the console.
/// </summary>
internal sealed class UsageDisplayer
{
private readonly TokenTracker _tokenTracker;
public UsageDisplayer(TokenTracker tokenTracker)
{
_tokenTracker = tokenTracker;
}
/// <summary>
/// Displays the usage statistics for a single response.
/// </summary>
public void Display(int inputTokens, int outputTokens)
{
if (inputTokens > 0 || outputTokens > 0)
{
_tokenTracker.AddUsage(inputTokens, outputTokens);
var cost = _tokenTracker.CalculateCost(inputTokens, outputTokens);
var ctxPct = _tokenTracker.ContextUsagePercent;
AnsiConsole.WriteLine();
AnsiConsole.MarkupLine(
$"[dim grey] {TokenTracker.FormatTokens(inputTokens)}↑ {TokenTracker.FormatTokens(outputTokens)}↓" +
$" {TokenTracker.FormatCost(cost)}" +
(ctxPct >= 0 ? $" ctx:{ctxPct:F0}%" : "") +
$" │ session: {TokenTracker.FormatCost(_tokenTracker.SessionCost)}[/]");
}
else
{
AnsiConsole.WriteLine();
}
}
/// <summary>
/// Displays a rule separator.
/// </summary>
public void DisplaySeparator()
{
AnsiConsole.Write(new Rule().RuleStyle(Style.Parse("grey dim")));
}
}