improve language-model compatibility error messages with docs URL

This commit is contained in:
leonardotrapani
2026-02-01 13:34:50 +01:00
parent 811ca71c08
commit 170ac22e3c
6 changed files with 70 additions and 12 deletions
+2 -2
View File
@@ -707,7 +707,7 @@ func TestValidateModelLanguageCompatibility(t *testing.T) {
model: "distil-whisper-large-v3-en", model: "distil-whisper-large-v3-en",
langCode: "es", langCode: "es",
wantErr: true, wantErr: true,
errContains: "does not support language 'es'", errContains: "does not support Spanish (es)",
}, },
{ {
name: "multilingual model supports spanish", name: "multilingual model supports spanish",
@@ -722,7 +722,7 @@ func TestValidateModelLanguageCompatibility(t *testing.T) {
model: "base.en", model: "base.en",
langCode: "fr", langCode: "fr",
wantErr: true, wantErr: true,
errContains: "does not support language 'fr'", errContains: "does not support French (fr)",
}, },
{ {
name: "whisper-cpp multilingual supports french", name: "whisper-cpp multilingual supports french",
+12 -5
View File
@@ -212,16 +212,23 @@ func ValidateModelLanguageCompatibility(registryProvider, modelID, langCode stri
// truncate supported languages for error message // truncate supported languages for error message
supported := model.SupportedLanguages supported := model.SupportedLanguages
suffix := "" suffix := ""
if len(supported) > 10 { if len(supported) > 5 {
supported = supported[:10] supported = supported[:5]
suffix = "..." suffix = "..."
} }
// build error with docs URL if available
docsHint := ""
if model.DocsURL != "" {
docsHint = fmt.Sprintf(" See %s for full list.", model.DocsURL)
}
return fmt.Errorf( return fmt.Errorf(
"model %s does not support language '%s' (%s). Either change model, select auto-detect, or choose a supported language: %s%s", "model %s does not support %s (%s).%s Supported: %s%s",
modelID, model.Name,
langCode,
langName, langName,
langCode,
docsHint,
strings.Join(supported, ", "), strings.Join(supported, ", "),
suffix, suffix,
) )
+14 -4
View File
@@ -151,15 +151,25 @@ func ValidateModelLanguage(providerName, modelID, langCode string) error {
// truncate supported languages list for error message // truncate supported languages list for error message
supported := model.SupportedLanguages supported := model.SupportedLanguages
if len(supported) > 10 { suffix := ""
supported = append(supported[:10], "...") if len(supported) > 5 {
supported = supported[:5]
suffix = "..."
}
// build error with docs URL if available
docsHint := ""
if model.DocsURL != "" {
docsHint = fmt.Sprintf(" See %s for full list.", model.DocsURL)
} }
return fmt.Errorf( return fmt.Errorf(
"model %s does not support language '%s'. Supported: %s", "model %s does not support language '%s'.%s Supported: %s%s",
modelID, model.Name,
langCode, langCode,
docsHint,
strings.Join(supported, ", "), strings.Join(supported, ", "),
suffix,
) )
} }
+30
View File
@@ -2,6 +2,7 @@ package provider
import ( import (
"slices" "slices"
"strings"
"testing" "testing"
) )
@@ -263,6 +264,35 @@ func TestValidateModelLanguage(t *testing.T) {
} }
} }
func TestValidateModelLanguage_ErrorFormat(t *testing.T) {
// verify error includes model name, not ID
err := ValidateModelLanguage("groq", "distil-whisper-large-v3-en", "es")
if err == nil {
t.Fatal("expected error for unsupported language")
}
errMsg := err.Error()
// should contain model name (from Model.Name)
if !strings.Contains(errMsg, "Distil Whisper Large v3 EN") {
t.Errorf("error should contain model name, got: %s", errMsg)
}
// should contain docs URL
if !strings.Contains(errMsg, "https://console.groq.com/docs/speech-to-text#supported-languages") {
t.Errorf("error should contain docs URL, got: %s", errMsg)
}
// should contain language code
if !strings.Contains(errMsg, "'es'") {
t.Errorf("error should contain language code, got: %s", errMsg)
}
// should have truncated language list (only 5 supported langs, English-only has 1)
if !strings.Contains(errMsg, "en") {
t.Errorf("error should contain supported languages, got: %s", errMsg)
}
}
func TestOpenAIRealtimeModel(t *testing.T) { func TestOpenAIRealtimeModel(t *testing.T) {
m, err := GetModel("openai", "gpt-4o-realtime-preview") m, err := GetModel("openai", "gpt-4o-realtime-preview")
if err != nil { if err != nil {
+11
View File
@@ -585,3 +585,14 @@ Started: Sun Feb 1 12:22:47 AM CET 2026
- LLM models don't have DocsURL (not needed - no language restrictions) - LLM models don't have DocsURL (not needed - no language restrictions)
- Added TestAllTranscriptionModels_HaveDocsURL test verifying all transcription models have correct URLs - Added TestAllTranscriptionModels_HaveDocsURL test verifying all transcription models have correct URLs
- All tests passing, typecheck passes - All tests passing, typecheck passes
### Task 10: Improve language-model compatibility error messages
- Updated `ValidateModelLanguageCompatibility` in internal/config/validate.go
- Updated `ValidateModelLanguage` in internal/provider/provider.go
- Error now includes: model Name (not ID), language Name (not just code), DocsURL, first 5 supported languages
- Format: "model {Name} does not support {LanguageName} ({code}). See {DocsURL} for full list. Supported: {langs}..."
- Truncated languages list from 10 to 5 for more concise errors
- TUI already displays err.Error() so improvements propagate automatically
- Added TestValidateModelLanguage_ErrorFormat test verifying error includes model name, docs URL, and language
- Updated test expectations in config_test.go for new error format
- All tests passing, typecheck passes
+1 -1
View File
@@ -168,7 +168,7 @@
"Error is actionable and clear", "Error is actionable and clear",
"Typecheck passes" "Typecheck passes"
], ],
"passes": false "passes": true
}, },
{ {
"title": "Update config validation for general language", "title": "Update config validation for general language",