Files
picoclaw/pkg/audio/asr/asr_test.go
T
LC 81a050555d feat(provider,web,asr): enhance model management with explicit provider metadata (#2701)
* feat(provider,web): enhance model management with provider options

* fix(asr): enhance compatibility for ElevenLabs transcription model

* fix(provider,web): align provider availability predicates and add flow gating

* fix(web,asr): preserve legacy elevenlabs transcription configs

* fix(provider,web,asr): normalize elevenlabs configs and gate default chat models

* fix: tighten provider catalog and elevenlabs compatibility
2026-05-06 16:06:49 +08:00

244 lines
6.2 KiB
Go

package asr
import (
"testing"
"github.com/sipeed/picoclaw/pkg/config"
)
func TestDetectTranscriber(t *testing.T) {
tests := []struct {
name string
cfg *config.Config
wantNil bool
wantName string
}{
{
name: "no config",
cfg: &config.Config{},
wantNil: true,
},
{
name: "voice model name selects audio model transcriber",
cfg: &config.Config{
Voice: config.VoiceConfig{ModelName: "voice-gemini"},
ModelList: []*config.ModelConfig{
{
ModelName: "voice-gemini",
Model: "gemini/gemini-2.5-flash",
APIKeys: config.SimpleSecureStrings("sk-gemini-model"),
},
},
},
wantName: "audio-model",
},
{
name: "voice model name alias selects elevenlabs transcriber",
cfg: &config.Config{
Voice: config.VoiceConfig{ModelName: "my-asr-model"},
ModelList: []*config.ModelConfig{
{
ModelName: "my-asr-model",
Model: "elevenlabs/scribe_v1",
APIKeys: config.SimpleSecureStrings("sk_elevenlabs_test"),
},
},
},
wantName: "elevenlabs",
},
{
name: "explicit elevenlabs provider selects elevenlabs transcriber",
cfg: &config.Config{
Voice: config.VoiceConfig{ModelName: "my-asr-model"},
ModelList: []*config.ModelConfig{
{
ModelName: "my-asr-model",
Provider: "elevenlabs",
Model: "scribe_v1",
APIKeys: config.SimpleSecureStrings("sk_elevenlabs_test"),
},
},
},
wantName: "elevenlabs",
},
{
name: "voice model name alias selects whisper transcriber for groq",
cfg: &config.Config{
Voice: config.VoiceConfig{ModelName: "my-asr-model"},
ModelList: []*config.ModelConfig{
{
ModelName: "my-asr-model",
Model: "groq/whisper-large-v3",
APIKeys: config.SimpleSecureStrings("sk-groq-model"),
},
},
},
wantName: "whisper",
},
{
name: "openai whisper alias selects whisper transcriber",
cfg: &config.Config{
Voice: config.VoiceConfig{ModelName: "my-asr-model"},
ModelList: []*config.ModelConfig{
{
ModelName: "my-asr-model",
Model: "openai/whisper-1",
APIKeys: config.SimpleSecureStrings("sk-openai-model"),
},
},
},
wantName: "whisper",
},
{
name: "whisper via model list fallback",
cfg: &config.Config{
ModelList: []*config.ModelConfig{
{ModelName: "openai", Model: "openai/gpt-4o", APIKeys: config.SimpleSecureStrings("sk-openai")},
{
ModelName: "groq",
Model: "groq/whisper-large-v3-turbo",
APIKeys: config.SimpleSecureStrings("sk-groq-model"),
},
},
},
wantName: "whisper",
},
{
name: "voice model name alias selects non-gemini audio model transcriber",
cfg: &config.Config{
Voice: config.VoiceConfig{ModelName: "my-asr-model"},
ModelList: []*config.ModelConfig{
{
ModelName: "my-asr-model",
Model: "openai/gpt-4o-audio-preview",
APIKeys: config.SimpleSecureStrings("sk-openai"),
},
},
},
wantName: "audio-model",
},
{
name: "voice model name selects azure audio model transcriber",
cfg: &config.Config{
Voice: config.VoiceConfig{ModelName: "voice-azure-audio"},
ModelList: []*config.ModelConfig{
{
ModelName: "voice-azure-audio",
Model: "azure/my-audio-deployment", APIKeys: config.SimpleSecureStrings("sk-azure"),
APIBase: "https://example.openai.azure.com",
},
},
},
wantName: "audio-model",
},
{
name: "voice model name with non openai compatible protocol does not select audio model transcriber",
cfg: &config.Config{
Voice: config.VoiceConfig{ModelName: "voice-anthropic"},
ModelList: []*config.ModelConfig{
{
ModelName: "voice-anthropic",
Model: "anthropic/claude-sonnet-4.6",
APIKeys: config.SimpleSecureStrings("sk-anthropic"),
},
},
},
wantNil: true,
},
{
name: "groq model list entry without key is skipped",
cfg: &config.Config{
ModelList: []*config.ModelConfig{
{Model: "groq/whisper-large-v3"},
},
},
wantNil: true,
},
{
name: "provider key takes priority over model list",
cfg: &config.Config{
ModelList: []*config.ModelConfig{
{
ModelName: "groq",
Model: "groq/whisper-large-v3",
APIKeys: config.SimpleSecureStrings("sk-groq-model"),
},
},
},
wantName: "whisper",
},
{
name: "missing voice model name config returns nil",
cfg: &config.Config{
Voice: config.VoiceConfig{ModelName: "missing"},
ModelList: []*config.ModelConfig{
{
ModelName: "other",
Model: "gemini/gemini-2.5-flash",
APIKeys: config.SimpleSecureStrings("sk-other-model"),
},
},
},
wantNil: true,
},
{
name: "elevenlabs voice config key",
cfg: &config.Config{
ModelList: []*config.ModelConfig{
{Model: "elevenlabs/scribe_v1", APIKeys: config.SimpleSecureStrings("sk_elevenlabs_test")},
},
},
wantName: "elevenlabs",
},
{
name: "elevenlabs takes priority over groq model list",
cfg: &config.Config{
ModelList: []*config.ModelConfig{
{Model: "elevenlabs/scribe_v1", APIKeys: config.SimpleSecureStrings("sk_elevenlabs_test")},
{
ModelName: "groq",
Model: "groq/llama-3.3-70b",
APIKeys: config.SimpleSecureStrings("sk-groq-model"),
},
},
},
wantName: "elevenlabs",
},
{
name: "voice model name takes priority over elevenlabs",
cfg: &config.Config{
Voice: config.VoiceConfig{
ModelName: "voice-gemini",
},
ModelList: []*config.ModelConfig{
{Model: "elevenlabs", APIKeys: config.SimpleSecureStrings("sk_elevenlabs_test")},
{
ModelName: "voice-gemini",
Model: "gemini/gemini-2.5-flash",
APIKeys: config.SimpleSecureStrings("sk-gemini-model"),
},
},
},
wantName: "audio-model",
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
tr := DetectTranscriber(tc.cfg)
if tc.wantNil {
if tr != nil {
t.Errorf("DetectTranscriber() = %v, want nil", tr)
}
return
}
if tr == nil {
t.Fatal("DetectTranscriber() = nil, want non-nil")
}
if got := tr.Name(); got != tc.wantName {
t.Errorf("Name() = %q, want %q", got, tc.wantName)
}
})
}
}