1
0
Files
Toak/Commands/OnboardCommand.cs

102 lines
4.4 KiB
C#

using System;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Spectre.Console;
using Toak.Configuration;
using Toak.Core.Skills;
namespace Toak.Commands;
public static class OnboardCommand
{
public static async Task ExecuteAsync(bool verbose)
{
Toak.Core.Logger.Verbose = verbose;
var configManager = new ConfigManager();
var config = configManager.LoadConfig();
AnsiConsole.Write(new FigletText("Toak").Color(Color.Green));
AnsiConsole.MarkupLine("[grey]Welcome to the Toak configuration wizard.[/]");
AnsiConsole.WriteLine();
config.GroqApiKey = AnsiConsole.Prompt(
new TextPrompt<string>("Groq API Key:")
.DefaultValue(string.IsNullOrWhiteSpace(config.GroqApiKey) ? "" : config.GroqApiKey)
.AllowEmpty());
config.LlmModel = AnsiConsole.Prompt(
new SelectionPrompt<string>()
.Title("Select [green]LLM Model[/]:")
.AddChoices(new[] { "openai/gpt-oss-20b", "llama-3.1-8b-instant", "llama-3.3-70b-versatile" })
.UseConverter(c => c == "openai/gpt-oss-20b" ? "openai/gpt-oss-20b (Fastest)" : c == "llama-3.1-8b-instant" ? "llama-3.1-8b-instant (Cheapest)" : "llama-3.3-70b-versatile (More Accurate)"));
if (config.LlmModel.Contains(" ")) config.LlmModel = config.LlmModel.Split(' ')[0];
config.WhisperModel = AnsiConsole.Prompt(
new SelectionPrompt<string>()
.Title("Select [green]Whisper Model[/]:")
.AddChoices(new[] { "whisper-large-v3", "whisper-large-v3-turbo" })
.UseConverter(c => c == "whisper-large-v3" ? "whisper-large-v3 (Accurate)" : "whisper-large-v3-turbo (Fast)"));
config.WhisperLanguage = AnsiConsole.Prompt(
new TextPrompt<string>("Microphone Spoken Language (e.g. en, es, zh):")
.DefaultValue(string.IsNullOrWhiteSpace(config.WhisperLanguage) ? "en" : config.WhisperLanguage)
.AllowEmpty()
.Validate(lang =>
{
if (string.IsNullOrWhiteSpace(lang)) return ValidationResult.Success();
if (lang.Contains(",") || lang.Contains(" "))
return ValidationResult.Error("[red]Please provide only one language code (e.g., 'en' not 'en, es')[/]");
return ValidationResult.Success();
}));
var sessionType = Environment.GetEnvironmentVariable("XDG_SESSION_TYPE")?.ToLowerInvariant();
var typingBackends = sessionType == "wayland" ? new[] { "wtype", "ydotool", "xdotool" } : new[] { "xdotool", "ydotool" };
config.TypingBackend = AnsiConsole.Prompt(
new SelectionPrompt<string>()
.Title($"Select [green]Typing Backend[/] (Detected: {sessionType}):")
.AddChoices(typingBackends));
config.AudioBackend = AnsiConsole.Prompt(
new SelectionPrompt<string>()
.Title("Select [green]Audio Recording Backend[/]:")
.AddChoices(new[] { "pw-record", "ffmpeg" })
.UseConverter(c => c == "pw-record" ? "pw-record (Default PipeWire)" : "ffmpeg (Universal PulseAudio)"));
var availableSkills = SkillRegistry.AllSkills.Select(s => s.Name).ToList();
if (availableSkills.Any())
{
config.ActiveSkills = AnsiConsole.Prompt(
new MultiSelectionPrompt<string>()
.Title("Select [green]Active Skills[/]:")
.NotRequired()
.InstructionsText("[grey](Press [blue]<space>[/] to toggle a skill, [green]<enter>[/] to accept)[/]")
.AddChoices(availableSkills));
}
configManager.SaveConfig(config);
AnsiConsole.MarkupLine("\n[bold green]Configuration saved successfully![/]");
try
{
var processInfo = new ProcessStartInfo("systemctl", "--user restart toak.service")
{
CreateNoWindow = true,
UseShellExecute = false
};
Process.Start(processInfo)?.WaitForExit();
AnsiConsole.MarkupLine("[grey]Restarted Toak daemon service.[/]");
}
catch (Exception ex)
{
Toak.Core.Logger.LogDebug($"Failed to restart toak service: {ex.Message}");
}
}
}