add Fireworks AI provider support

This commit is contained in:
2026-03-22 19:02:37 +01:00
parent a26d453720
commit 70e784a1cc
4 changed files with 310 additions and 73 deletions
+67 -37
View File
@@ -32,48 +32,62 @@ public static class SetupCommand
AnsiConsole.MarkupLine("[bold blue]Welcome to Hush Setup![/]\n");
AnsiConsole.MarkupLine("This wizard will help you configure Hush.\n");
var config = new HushConfig();
var configManager = new ConfigManager();
var config = configManager.Load();
AnsiConsole.MarkupLine("[bold]Step 1: Whisper Provider[/]");
config.WhisperProvider = AnsiConsole.Prompt(
new SelectionPrompt<string>()
.Title("Select Whisper provider:")
.AddChoices("groq"));
config.WhisperProvider = PromptSelection("Select Whisper provider:", ["groq", "fireworks"], config.WhisperProvider);
AnsiConsole.MarkupLine("[bold]Step 2: Groq API Key[/]");
config.GroqApiKey = ReadMaskedInput("Enter your Groq API key:");
AnsiConsole.MarkupLine("[bold]Step 2: LLM Provider[/]");
config.LlmProvider = PromptSelection("Select LLM provider:", ["groq", "fireworks"], config.LlmProvider);
AnsiConsole.MarkupLine("[bold]Step 3: LLM Model[/]");
config.LlmProvider = "groq";
config.LlmModel = AnsiConsole.Prompt(
new SelectionPrompt<string>()
.Title("Select LLM model:")
.AddChoices("openai/gpt-oss-20b", "llama-3.1-8b-instant", "openai/gpt-oss-120b"));
if (config.WhisperProvider == "groq" || config.LlmProvider == "groq")
{
AnsiConsole.MarkupLine("[bold]Step 3: Groq API Key[/]");
config.GroqApiKey = ReadMaskedInput("Enter your Groq API key:", config.GroqApiKey);
}
AnsiConsole.MarkupLine("[bold]Step 4: Whisper Model[/]");
config.WhisperModel = AnsiConsole.Prompt(
new SelectionPrompt<string>()
.Title("Select Whisper model:")
.AddChoices("whisper-large-v3", "whisper-large-v3-turbo"));
if (config.WhisperProvider == "fireworks" || config.LlmProvider == "fireworks")
{
AnsiConsole.MarkupLine("[bold]Step 3: Fireworks API Key[/]");
config.FireworksApiKey = ReadMaskedInput("Enter your Fireworks API key:", config.FireworksApiKey);
}
AnsiConsole.MarkupLine("[bold]Step 5: Audio Backend[/]");
config.AudioBackend = AnsiConsole.Prompt(
new SelectionPrompt<string>()
.Title("Select audio backend:")
.AddChoices("pipewire", "ffmpeg"));
AnsiConsole.MarkupLine("[bold]Step 4: LLM Model[/]");
config.LlmModel = config.LlmProvider switch
{
"fireworks" => PromptSelection("Select LLM model:", [
"accounts/fireworks/models/kimi-k2-instruct-0905",
"accounts/fireworks/models/deepseek-v3p1",
"accounts/fireworks/models/llama-v3p1-70b-instruct"
], config.LlmModel),
_ => PromptSelection("Select LLM model:", [
"openai/gpt-oss-20b", "llama-3.1-8b-instant", "openai/gpt-oss-120b"
], config.LlmModel)
};
AnsiConsole.MarkupLine("[bold]Step 6: Typing Backend[/]");
config.TypingBackend = AnsiConsole.Prompt(
new SelectionPrompt<string>()
.Title("Select typing backend:")
.AddChoices("wtype", "xdotool"));
AnsiConsole.MarkupLine("[bold]Step 5: Whisper Model[/]");
config.WhisperModel = config.WhisperProvider switch
{
"fireworks" => PromptSelection("Select Whisper model:", [
"whisper-v3", "whisper-v3-turbo"
], config.WhisperModel),
_ => PromptSelection("Select Whisper model:", [
"whisper-large-v3", "whisper-large-v3-turbo"
], config.WhisperModel)
};
AnsiConsole.MarkupLine("[bold]Step 7: Minimum Recording Duration[/]");
var minDuration = AnsiConsole.Prompt(
new TextPrompt<int>("Enter minimum duration (ms, default 500):")
.DefaultValue(500)
AnsiConsole.MarkupLine("[bold]Step 6: Audio Backend[/]");
config.AudioBackend = PromptSelection("Select audio backend:", ["pipewire", "ffmpeg"], config.AudioBackend);
AnsiConsole.MarkupLine("[bold]Step 7: Typing Backend[/]");
config.TypingBackend = PromptSelection("Select typing backend:", ["wtype", "xdotool"], config.TypingBackend);
AnsiConsole.MarkupLine("[bold]Step 8: Minimum Recording Duration[/]");
config.MinRecordingDuration = AnsiConsole.Prompt(
new TextPrompt<int>("Enter minimum duration (ms):")
.DefaultValue(config.MinRecordingDuration)
.Validate(x => x > 0, "Must be greater than 0"));
config.MinRecordingDuration = minDuration;
AnsiConsole.WriteLine();
AnsiConsole.MarkupLine("[bold]Configuration Summary:[/]");
@@ -82,7 +96,11 @@ public static class SetupCommand
table.AddColumn("Setting");
table.AddColumn("Value");
table.AddRow("Whisper Provider", config.WhisperProvider);
table.AddRow("Groq API Key", MaskApiKey(config.GroqApiKey));
table.AddRow("LLM Provider", config.LlmProvider);
if (!string.IsNullOrEmpty(config.GroqApiKey))
table.AddRow("Groq API Key", MaskApiKey(config.GroqApiKey));
if (!string.IsNullOrEmpty(config.FireworksApiKey))
table.AddRow("Fireworks API Key", MaskApiKey(config.FireworksApiKey));
table.AddRow("LLM Model", config.LlmModel);
table.AddRow("Whisper Model", config.WhisperModel);
table.AddRow("Audio Backend", config.AudioBackend);
@@ -94,9 +112,20 @@ public static class SetupCommand
return config;
}
private static string ReadMaskedInput(string prompt)
private static string PromptSelection(string title, string[] choices, string current)
{
AnsiConsole.Write(prompt + " ");
var prompt = new SelectionPrompt<string>().Title(title);
// Put current value first so it starts highlighted; add it if it's a custom value not in the list
prompt.AddChoice(current);
foreach (var choice in choices.Where(c => c != current))
prompt.AddChoice(choice);
return AnsiConsole.Prompt(prompt);
}
private static string ReadMaskedInput(string prompt, string current = "")
{
var hint = string.IsNullOrEmpty(current) ? "" : $" [{MaskApiKey(current)}]";
AnsiConsole.Write(prompt + hint + " ");
var input = "";
while (true)
{
@@ -117,7 +146,8 @@ public static class SetupCommand
AnsiConsole.Write("*");
}
}
return input;
// Keep existing key if user just hit Enter without typing anything
return string.IsNullOrEmpty(input) ? current : input;
}
private static string MaskApiKey(string key)
+3 -1
View File
@@ -36,6 +36,7 @@ public static class ShowCommand
{
AnsiConsole.WriteLine($"whisper_provider={config.WhisperProvider}");
AnsiConsole.WriteLine($"groq_api_key={MaskApiKey(config.GroqApiKey)}");
AnsiConsole.WriteLine($"fireworks_api_key={MaskApiKey(config.FireworksApiKey)}");
AnsiConsole.WriteLine($"llm_provider={config.LlmProvider}");
AnsiConsole.WriteLine($"llm_model={config.LlmModel}");
AnsiConsole.WriteLine($"whisper_model={config.WhisperModel}");
@@ -50,8 +51,9 @@ public static class ShowCommand
table.AddColumn("Value");
table.AddRow("Whisper Provider", config.WhisperProvider);
table.AddRow("Groq API Key", MaskApiKey(config.GroqApiKey));
table.AddRow("LLM Provider", config.LlmProvider);
table.AddRow("Groq API Key", MaskApiKey(config.GroqApiKey));
table.AddRow("Fireworks API Key", MaskApiKey(config.FireworksApiKey));
table.AddRow("LLM Model", config.LlmModel);
table.AddRow("Whisper Model", config.WhisperModel);
table.AddRow("Audio Backend", config.AudioBackend);