feat: Add Cerebras and Fireworks as LLM providers and introduce configurable Whisper providers with dedicated API keys.
This commit is contained in:
@@ -17,16 +17,11 @@ public static class OnboardCommand
|
|||||||
AnsiConsole.MarkupLine("[grey]Welcome to the Toak configuration wizard.[/]");
|
AnsiConsole.MarkupLine("[grey]Welcome to the Toak configuration wizard.[/]");
|
||||||
AnsiConsole.WriteLine();
|
AnsiConsole.WriteLine();
|
||||||
|
|
||||||
config.GroqApiKey = AnsiConsole.Prompt(
|
|
||||||
new TextPrompt<string>("Groq API Key (required for Whisper):")
|
|
||||||
.DefaultValue(string.IsNullOrWhiteSpace(config.GroqApiKey) ? "" : config.GroqApiKey)
|
|
||||||
.AllowEmpty());
|
|
||||||
|
|
||||||
config.LlmProvider = AnsiConsole.Prompt(
|
config.LlmProvider = AnsiConsole.Prompt(
|
||||||
new SelectionPrompt<string>()
|
new SelectionPrompt<string>()
|
||||||
.Title("Select [green]LLM Provider[/]:")
|
.Title("Select [green]LLM Provider[/]:")
|
||||||
.AddChoices(new[] { "groq", "together" })
|
.AddChoices(new[] { "groq", "together", "cerebras", "fireworks" })
|
||||||
.UseConverter(c => c == "groq" ? "Groq (Default)" : "Together AI"));
|
.UseConverter(c => c == "groq" ? "Groq (Default)" : c == "together" ? "Together AI" : c == "cerebras" ? "Cerebras" : "Fireworks AI"));
|
||||||
|
|
||||||
if (config.LlmProvider == "together")
|
if (config.LlmProvider == "together")
|
||||||
{
|
{
|
||||||
@@ -40,8 +35,38 @@ public static class OnboardCommand
|
|||||||
.Title("Select [green]LLM Model[/]:")
|
.Title("Select [green]LLM Model[/]:")
|
||||||
.AddChoices(new[] { "meta-llama/Llama-3.3-70B-Instruct-Turbo", "meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo", "openai/gpt-oss-20b" }));
|
.AddChoices(new[] { "meta-llama/Llama-3.3-70B-Instruct-Turbo", "meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo", "openai/gpt-oss-20b" }));
|
||||||
}
|
}
|
||||||
|
else if (config.LlmProvider == "cerebras")
|
||||||
|
{
|
||||||
|
config.CerebrasApiKey = AnsiConsole.Prompt(
|
||||||
|
new TextPrompt<string>("Cerebras API Key:")
|
||||||
|
.DefaultValue(string.IsNullOrWhiteSpace(config.CerebrasApiKey) ? "" : config.CerebrasApiKey)
|
||||||
|
.AllowEmpty());
|
||||||
|
|
||||||
|
config.LlmModel = AnsiConsole.Prompt(
|
||||||
|
new SelectionPrompt<string>()
|
||||||
|
.Title("Select [green]LLM Model[/]:")
|
||||||
|
.AddChoices(new[] { "llama3.1-8b", "gpt-oss-120b" }));
|
||||||
|
}
|
||||||
|
else if (config.LlmProvider == "fireworks")
|
||||||
|
{
|
||||||
|
config.FireworksApiKey = AnsiConsole.Prompt(
|
||||||
|
new TextPrompt<string>("Fireworks API Key:")
|
||||||
|
.DefaultValue(string.IsNullOrWhiteSpace(config.FireworksApiKey) ? "" : config.FireworksApiKey)
|
||||||
|
.AllowEmpty());
|
||||||
|
|
||||||
|
config.LlmModel = AnsiConsole.Prompt(
|
||||||
|
new SelectionPrompt<string>()
|
||||||
|
.Title("Select [green]LLM Model[/]:")
|
||||||
|
.AddChoices(new[] { "accounts/fireworks/models/deepseek-v3p1", "fireworks/gpt-oss-120b", "fireworks/deepseek-v3p2", "fireworks/qwen3-8b", "fireworks/minimax-m2p5" })
|
||||||
|
.UseConverter(c => c.Split('/').Last()));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
config.GroqApiKey = AnsiConsole.Prompt(
|
||||||
|
new TextPrompt<string>("Groq API Key:")
|
||||||
|
.DefaultValue(string.IsNullOrWhiteSpace(config.GroqApiKey) ? "" : config.GroqApiKey)
|
||||||
|
.AllowEmpty());
|
||||||
|
|
||||||
config.LlmModel = AnsiConsole.Prompt(
|
config.LlmModel = AnsiConsole.Prompt(
|
||||||
new SelectionPrompt<string>()
|
new SelectionPrompt<string>()
|
||||||
.Title("Select [green]LLM Model[/]:")
|
.Title("Select [green]LLM Model[/]:")
|
||||||
@@ -57,11 +82,43 @@ public static class OnboardCommand
|
|||||||
.AddChoices(new[] { "none", "low" })
|
.AddChoices(new[] { "none", "low" })
|
||||||
.UseConverter(c => c == "none" ? "None (Standard)" : "Low (Moderate Reasoning)"));
|
.UseConverter(c => c == "none" ? "None (Standard)" : "Low (Moderate Reasoning)"));
|
||||||
|
|
||||||
config.WhisperModel = AnsiConsole.Prompt(
|
config.WhisperProvider = AnsiConsole.Prompt(
|
||||||
new SelectionPrompt<string>()
|
new SelectionPrompt<string>()
|
||||||
.Title("Select [green]Whisper Model[/]:")
|
.Title("Select [green]Whisper Provider[/]:")
|
||||||
.AddChoices(new[] { "whisper-large-v3", "whisper-large-v3-turbo" })
|
.AddChoices(new[] { "groq", "fireworks" })
|
||||||
.UseConverter(c => c == "whisper-large-v3" ? "whisper-large-v3 (Accurate)" : "whisper-large-v3-turbo (Fast)"));
|
.UseConverter(c => c == "groq" ? "Groq (Default)" : "Fireworks AI"));
|
||||||
|
|
||||||
|
if (config.WhisperProvider == "fireworks")
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(config.FireworksApiKey))
|
||||||
|
{
|
||||||
|
config.FireworksApiKey = AnsiConsole.Prompt(
|
||||||
|
new TextPrompt<string>("Fireworks API Key (required for Whisper):")
|
||||||
|
.DefaultValue("")
|
||||||
|
.AllowEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
config.WhisperModel = AnsiConsole.Prompt(
|
||||||
|
new SelectionPrompt<string>()
|
||||||
|
.Title("Select [green]Whisper Model[/]:")
|
||||||
|
.AddChoices(new[] { "fireworks/whisper-v3", "fireworks/whisper-v3-turbo" }));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(config.GroqApiKey))
|
||||||
|
{
|
||||||
|
config.GroqApiKey = AnsiConsole.Prompt(
|
||||||
|
new TextPrompt<string>("Groq API Key (required for Whisper):")
|
||||||
|
.DefaultValue("")
|
||||||
|
.AllowEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
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(
|
config.WhisperLanguage = AnsiConsole.Prompt(
|
||||||
new TextPrompt<string>("Microphone Spoken Language (e.g. en, es, zh):")
|
new TextPrompt<string>("Microphone Spoken Language (e.g. en, es, zh):")
|
||||||
|
|||||||
@@ -4,7 +4,10 @@ public class ToakConfig
|
|||||||
{
|
{
|
||||||
public string GroqApiKey { get; set; } = string.Empty;
|
public string GroqApiKey { get; set; } = string.Empty;
|
||||||
public string TogetherApiKey { get; set; } = string.Empty;
|
public string TogetherApiKey { get; set; } = string.Empty;
|
||||||
public string LlmProvider { get; set; } = "groq"; // groq or together
|
public string CerebrasApiKey { get; set; } = string.Empty;
|
||||||
|
public string FireworksApiKey { get; set; } = string.Empty;
|
||||||
|
public string LlmProvider { get; set; } = "groq"; // groq, together, cerebras, or fireworks
|
||||||
|
public string WhisperProvider { get; set; } = "groq"; // groq or fireworks
|
||||||
public string TypingBackend { get; set; } = "xdotool"; // wtype or xdotool
|
public string TypingBackend { get; set; } = "xdotool"; // wtype or xdotool
|
||||||
public string AudioBackend { get; set; } = "pw-record"; // pw-record or ffmpeg
|
public string AudioBackend { get; set; } = "pw-record"; // pw-record or ffmpeg
|
||||||
public bool ModulePunctuation { get; set; } = true;
|
public bool ModulePunctuation { get; set; } = true;
|
||||||
|
|||||||
@@ -40,19 +40,31 @@ public static class DaemonService
|
|||||||
|
|
||||||
var configManager = new ConfigManager();
|
var configManager = new ConfigManager();
|
||||||
var config = configManager.LoadConfig();
|
var config = configManager.LoadConfig();
|
||||||
if (string.IsNullOrWhiteSpace(config.GroqApiKey))
|
if (config.WhisperProvider == "groq" && string.IsNullOrWhiteSpace(config.GroqApiKey))
|
||||||
{
|
{
|
||||||
Console.WriteLine("Groq API Key is not configured. Run 'toak onboard'.");
|
Console.WriteLine("Groq API Key is not configured for Whisper. Run 'toak onboard'.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (config.WhisperProvider == "fireworks" && string.IsNullOrWhiteSpace(config.FireworksApiKey))
|
||||||
|
{
|
||||||
|
Console.WriteLine("Fireworks API Key is not configured for Whisper. Run 'toak onboard'.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var stateTracker = new StateTracker();
|
var stateTracker = new StateTracker();
|
||||||
var notifications = new Notifications();
|
var notifications = new Notifications();
|
||||||
|
|
||||||
var speechClient = new OpenAiCompatibleClient(config.GroqApiKey);
|
ISpeechClient speechClient = config.WhisperProvider == "fireworks"
|
||||||
ILlmClient llmClient = config.LlmProvider == "together"
|
? new OpenAiCompatibleClient(config.FireworksApiKey, "https://api.fireworks.ai/inference/v1/")
|
||||||
? new OpenAiCompatibleClient(config.TogetherApiKey, "https://api.together.xyz/v1/", config.ReasoningEffort)
|
: new OpenAiCompatibleClient(config.GroqApiKey);
|
||||||
: new OpenAiCompatibleClient(config.GroqApiKey, "https://api.groq.com/openai/v1/", config.ReasoningEffort);
|
|
||||||
|
ILlmClient llmClient = config.LlmProvider switch
|
||||||
|
{
|
||||||
|
"together" => new OpenAiCompatibleClient(config.TogetherApiKey, "https://api.together.xyz/v1/", config.ReasoningEffort),
|
||||||
|
"cerebras" => new OpenAiCompatibleClient(config.CerebrasApiKey, "https://api.cerebras.ai/v1/", config.ReasoningEffort),
|
||||||
|
"fireworks" => new OpenAiCompatibleClient(config.FireworksApiKey, "https://api.fireworks.ai/inference/v1/", config.ReasoningEffort),
|
||||||
|
_ => new OpenAiCompatibleClient(config.GroqApiKey, "https://api.groq.com/openai/v1/", config.ReasoningEffort)
|
||||||
|
};
|
||||||
|
|
||||||
IAudioRecorder recorder = config.AudioBackend == "ffmpeg"
|
IAudioRecorder recorder = config.AudioBackend == "ffmpeg"
|
||||||
? new FfmpegAudioRecorder(stateTracker, notifications)
|
? new FfmpegAudioRecorder(stateTracker, notifications)
|
||||||
|
|||||||
Reference in New Issue
Block a user