refactor tui to use model metadata for descriptions
- getTranscriptionModelOptions now uses provider.ModelsOfType() instead of hardcoded switch - getLLMModelOptions now uses provider.ModelsOfType() instead of hardcoded switch - added currentLang param to show language compatibility warnings on models - buildModelLabel adds [size] for local models, [streaming] for streaming - mapConfigProviderToRegistry maps config names to registry names
This commit is contained in:
@@ -8,6 +8,11 @@ import (
|
||||
"github.com/leonardotrapani/hyprvoice/internal/provider"
|
||||
)
|
||||
|
||||
// buildLLMModelLabel creates the display label for an LLM model option
|
||||
func buildLLMModelLabel(m provider.Model) string {
|
||||
return fmt.Sprintf("%s (%s)", m.Name, m.Description)
|
||||
}
|
||||
|
||||
// editLLM handles the LLM section edit with smart provider detection
|
||||
func editLLM(cfg *config.Config, configuredProviders []string) ([]string, error) {
|
||||
var llmProviders []string
|
||||
@@ -210,24 +215,21 @@ func getUnconfiguredLLMOptions(configuredProviders []string) []huh.Option[string
|
||||
return options
|
||||
}
|
||||
|
||||
func getLLMModelOptions(provider string) []huh.Option[string] {
|
||||
switch provider {
|
||||
case "openai":
|
||||
return []huh.Option[string]{
|
||||
huh.NewOption("gpt-4o-mini (recommended)", "gpt-4o-mini"),
|
||||
huh.NewOption("gpt-4o", "gpt-4o"),
|
||||
huh.NewOption("gpt-4-turbo", "gpt-4-turbo"),
|
||||
huh.NewOption("gpt-3.5-turbo", "gpt-3.5-turbo"),
|
||||
}
|
||||
case "groq":
|
||||
return []huh.Option[string]{
|
||||
huh.NewOption("llama-3.3-70b-versatile (recommended)", "llama-3.3-70b-versatile"),
|
||||
huh.NewOption("llama-3.1-8b-instant (faster)", "llama-3.1-8b-instant"),
|
||||
huh.NewOption("mixtral-8x7b-32768", "mixtral-8x7b-32768"),
|
||||
}
|
||||
default:
|
||||
func getLLMModelOptions(providerName string) []huh.Option[string] {
|
||||
p := provider.GetProvider(providerName)
|
||||
if p == nil {
|
||||
return []huh.Option[string]{}
|
||||
}
|
||||
|
||||
models := provider.ModelsOfType(p, provider.LLM)
|
||||
var options []huh.Option[string]
|
||||
|
||||
for _, m := range models {
|
||||
label := buildLLMModelLabel(m)
|
||||
options = append(options, huh.NewOption(label, m.ID))
|
||||
}
|
||||
|
||||
return options
|
||||
}
|
||||
|
||||
// selectPostProcessingOptions shows a multi-select for LLM post-processing toggles
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
|
||||
"github.com/charmbracelet/huh"
|
||||
"github.com/leonardotrapani/hyprvoice/internal/config"
|
||||
"github.com/leonardotrapani/hyprvoice/internal/language"
|
||||
"github.com/leonardotrapani/hyprvoice/internal/provider"
|
||||
)
|
||||
|
||||
@@ -68,7 +69,7 @@ func editTranscription(cfg *config.Config, configuredProviders []string) ([]stri
|
||||
configuredProviders = ensureProviderConfigured(cfg, selectedProvider, configuredProviders)
|
||||
cfg.Transcription.Provider = selectedProvider
|
||||
|
||||
modelOptions := getTranscriptionModelOptions(selectedProvider)
|
||||
modelOptions := getTranscriptionModelOptions(selectedProvider, cfg.Transcription.Language)
|
||||
selectedModel := cfg.Transcription.Model
|
||||
if selectedModel == "" && len(modelOptions) > 0 {
|
||||
selectedModel = modelOptions[0].Value
|
||||
@@ -136,32 +137,77 @@ func getUnconfiguredTranscriptionOptions(configuredProviders []string) []huh.Opt
|
||||
return options
|
||||
}
|
||||
|
||||
func getTranscriptionModelOptions(provider string) []huh.Option[string] {
|
||||
switch provider {
|
||||
case "openai":
|
||||
return []huh.Option[string]{
|
||||
huh.NewOption("whisper-1", "whisper-1"),
|
||||
}
|
||||
case "groq-transcription":
|
||||
return []huh.Option[string]{
|
||||
huh.NewOption("whisper-large-v3-turbo (faster)", "whisper-large-v3-turbo"),
|
||||
huh.NewOption("whisper-large-v3 (standard)", "whisper-large-v3"),
|
||||
}
|
||||
case "groq-translation":
|
||||
func getTranscriptionModelOptions(configProvider string, currentLang string) []huh.Option[string] {
|
||||
// special case: groq-translation only supports whisper-large-v3
|
||||
if configProvider == "groq-translation" {
|
||||
return []huh.Option[string]{
|
||||
huh.NewOption("whisper-large-v3 (only option)", "whisper-large-v3"),
|
||||
}
|
||||
case "mistral-transcription":
|
||||
return []huh.Option[string]{
|
||||
huh.NewOption("voxtral-mini-latest (recommended)", "voxtral-mini-latest"),
|
||||
huh.NewOption("voxtral-mini-2507", "voxtral-mini-2507"),
|
||||
}
|
||||
case "elevenlabs":
|
||||
return []huh.Option[string]{
|
||||
huh.NewOption("scribe_v1 (99 languages, best accuracy)", "scribe_v1"),
|
||||
huh.NewOption("scribe_v2 (real-time, lower latency)", "scribe_v2"),
|
||||
}
|
||||
default:
|
||||
}
|
||||
|
||||
// map config provider name to registry provider name
|
||||
registryName := mapConfigProviderToRegistry(configProvider)
|
||||
p := provider.GetProvider(registryName)
|
||||
if p == nil {
|
||||
return []huh.Option[string]{}
|
||||
}
|
||||
|
||||
models := provider.ModelsOfType(p, provider.Transcription)
|
||||
var options []huh.Option[string]
|
||||
|
||||
for _, m := range models {
|
||||
// skip streaming models for now (not yet implemented)
|
||||
if m.Streaming {
|
||||
continue
|
||||
}
|
||||
|
||||
label := buildModelLabel(m, currentLang)
|
||||
options = append(options, huh.NewOption(label, m.ID))
|
||||
}
|
||||
|
||||
return options
|
||||
}
|
||||
|
||||
// mapConfigProviderToRegistry maps config provider names to registry provider names
|
||||
func mapConfigProviderToRegistry(configProvider string) string {
|
||||
switch configProvider {
|
||||
case "groq-transcription", "groq-translation":
|
||||
return "groq"
|
||||
case "mistral-transcription":
|
||||
return "mistral"
|
||||
default:
|
||||
return configProvider
|
||||
}
|
||||
}
|
||||
|
||||
// buildModelLabel creates the display label for a model option
|
||||
func buildModelLabel(m provider.Model, currentLang string) string {
|
||||
label := fmt.Sprintf("%s (%s)", m.Name, m.Description)
|
||||
|
||||
// append size for local models
|
||||
if m.Local && m.LocalInfo != nil {
|
||||
label += fmt.Sprintf(" [%s]", m.LocalInfo.Size)
|
||||
}
|
||||
|
||||
// append streaming tag
|
||||
if m.Streaming {
|
||||
label += " [streaming]"
|
||||
}
|
||||
|
||||
// append language warning if model doesn't support current language
|
||||
if currentLang != "" && !m.SupportsLanguage(currentLang) {
|
||||
langName := getLangName(currentLang)
|
||||
label += fmt.Sprintf(" (does not support %s)", langName)
|
||||
}
|
||||
|
||||
return label
|
||||
}
|
||||
|
||||
// getLangName returns a human-readable language name for a code
|
||||
func getLangName(code string) string {
|
||||
lang := language.FromCode(code)
|
||||
if lang.Code == "" {
|
||||
return code // unknown code, return as-is
|
||||
}
|
||||
return lang.Name
|
||||
}
|
||||
|
||||
+12
-1
@@ -263,4 +263,15 @@ Started: Sun Feb 1 12:22:47 AM CET 2026
|
||||
- Cloud models: prints 'nothing to remove'
|
||||
- Not installed: returns error 'model is not installed'
|
||||
- Installed: calls `whisper.Remove()`, prints success message
|
||||
- All verification scenarios tested, typecheck passes
|
||||
- All verification scenarios tested, typecheck passes
|
||||
|
||||
### Task 27: Refactor TUI to use Model metadata for descriptions
|
||||
- Refactored `getTranscriptionModelOptions()` to use `provider.ModelsOfType()` instead of hardcoded switch
|
||||
- Added `currentLang` parameter to show language compatibility warnings
|
||||
- Created `buildModelLabel()` helper: formats "Name (Description)", adds [size] for local, [streaming] for streaming models
|
||||
- Created `mapConfigProviderToRegistry()` to map config provider names (groq-transcription, mistral-transcription) to registry names
|
||||
- Refactored `getLLMModelOptions()` to use `provider.ModelsOfType()` instead of hardcoded switch
|
||||
- Created `buildLLMModelLabel()` helper for LLM model formatting
|
||||
- Added `getLangName()` helper to get human-readable language name from code
|
||||
- Added language import to configure_transcription.go
|
||||
- All tests passing, typecheck passes
|
||||
+1
-1
@@ -644,7 +644,7 @@
|
||||
"No more hardcoded descriptions in TUI",
|
||||
"Typecheck passes"
|
||||
],
|
||||
"passes": false
|
||||
"passes": true
|
||||
},
|
||||
{
|
||||
"title": "Add local provider options to TUI with dependency check",
|
||||
|
||||
Reference in New Issue
Block a user