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"
|
"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
|
// editLLM handles the LLM section edit with smart provider detection
|
||||||
func editLLM(cfg *config.Config, configuredProviders []string) ([]string, error) {
|
func editLLM(cfg *config.Config, configuredProviders []string) ([]string, error) {
|
||||||
var llmProviders []string
|
var llmProviders []string
|
||||||
@@ -210,24 +215,21 @@ func getUnconfiguredLLMOptions(configuredProviders []string) []huh.Option[string
|
|||||||
return options
|
return options
|
||||||
}
|
}
|
||||||
|
|
||||||
func getLLMModelOptions(provider string) []huh.Option[string] {
|
func getLLMModelOptions(providerName string) []huh.Option[string] {
|
||||||
switch provider {
|
p := provider.GetProvider(providerName)
|
||||||
case "openai":
|
if p == nil {
|
||||||
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:
|
|
||||||
return []huh.Option[string]{}
|
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
|
// selectPostProcessingOptions shows a multi-select for LLM post-processing toggles
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
|
|
||||||
"github.com/charmbracelet/huh"
|
"github.com/charmbracelet/huh"
|
||||||
"github.com/leonardotrapani/hyprvoice/internal/config"
|
"github.com/leonardotrapani/hyprvoice/internal/config"
|
||||||
|
"github.com/leonardotrapani/hyprvoice/internal/language"
|
||||||
"github.com/leonardotrapani/hyprvoice/internal/provider"
|
"github.com/leonardotrapani/hyprvoice/internal/provider"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -68,7 +69,7 @@ func editTranscription(cfg *config.Config, configuredProviders []string) ([]stri
|
|||||||
configuredProviders = ensureProviderConfigured(cfg, selectedProvider, configuredProviders)
|
configuredProviders = ensureProviderConfigured(cfg, selectedProvider, configuredProviders)
|
||||||
cfg.Transcription.Provider = selectedProvider
|
cfg.Transcription.Provider = selectedProvider
|
||||||
|
|
||||||
modelOptions := getTranscriptionModelOptions(selectedProvider)
|
modelOptions := getTranscriptionModelOptions(selectedProvider, cfg.Transcription.Language)
|
||||||
selectedModel := cfg.Transcription.Model
|
selectedModel := cfg.Transcription.Model
|
||||||
if selectedModel == "" && len(modelOptions) > 0 {
|
if selectedModel == "" && len(modelOptions) > 0 {
|
||||||
selectedModel = modelOptions[0].Value
|
selectedModel = modelOptions[0].Value
|
||||||
@@ -136,32 +137,77 @@ func getUnconfiguredTranscriptionOptions(configuredProviders []string) []huh.Opt
|
|||||||
return options
|
return options
|
||||||
}
|
}
|
||||||
|
|
||||||
func getTranscriptionModelOptions(provider string) []huh.Option[string] {
|
func getTranscriptionModelOptions(configProvider string, currentLang string) []huh.Option[string] {
|
||||||
switch provider {
|
// special case: groq-translation only supports whisper-large-v3
|
||||||
case "openai":
|
if configProvider == "groq-translation" {
|
||||||
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":
|
|
||||||
return []huh.Option[string]{
|
return []huh.Option[string]{
|
||||||
huh.NewOption("whisper-large-v3 (only option)", "whisper-large-v3"),
|
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"),
|
// map config provider name to registry provider name
|
||||||
huh.NewOption("voxtral-mini-2507", "voxtral-mini-2507"),
|
registryName := mapConfigProviderToRegistry(configProvider)
|
||||||
}
|
p := provider.GetProvider(registryName)
|
||||||
case "elevenlabs":
|
if p == nil {
|
||||||
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:
|
|
||||||
return []huh.Option[string]{}
|
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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -264,3 +264,14 @@ Started: Sun Feb 1 12:22:47 AM CET 2026
|
|||||||
- Not installed: returns error 'model is not installed'
|
- Not installed: returns error 'model is not installed'
|
||||||
- Installed: calls `whisper.Remove()`, prints success message
|
- 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",
|
"No more hardcoded descriptions in TUI",
|
||||||
"Typecheck passes"
|
"Typecheck passes"
|
||||||
],
|
],
|
||||||
"passes": false
|
"passes": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title": "Add local provider options to TUI with dependency check",
|
"title": "Add local provider options to TUI with dependency check",
|
||||||
|
|||||||
Reference in New Issue
Block a user