Files
hyprvoice/internal/tui/helpers.go
T

133 lines
3.1 KiB
Go

package tui
import (
"fmt"
"sort"
"strings"
"github.com/leonardotrapani/hyprvoice/internal/config"
"github.com/leonardotrapani/hyprvoice/internal/models/whisper"
"github.com/leonardotrapani/hyprvoice/internal/provider"
)
// AllProviders is the list of all supported cloud providers (require API keys).
var AllProviders = []string{"openai", "groq", "mistral", "elevenlabs", "deepgram"}
// LocalProviders is the list of local providers (no API key required).
var LocalProviders = []string{"whisper-cpp"}
// providerDisplayNames maps provider IDs to human-readable names.
var providerDisplayNames = map[string]string{
"openai": "OpenAI",
"groq": "Groq",
"mistral": "Mistral",
"elevenlabs": "ElevenLabs",
"deepgram": "Deepgram",
"whisper-cpp": "Whisper.cpp (local)",
}
func getProviderDisplayName(providerName string) string {
if name, ok := providerDisplayNames[providerName]; ok {
return name
}
return providerName
}
func getProviderKeyURL(providerName string) string {
p := provider.GetProvider(providerName)
if p == nil {
return ""
}
return p.APIKeyURL()
}
func maskAPIKey(key string) string {
if len(key) <= 8 {
return "***"
}
return key[:7] + "..." + key[len(key)-4:]
}
func getConfiguredProviders(cfg *config.Config) []string {
providers := make([]string, 0, len(cfg.Providers))
for name, pc := range cfg.Providers {
if pc.APIKey != "" {
providers = append(providers, name)
}
}
sort.Strings(providers)
return providers
}
func isProviderConfigured(cfg *config.Config, providerName string) bool {
if pc, ok := cfg.Providers[providerName]; ok {
return pc.APIKey != ""
}
return false
}
func mapConfigProviderToRegistry(configProvider string) string {
switch configProvider {
case "groq-transcription":
return "groq"
case "mistral-transcription":
return "mistral"
default:
return configProvider
}
}
func buildModelDesc(m provider.Model) string {
parts := []string{}
if m.Description != "" {
parts = append(parts, m.Description)
} else if m.Name != "" {
parts = append(parts, m.Name)
}
if m.Local {
parts = append(parts, "local model")
}
if m.SupportsBothModes() {
parts = append(parts, "batch+streaming")
} else if m.SupportsStreaming {
parts = append(parts, "streaming")
} else {
parts = append(parts, "batch-only")
}
if m.Local && m.LocalInfo != nil && m.LocalInfo.Size != "" {
parts = append(parts, fmt.Sprintf("size %s", m.LocalInfo.Size))
}
if len(parts) == 0 {
return "Transcription model"
}
return strings.Join(parts, " - ")
}
func getTranscriptionModelOptions(configProvider string) []modelOption {
registryName := mapConfigProviderToRegistry(configProvider)
p := provider.GetProvider(registryName)
if p == nil {
return []modelOption{}
}
models := provider.ModelsOfType(p, provider.Transcription)
options := make([]modelOption, 0, len(models))
for _, m := range models {
desc := buildModelDesc(m)
if m.Local && registryName == "whisper-cpp" {
if whisper.IsInstalled(m.ID) {
desc = desc + " - installed"
} else {
desc = desc + " - not installed"
}
}
options = append(options, modelOption{ID: m.ID, Title: m.ID, Desc: desc})
}
return options
}