1
0
Files
Toak/Commands/LatencyTestCommand.cs

96 lines
3.4 KiB
C#

using System;
using System.Diagnostics;
using System.IO;
using System.Threading.Tasks;
using Spectre.Console;
using Toak.Api;
using Toak.Configuration;
using Toak.Core;
namespace Toak.Commands;
public static class LatencyTestCommand
{
public static async Task ExecuteAsync(bool verbose)
{
Logger.Verbose = verbose;
var config = new ConfigManager().LoadConfig();
if (string.IsNullOrWhiteSpace(config.GroqApiKey))
{
AnsiConsole.MarkupLine("[red]Groq API Key is not configured.[/] Run 'toak onboard'.");
return;
}
AnsiConsole.MarkupLine("Generating 1-second silent audio file for testing...");
var testWavPath = Constants.Paths.LatencyTestWavFile;
var pInfo = new ProcessStartInfo
{
FileName = Constants.Commands.AudioFfmpeg,
Arguments = $"-f lavfi -i anullsrc=r=44100:cl=mono -t 1 -y {testWavPath}",
UseShellExecute = false,
CreateNoWindow = true,
RedirectStandardError = true,
RedirectStandardOutput = true
};
var proc = Process.Start(pInfo);
proc?.WaitForExit();
if (!File.Exists(testWavPath))
{
AnsiConsole.MarkupLine("[red]Failed to generate test audio file using ffmpeg.[/]");
return;
}
var groq = new GroqApiClient(config.GroqApiKey);
try
{
await AnsiConsole.Status()
.StartAsync("Running latency test...", async ctx =>
{
ctx.Status("Testing STT (Whisper)...");
var sttWatch = Stopwatch.StartNew();
var transcript = await groq.TranscribeAsync(testWavPath, config.WhisperLanguage, config.WhisperModel);
sttWatch.Stop();
ctx.Status("Testing LLM (Llama)...");
var systemPrompt = PromptBuilder.BuildPrompt(config);
var llmWatch = Stopwatch.StartNew();
var refinedText = await groq.RefineTextAsync("Hello world, this is a latency test.", systemPrompt, config.LlmModel);
llmWatch.Stop();
var total = sttWatch.ElapsedMilliseconds + llmWatch.ElapsedMilliseconds;
AnsiConsole.WriteLine();
var table = new Table();
table.AddColumn("Operation");
table.AddColumn("Latency (ms)");
table.AddRow("STT", sttWatch.ElapsedMilliseconds.ToString());
table.AddRow("LLM", llmWatch.ElapsedMilliseconds.ToString());
table.AddRow("[bold]Total[/]", $"[bold]{total}ms[/]");
AnsiConsole.Write(table);
if (total < 1500)
{
AnsiConsole.MarkupLine($"[green]Status: OK (under 1.5s target). Total time: {(total / 1000.0):0.0}s.[/]");
}
else
{
AnsiConsole.MarkupLine($"[yellow]Status: SLOW (over 1.5s target). Total time: {(total / 1000.0):0.0}s.[/]");
}
});
}
catch (Exception ex)
{
AnsiConsole.MarkupLine($"[red]Error during test: {ex.Message}[/]");
}
finally
{
if (File.Exists(testWavPath)) File.Delete(testWavPath);
}
}
}