add DocsURL field to Model struct for language support documentation
This commit is contained in:
@@ -37,6 +37,8 @@ func (p *DeepgramProvider) Models() []Model {
|
|||||||
"ro", "ru", "sk", "es", "sv", "th", "tr", "uk", "vi",
|
"ro", "ru", "sk", "es", "sv", "th", "tr", "uk", "vi",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
docsURL := "https://developers.deepgram.com/docs/language"
|
||||||
|
|
||||||
return []Model{
|
return []Model{
|
||||||
{
|
{
|
||||||
ID: "nova-3",
|
ID: "nova-3",
|
||||||
@@ -48,6 +50,7 @@ func (p *DeepgramProvider) Models() []Model {
|
|||||||
AdapterType: "deepgram",
|
AdapterType: "deepgram",
|
||||||
SupportedLanguages: nova3Langs,
|
SupportedLanguages: nova3Langs,
|
||||||
Endpoint: &EndpointConfig{BaseURL: "wss://api.deepgram.com", Path: "/v1/listen"},
|
Endpoint: &EndpointConfig{BaseURL: "wss://api.deepgram.com", Path: "/v1/listen"},
|
||||||
|
DocsURL: docsURL,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "nova-3-general",
|
ID: "nova-3-general",
|
||||||
@@ -59,6 +62,7 @@ func (p *DeepgramProvider) Models() []Model {
|
|||||||
AdapterType: "deepgram",
|
AdapterType: "deepgram",
|
||||||
SupportedLanguages: nova3Langs,
|
SupportedLanguages: nova3Langs,
|
||||||
Endpoint: &EndpointConfig{BaseURL: "wss://api.deepgram.com", Path: "/v1/listen"},
|
Endpoint: &EndpointConfig{BaseURL: "wss://api.deepgram.com", Path: "/v1/listen"},
|
||||||
|
DocsURL: docsURL,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "nova-2",
|
ID: "nova-2",
|
||||||
@@ -70,6 +74,7 @@ func (p *DeepgramProvider) Models() []Model {
|
|||||||
AdapterType: "deepgram",
|
AdapterType: "deepgram",
|
||||||
SupportedLanguages: nova2Langs,
|
SupportedLanguages: nova2Langs,
|
||||||
Endpoint: &EndpointConfig{BaseURL: "wss://api.deepgram.com", Path: "/v1/listen"},
|
Endpoint: &EndpointConfig{BaseURL: "wss://api.deepgram.com", Path: "/v1/listen"},
|
||||||
|
DocsURL: docsURL,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "nova-2-general",
|
ID: "nova-2-general",
|
||||||
@@ -81,6 +86,7 @@ func (p *DeepgramProvider) Models() []Model {
|
|||||||
AdapterType: "deepgram",
|
AdapterType: "deepgram",
|
||||||
SupportedLanguages: nova2Langs,
|
SupportedLanguages: nova2Langs,
|
||||||
Endpoint: &EndpointConfig{BaseURL: "wss://api.deepgram.com", Path: "/v1/listen"},
|
Endpoint: &EndpointConfig{BaseURL: "wss://api.deepgram.com", Path: "/v1/listen"},
|
||||||
|
DocsURL: docsURL,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ func (p *ElevenLabsProvider) Models() []Model {
|
|||||||
// ElevenLabs Scribe supports 90+ languages, including all 57 from our master list
|
// ElevenLabs Scribe supports 90+ languages, including all 57 from our master list
|
||||||
// See: https://elevenlabs.io/speech-to-text
|
// See: https://elevenlabs.io/speech-to-text
|
||||||
allLangs := language.AllLanguageCodes()
|
allLangs := language.AllLanguageCodes()
|
||||||
|
docsURL := "https://elevenlabs.io/docs/capabilities/speech-to-text#supported-languages"
|
||||||
|
|
||||||
return []Model{
|
return []Model{
|
||||||
// batch models
|
// batch models
|
||||||
@@ -39,6 +40,7 @@ func (p *ElevenLabsProvider) Models() []Model {
|
|||||||
AdapterType: "elevenlabs",
|
AdapterType: "elevenlabs",
|
||||||
SupportedLanguages: allLangs,
|
SupportedLanguages: allLangs,
|
||||||
Endpoint: &EndpointConfig{BaseURL: "https://api.elevenlabs.io", Path: "/v1/speech-to-text"},
|
Endpoint: &EndpointConfig{BaseURL: "https://api.elevenlabs.io", Path: "/v1/speech-to-text"},
|
||||||
|
DocsURL: docsURL,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "scribe_v2",
|
ID: "scribe_v2",
|
||||||
@@ -50,6 +52,7 @@ func (p *ElevenLabsProvider) Models() []Model {
|
|||||||
AdapterType: "elevenlabs",
|
AdapterType: "elevenlabs",
|
||||||
SupportedLanguages: allLangs,
|
SupportedLanguages: allLangs,
|
||||||
Endpoint: &EndpointConfig{BaseURL: "https://api.elevenlabs.io", Path: "/v1/speech-to-text"},
|
Endpoint: &EndpointConfig{BaseURL: "https://api.elevenlabs.io", Path: "/v1/speech-to-text"},
|
||||||
|
DocsURL: docsURL,
|
||||||
},
|
},
|
||||||
// streaming models
|
// streaming models
|
||||||
{
|
{
|
||||||
@@ -62,6 +65,7 @@ func (p *ElevenLabsProvider) Models() []Model {
|
|||||||
AdapterType: "elevenlabs-streaming",
|
AdapterType: "elevenlabs-streaming",
|
||||||
SupportedLanguages: allLangs,
|
SupportedLanguages: allLangs,
|
||||||
Endpoint: &EndpointConfig{BaseURL: "wss://api.elevenlabs.io", Path: "/v1/speech-to-text/realtime"},
|
Endpoint: &EndpointConfig{BaseURL: "wss://api.elevenlabs.io", Path: "/v1/speech-to-text/realtime"},
|
||||||
|
DocsURL: docsURL,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "scribe_v2-streaming",
|
ID: "scribe_v2-streaming",
|
||||||
@@ -73,6 +77,7 @@ func (p *ElevenLabsProvider) Models() []Model {
|
|||||||
AdapterType: "elevenlabs-streaming",
|
AdapterType: "elevenlabs-streaming",
|
||||||
SupportedLanguages: allLangs,
|
SupportedLanguages: allLangs,
|
||||||
Endpoint: &EndpointConfig{BaseURL: "wss://api.elevenlabs.io", Path: "/v1/speech-to-text/realtime"},
|
Endpoint: &EndpointConfig{BaseURL: "wss://api.elevenlabs.io", Path: "/v1/speech-to-text/realtime"},
|
||||||
|
DocsURL: docsURL,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ func (p *GroqProvider) IsLocal() bool {
|
|||||||
|
|
||||||
func (p *GroqProvider) Models() []Model {
|
func (p *GroqProvider) Models() []Model {
|
||||||
allLangs := language.AllLanguageCodes()
|
allLangs := language.AllLanguageCodes()
|
||||||
|
docsURL := "https://console.groq.com/docs/speech-to-text#supported-languages"
|
||||||
|
|
||||||
return []Model{
|
return []Model{
|
||||||
// transcription models
|
// transcription models
|
||||||
@@ -40,6 +41,7 @@ func (p *GroqProvider) Models() []Model {
|
|||||||
AdapterType: "openai",
|
AdapterType: "openai",
|
||||||
SupportedLanguages: allLangs,
|
SupportedLanguages: allLangs,
|
||||||
Endpoint: &EndpointConfig{BaseURL: "https://api.groq.com/openai", Path: "/v1/audio/transcriptions"},
|
Endpoint: &EndpointConfig{BaseURL: "https://api.groq.com/openai", Path: "/v1/audio/transcriptions"},
|
||||||
|
DocsURL: docsURL,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "whisper-large-v3-turbo",
|
ID: "whisper-large-v3-turbo",
|
||||||
@@ -51,6 +53,7 @@ func (p *GroqProvider) Models() []Model {
|
|||||||
AdapterType: "openai",
|
AdapterType: "openai",
|
||||||
SupportedLanguages: allLangs,
|
SupportedLanguages: allLangs,
|
||||||
Endpoint: &EndpointConfig{BaseURL: "https://api.groq.com/openai", Path: "/v1/audio/transcriptions"},
|
Endpoint: &EndpointConfig{BaseURL: "https://api.groq.com/openai", Path: "/v1/audio/transcriptions"},
|
||||||
|
DocsURL: docsURL,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "distil-whisper-large-v3-en",
|
ID: "distil-whisper-large-v3-en",
|
||||||
@@ -62,6 +65,7 @@ func (p *GroqProvider) Models() []Model {
|
|||||||
AdapterType: "openai",
|
AdapterType: "openai",
|
||||||
SupportedLanguages: []string{"en"},
|
SupportedLanguages: []string{"en"},
|
||||||
Endpoint: &EndpointConfig{BaseURL: "https://api.groq.com/openai", Path: "/v1/audio/transcriptions"},
|
Endpoint: &EndpointConfig{BaseURL: "https://api.groq.com/openai", Path: "/v1/audio/transcriptions"},
|
||||||
|
DocsURL: docsURL,
|
||||||
},
|
},
|
||||||
// LLM models
|
// LLM models
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ func (p *MistralProvider) IsLocal() bool {
|
|||||||
|
|
||||||
func (p *MistralProvider) Models() []Model {
|
func (p *MistralProvider) Models() []Model {
|
||||||
allLangs := language.AllLanguageCodes()
|
allLangs := language.AllLanguageCodes()
|
||||||
|
docsURL := "https://docs.mistral.ai/capabilities/speech/"
|
||||||
|
|
||||||
return []Model{
|
return []Model{
|
||||||
{
|
{
|
||||||
@@ -36,6 +37,7 @@ func (p *MistralProvider) Models() []Model {
|
|||||||
AdapterType: "openai",
|
AdapterType: "openai",
|
||||||
SupportedLanguages: allLangs,
|
SupportedLanguages: allLangs,
|
||||||
Endpoint: &EndpointConfig{BaseURL: "https://api.mistral.ai", Path: "/v1/audio/transcriptions"},
|
Endpoint: &EndpointConfig{BaseURL: "https://api.mistral.ai", Path: "/v1/audio/transcriptions"},
|
||||||
|
DocsURL: docsURL,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "voxtral-mini-2507",
|
ID: "voxtral-mini-2507",
|
||||||
@@ -47,6 +49,7 @@ func (p *MistralProvider) Models() []Model {
|
|||||||
AdapterType: "openai",
|
AdapterType: "openai",
|
||||||
SupportedLanguages: allLangs,
|
SupportedLanguages: allLangs,
|
||||||
Endpoint: &EndpointConfig{BaseURL: "https://api.mistral.ai", Path: "/v1/audio/transcriptions"},
|
Endpoint: &EndpointConfig{BaseURL: "https://api.mistral.ai", Path: "/v1/audio/transcriptions"},
|
||||||
|
DocsURL: docsURL,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ type Model struct {
|
|||||||
SupportedLanguages []string // explicit list of supported language codes
|
SupportedLanguages []string // explicit list of supported language codes
|
||||||
Endpoint *EndpointConfig // nil for local models
|
Endpoint *EndpointConfig // nil for local models
|
||||||
LocalInfo *LocalModelInfo // nil for cloud models
|
LocalInfo *LocalModelInfo // nil for cloud models
|
||||||
|
DocsURL string // URL to provider's language support documentation
|
||||||
}
|
}
|
||||||
|
|
||||||
// EndpointConfig holds HTTP/WebSocket endpoint configuration
|
// EndpointConfig holds HTTP/WebSocket endpoint configuration
|
||||||
|
|||||||
@@ -296,6 +296,7 @@ func TestModel_AllFields(t *testing.T) {
|
|||||||
Size: "100MB",
|
Size: "100MB",
|
||||||
DownloadURL: "https://example.com/test.bin",
|
DownloadURL: "https://example.com/test.bin",
|
||||||
},
|
},
|
||||||
|
DocsURL: "https://example.com/docs/languages",
|
||||||
}
|
}
|
||||||
|
|
||||||
if model.ID != "test-model" {
|
if model.ID != "test-model" {
|
||||||
@@ -328,4 +329,41 @@ func TestModel_AllFields(t *testing.T) {
|
|||||||
if model.LocalInfo == nil {
|
if model.LocalInfo == nil {
|
||||||
t.Error("LocalInfo should not be nil")
|
t.Error("LocalInfo should not be nil")
|
||||||
}
|
}
|
||||||
|
if model.DocsURL != "https://example.com/docs/languages" {
|
||||||
|
t.Errorf("DocsURL = %q, want 'https://example.com/docs/languages'", model.DocsURL)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAllTranscriptionModels_HaveDocsURL(t *testing.T) {
|
||||||
|
// verify all transcription models have DocsURL set
|
||||||
|
providers := []string{"openai", "groq", "mistral", "elevenlabs", "deepgram", "whisper-cpp"}
|
||||||
|
|
||||||
|
expectedDocsURLs := map[string]string{
|
||||||
|
"openai": "https://platform.openai.com/docs/guides/speech-to-text#supported-languages",
|
||||||
|
"groq": "https://console.groq.com/docs/speech-to-text#supported-languages",
|
||||||
|
"mistral": "https://docs.mistral.ai/capabilities/speech/",
|
||||||
|
"elevenlabs": "https://elevenlabs.io/docs/capabilities/speech-to-text#supported-languages",
|
||||||
|
"deepgram": "https://developers.deepgram.com/docs/language",
|
||||||
|
"whisper-cpp": "https://github.com/openai/whisper#available-models-and-languages",
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, pName := range providers {
|
||||||
|
p := GetProvider(pName)
|
||||||
|
if p == nil {
|
||||||
|
t.Errorf("GetProvider(%q) returned nil", pName)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedURL := expectedDocsURLs[pName]
|
||||||
|
for _, m := range p.Models() {
|
||||||
|
if m.Type != Transcription {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if m.DocsURL == "" {
|
||||||
|
t.Errorf("%s/%s: DocsURL is empty", pName, m.ID)
|
||||||
|
} else if m.DocsURL != expectedURL {
|
||||||
|
t.Errorf("%s/%s: DocsURL = %q, want %q", pName, m.ID, m.DocsURL, expectedURL)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ func (p *OpenAIProvider) IsLocal() bool {
|
|||||||
func (p *OpenAIProvider) Models() []Model {
|
func (p *OpenAIProvider) Models() []Model {
|
||||||
allLangs := language.AllLanguageCodes()
|
allLangs := language.AllLanguageCodes()
|
||||||
|
|
||||||
|
docsURL := "https://platform.openai.com/docs/guides/speech-to-text#supported-languages"
|
||||||
|
|
||||||
return []Model{
|
return []Model{
|
||||||
// transcription models
|
// transcription models
|
||||||
{
|
{
|
||||||
@@ -40,6 +42,7 @@ func (p *OpenAIProvider) Models() []Model {
|
|||||||
AdapterType: "openai",
|
AdapterType: "openai",
|
||||||
SupportedLanguages: allLangs,
|
SupportedLanguages: allLangs,
|
||||||
Endpoint: &EndpointConfig{BaseURL: "https://api.openai.com", Path: "/v1/audio/transcriptions"},
|
Endpoint: &EndpointConfig{BaseURL: "https://api.openai.com", Path: "/v1/audio/transcriptions"},
|
||||||
|
DocsURL: docsURL,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "gpt-4o-transcribe",
|
ID: "gpt-4o-transcribe",
|
||||||
@@ -51,6 +54,7 @@ func (p *OpenAIProvider) Models() []Model {
|
|||||||
AdapterType: "openai",
|
AdapterType: "openai",
|
||||||
SupportedLanguages: allLangs,
|
SupportedLanguages: allLangs,
|
||||||
Endpoint: &EndpointConfig{BaseURL: "https://api.openai.com", Path: "/v1/audio/transcriptions"},
|
Endpoint: &EndpointConfig{BaseURL: "https://api.openai.com", Path: "/v1/audio/transcriptions"},
|
||||||
|
DocsURL: docsURL,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "gpt-4o-mini-transcribe",
|
ID: "gpt-4o-mini-transcribe",
|
||||||
@@ -62,6 +66,7 @@ func (p *OpenAIProvider) Models() []Model {
|
|||||||
AdapterType: "openai",
|
AdapterType: "openai",
|
||||||
SupportedLanguages: allLangs,
|
SupportedLanguages: allLangs,
|
||||||
Endpoint: &EndpointConfig{BaseURL: "https://api.openai.com", Path: "/v1/audio/transcriptions"},
|
Endpoint: &EndpointConfig{BaseURL: "https://api.openai.com", Path: "/v1/audio/transcriptions"},
|
||||||
|
DocsURL: docsURL,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "gpt-4o-realtime-preview",
|
ID: "gpt-4o-realtime-preview",
|
||||||
@@ -73,6 +78,7 @@ func (p *OpenAIProvider) Models() []Model {
|
|||||||
AdapterType: "openai-realtime",
|
AdapterType: "openai-realtime",
|
||||||
SupportedLanguages: allLangs,
|
SupportedLanguages: allLangs,
|
||||||
Endpoint: &EndpointConfig{BaseURL: "wss://api.openai.com", Path: "/v1/realtime"},
|
Endpoint: &EndpointConfig{BaseURL: "wss://api.openai.com", Path: "/v1/realtime"},
|
||||||
|
DocsURL: docsURL,
|
||||||
},
|
},
|
||||||
// LLM models
|
// LLM models
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ func (p *WhisperCppProvider) IsLocal() bool {
|
|||||||
func (p *WhisperCppProvider) Models() []Model {
|
func (p *WhisperCppProvider) Models() []Model {
|
||||||
allLangs := language.AllLanguageCodes()
|
allLangs := language.AllLanguageCodes()
|
||||||
englishOnly := []string{"en"}
|
englishOnly := []string{"en"}
|
||||||
|
docsURL := "https://github.com/openai/whisper#available-models-and-languages"
|
||||||
|
|
||||||
whisperModels := whisper.ListModels()
|
whisperModels := whisper.ListModels()
|
||||||
result := make([]Model, 0, len(whisperModels))
|
result := make([]Model, 0, len(whisperModels))
|
||||||
@@ -54,6 +55,7 @@ func (p *WhisperCppProvider) Models() []Model {
|
|||||||
Size: wm.Size,
|
Size: wm.Size,
|
||||||
DownloadURL: whisper.GetDownloadURL(wm.ID),
|
DownloadURL: whisper.GetDownloadURL(wm.ID),
|
||||||
},
|
},
|
||||||
|
DocsURL: docsURL,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -571,4 +571,17 @@ Started: Sun Feb 1 12:22:47 AM CET 2026
|
|||||||
- Default selection skips headers to find first real model
|
- Default selection skips headers to find first real model
|
||||||
- Providers with only one type (e.g., Groq=batch, Deepgram=streaming) show no headers
|
- Providers with only one type (e.g., Groq=batch, Deepgram=streaming) show no headers
|
||||||
- Added unit tests: GroupsModels, NoHeadersForSingleType, OpenAI_GroupsCorrectly
|
- Added unit tests: GroupsModels, NoHeadersForSingleType, OpenAI_GroupsCorrectly
|
||||||
|
- All tests passing, typecheck passes
|
||||||
|
|
||||||
|
### Task 9: Add docs URLs to provider models
|
||||||
|
- Added `DocsURL string` field to Model struct in internal/provider/model.go
|
||||||
|
- Updated all 6 providers to set DocsURL for transcription models:
|
||||||
|
- OpenAI: https://platform.openai.com/docs/guides/speech-to-text#supported-languages
|
||||||
|
- Groq: https://console.groq.com/docs/speech-to-text#supported-languages
|
||||||
|
- Mistral: https://docs.mistral.ai/capabilities/speech/
|
||||||
|
- ElevenLabs: https://elevenlabs.io/docs/capabilities/speech-to-text#supported-languages
|
||||||
|
- Deepgram: https://developers.deepgram.com/docs/language
|
||||||
|
- whisper-cpp: https://github.com/openai/whisper#available-models-and-languages
|
||||||
|
- LLM models don't have DocsURL (not needed - no language restrictions)
|
||||||
|
- Added TestAllTranscriptionModels_HaveDocsURL test verifying all transcription models have correct URLs
|
||||||
- All tests passing, typecheck passes
|
- All tests passing, typecheck passes
|
||||||
+1
-1
@@ -150,7 +150,7 @@
|
|||||||
"URLs point to correct language support documentation",
|
"URLs point to correct language support documentation",
|
||||||
"Typecheck passes"
|
"Typecheck passes"
|
||||||
],
|
],
|
||||||
"passes": false
|
"passes": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title": "Improve language-model compatibility error messages",
|
"title": "Improve language-model compatibility error messages",
|
||||||
|
|||||||
Reference in New Issue
Block a user