feat: better language selection

This commit is contained in:
leonardotrapani
2026-02-01 18:53:44 +01:00
parent 0025bf97b6
commit 3ae86f7bae
40 changed files with 452 additions and 852 deletions
-67
View File
@@ -1074,38 +1074,6 @@ func TestConfig_Validate_GroqTranscription(t *testing.T) {
}
}
func TestConfig_Validate_GroqTranslation(t *testing.T) {
config := &Config{
Recording: RecordingConfig{
SampleRate: 16000,
Channels: 1,
Format: "s16",
BufferSize: 8192,
ChannelBufferSize: 30,
Timeout: time.Minute,
},
Transcription: TranscriptionConfig{
Provider: "groq-translation",
APIKey: "gsk-test-key",
Language: "es",
Model: "whisper-large-v3", // Translation only supports non-turbo
},
Injection: InjectionConfig{
Backends: []string{"ydotool", "wtype", "clipboard"}, YdotoolTimeout: 5 * time.Second,
WtypeTimeout: time.Second,
ClipboardTimeout: time.Second,
},
Notifications: NotificationsConfig{
Type: "log",
},
}
err := config.Validate()
if err != nil {
t.Errorf("Validate() should have passed with valid groq-translation config: %v", err)
}
}
func TestConfig_Validate_GroqInvalidModel(t *testing.T) {
config := &Config{
Recording: RecordingConfig{
@@ -1248,41 +1216,6 @@ func TestConfig_ToTranscriberConfig_GroqWithEnvVar(t *testing.T) {
}
}
func TestConfig_Validate_GroqTranslation_RejectsTurbo(t *testing.T) {
config := &Config{
Recording: RecordingConfig{
SampleRate: 16000,
Channels: 1,
Format: "s16",
BufferSize: 8192,
ChannelBufferSize: 30,
Timeout: time.Minute,
},
Transcription: TranscriptionConfig{
Provider: "groq-translation",
APIKey: "gsk-test-key",
Language: "es",
Model: "whisper-large-v3-turbo", // Turbo not supported for translation
},
Injection: InjectionConfig{
Backends: []string{"ydotool", "wtype", "clipboard"}, YdotoolTimeout: 5 * time.Second,
WtypeTimeout: time.Second,
ClipboardTimeout: time.Second,
},
Notifications: NotificationsConfig{
Type: "log",
},
}
err := config.Validate()
if err == nil {
t.Error("Validate() should have rejected whisper-large-v3-turbo for groq-translation")
}
if err != nil && err.Error() != "invalid model for groq-translation: whisper-large-v3-turbo (must be whisper-large-v3, turbo version not supported for translation)" {
t.Errorf("Unexpected error message: %v", err)
}
}
func TestMessagesConfig_Resolve_Defaults(t *testing.T) {
cfg := createTestConfig()
msgs := cfg.Notifications.Messages.Resolve()
+1 -1
View File
@@ -104,7 +104,7 @@ func (c *Config) migrateTranscriptionAPIKey(apiKey string) {
switch providerName {
case "openai":
c.Providers["openai"] = ProviderConfig{APIKey: apiKey}
case "groq-transcription", "groq-translation":
case "groq-transcription":
c.Providers["groq"] = ProviderConfig{APIKey: apiKey}
case "mistral-transcription":
c.Providers["mistral"] = ProviderConfig{APIKey: apiKey}
+1 -2
View File
@@ -246,7 +246,7 @@ keywords = []
# ─────────────────────────────────────────────────────────────────────────────
[transcription]
provider = "openai" # "openai", "groq-transcription", "groq-translation", "mistral-transcription", "elevenlabs", "whisper-cpp"
provider = "openai" # "openai", "groq-transcription", "mistral-transcription", "elevenlabs", "whisper-cpp"
model = "whisper-1" # Model: OpenAI="whisper-1", Groq="whisper-large-v3", Mistral="voxtral-mini-latest", ElevenLabs="scribe_v1"
language = "" # ISO 639-1 code (e.g., en, es, de). Empty for auto-detect.
threads = 0 # CPU threads for local transcription (0 = auto: uses NumCPU-1)
@@ -325,7 +325,6 @@ keywords = []
# Transcription providers:
# - "openai": OpenAI Whisper API (cloud-based, excellent accuracy)
# - "groq-transcription": Groq Whisper API (very fast, models: whisper-large-v3, whisper-large-v3-turbo)
# - "groq-translation": Groq translation to English (always outputs English text, model: whisper-large-v3)
# - "mistral-transcription": Mistral Voxtral API (excellent for European languages, model: voxtral-mini-latest)
# - "elevenlabs": ElevenLabs Scribe API (99 languages, models: scribe_v1, scribe_v2)
#
+3 -21
View File
@@ -2,19 +2,17 @@ package config
import (
"fmt"
"log"
"strings"
"github.com/leonardotrapani/hyprvoice/internal/language"
"github.com/leonardotrapani/hyprvoice/internal/provider"
)
// mapConfigProviderToRegistryName maps config provider names to provider registry names
// Config uses names like "groq-transcription", "groq-translation", "mistral-transcription"
// Config uses names like "groq-transcription", "mistral-transcription"
// Registry uses base names like "groq", "mistral"
func mapConfigProviderToRegistryName(configProvider string) string {
switch configProvider {
case "groq-transcription", "groq-translation":
case "groq-transcription":
return "groq"
case "mistral-transcription":
return "mistral"
@@ -85,21 +83,11 @@ func (c *Config) Validate() error {
}
}
// validate language codes - warn if not recognized but don't error
if c.Transcription.Language != "" && !language.IsValidCode(c.Transcription.Language) {
log.Printf("warning: unrecognized language code '%s' in transcription.language, will be passed as-is to provider", c.Transcription.Language)
}
// validate model exists
if c.Transcription.Model == "" {
return fmt.Errorf("invalid transcription.model: empty")
}
// groq-translation is a special case - only supports whisper-large-v3
if c.Transcription.Provider == "groq-translation" && c.Transcription.Model != "whisper-large-v3" {
return fmt.Errorf("invalid model for groq-translation: %s (must be whisper-large-v3, turbo version not supported for translation)", c.Transcription.Model)
}
// validate model exists in provider
_, err := provider.GetModel(registryName, c.Transcription.Model)
if err != nil {
@@ -205,11 +193,6 @@ func ValidateModelLanguageCompatibility(registryProvider, modelID, langCode stri
}
// language not supported - build helpful error message
langName := language.FromCode(langCode).Name
if langName == "Auto-detect" {
langName = langCode // use code if not found
}
// truncate supported languages for error message
supported := model.SupportedLanguages
suffix := ""
@@ -225,9 +208,8 @@ func ValidateModelLanguageCompatibility(registryProvider, modelID, langCode stri
}
return fmt.Errorf(
"model %s does not support %s (%s).%s Supported: %s%s",
"model %s does not support language '%s'.%s Supported: %s%s",
model.Name,
langName,
langCode,
docsHint,
strings.Join(supported, ", "),