mirror of
https://github.com/sipeed/picoclaw.git
synced 2026-06-12 18:08:54 +00:00
81a050555d
* 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
178 lines
4.6 KiB
Go
178 lines
4.6 KiB
Go
package providers
|
|
|
|
import "testing"
|
|
|
|
func TestParseModelRef_WithSlash(t *testing.T) {
|
|
ref := ParseModelRef("anthropic/claude-opus", "openai")
|
|
if ref == nil {
|
|
t.Fatal("expected non-nil ref")
|
|
}
|
|
if ref.Provider != "anthropic" {
|
|
t.Errorf("provider = %q, want anthropic", ref.Provider)
|
|
}
|
|
if ref.Model != "claude-opus" {
|
|
t.Errorf("model = %q, want claude-opus", ref.Model)
|
|
}
|
|
}
|
|
|
|
func TestParseModelRef_WithoutSlash(t *testing.T) {
|
|
ref := ParseModelRef("gpt-4", "openai")
|
|
if ref == nil {
|
|
t.Fatal("expected non-nil ref")
|
|
}
|
|
if ref.Provider != "openai" {
|
|
t.Errorf("provider = %q, want openai", ref.Provider)
|
|
}
|
|
if ref.Model != "gpt-4" {
|
|
t.Errorf("model = %q, want gpt-4", ref.Model)
|
|
}
|
|
}
|
|
|
|
func TestParseModelRef_Empty(t *testing.T) {
|
|
ref := ParseModelRef("", "openai")
|
|
if ref != nil {
|
|
t.Errorf("expected nil for empty string, got %+v", ref)
|
|
}
|
|
}
|
|
|
|
func TestParseModelRef_EmptyModelAfterSlash(t *testing.T) {
|
|
ref := ParseModelRef("openai/", "default")
|
|
if ref != nil {
|
|
t.Errorf("expected nil for empty model, got %+v", ref)
|
|
}
|
|
}
|
|
|
|
func TestParseModelRef_WhitespaceHandling(t *testing.T) {
|
|
ref := ParseModelRef(" anthropic / claude-opus ", "openai")
|
|
if ref == nil {
|
|
t.Fatal("expected non-nil ref")
|
|
}
|
|
if ref.Provider != "anthropic" {
|
|
t.Errorf("provider = %q, want anthropic", ref.Provider)
|
|
}
|
|
if ref.Model != "claude-opus" {
|
|
t.Errorf("model = %q, want claude-opus", ref.Model)
|
|
}
|
|
}
|
|
|
|
func TestNormalizeProvider(t *testing.T) {
|
|
tests := []struct {
|
|
input string
|
|
want string
|
|
}{
|
|
{"OpenAI", "openai"},
|
|
{"ANTHROPIC", "anthropic"},
|
|
{"z.ai", "zai"},
|
|
{"z-ai", "zai"},
|
|
{"Z.AI", "zai"},
|
|
{"opencode-zen", "opencode"},
|
|
{"qwen", "qwen-portal"},
|
|
{"kimi-code", "kimi-coding"},
|
|
{"gpt", "openai"},
|
|
{"claude", "anthropic"},
|
|
{"glm", "zhipu"},
|
|
{"google", "gemini"},
|
|
{"google-antigravity", "antigravity"},
|
|
{"groq", "groq"},
|
|
{"azure-openai", "azure"},
|
|
{"claudecli", "claude-cli"},
|
|
{"codexcli", "codex-cli"},
|
|
{"copilot", "github-copilot"},
|
|
// Alibaba Coding Plan aliases
|
|
{"alibaba-coding", "coding-plan"},
|
|
{"qwen-coding", "coding-plan"},
|
|
{"alibaba-coding-anthropic", "coding-plan-anthropic"},
|
|
// Qwen international aliases
|
|
{"qwen-international", "qwen-intl"},
|
|
{"dashscope-intl", "qwen-intl"},
|
|
{"dashscope-us", "qwen-us"},
|
|
{"", ""},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
got := NormalizeProvider(tt.input)
|
|
if got != tt.want {
|
|
t.Errorf("NormalizeProvider(%q) = %q, want %q", tt.input, got, tt.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestModelKey(t *testing.T) {
|
|
tests := []struct {
|
|
provider string
|
|
model string
|
|
want string
|
|
}{
|
|
{"openai", "gpt-4", "openai/gpt-4"},
|
|
{"Anthropic", "Claude-Opus", "anthropic/claude-opus"},
|
|
{"claude", "sonnet", "anthropic/sonnet"},
|
|
{"z.ai", "Model-X", "zai/model-x"},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
got := ModelKey(tt.provider, tt.model)
|
|
if got != tt.want {
|
|
t.Errorf("ModelKey(%q, %q) = %q, want %q", tt.provider, tt.model, got, tt.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestParseModelRef_ProviderNormalization(t *testing.T) {
|
|
ref := ParseModelRef("Z.AI/model-x", "default")
|
|
if ref == nil {
|
|
t.Fatal("expected non-nil ref")
|
|
}
|
|
if ref.Provider != "zai" {
|
|
t.Errorf("provider = %q, want zai", ref.Provider)
|
|
}
|
|
}
|
|
|
|
func TestParseModelRef_DefaultProviderNormalization(t *testing.T) {
|
|
ref := ParseModelRef("gpt-4o", "GPT")
|
|
if ref == nil {
|
|
t.Fatal("expected non-nil ref")
|
|
}
|
|
if ref.Provider != "openai" {
|
|
t.Errorf("provider = %q, want openai (normalized from GPT)", ref.Provider)
|
|
}
|
|
}
|
|
|
|
func TestParseModelRef_UnknownPrefixFallsBackToDefaultProvider(t *testing.T) {
|
|
ref := ParseModelRef("meta-llama/Llama-3.1-8B-Instruct", "openai")
|
|
if ref == nil {
|
|
t.Fatal("expected non-nil ref")
|
|
}
|
|
if ref.Provider != "openai" {
|
|
t.Fatalf("provider = %q, want openai", ref.Provider)
|
|
}
|
|
if ref.Model != "meta-llama/Llama-3.1-8B-Instruct" {
|
|
t.Fatalf("model = %q, want full original model ID", ref.Model)
|
|
}
|
|
}
|
|
|
|
func TestParseModelRef_UnknownPrefixPreservesEmptyDefaultProvider(t *testing.T) {
|
|
ref := ParseModelRef("meta-llama/Llama-3.1-8B-Instruct", "")
|
|
if ref == nil {
|
|
t.Fatal("expected non-nil ref")
|
|
}
|
|
if ref.Provider != "" {
|
|
t.Fatalf("provider = %q, want empty", ref.Provider)
|
|
}
|
|
if ref.Model != "meta-llama/Llama-3.1-8B-Instruct" {
|
|
t.Fatalf("model = %q, want full original model ID", ref.Model)
|
|
}
|
|
}
|
|
|
|
func TestParseModelRef_KnownNonSelectableProvider(t *testing.T) {
|
|
ref := ParseModelRef("bedrock/us.anthropic.claude-sonnet-4-20250514-v1:0", "openai")
|
|
if ref == nil {
|
|
t.Fatal("expected non-nil ref")
|
|
}
|
|
if ref.Provider != "bedrock" {
|
|
t.Fatalf("provider = %q, want bedrock", ref.Provider)
|
|
}
|
|
if ref.Model != "us.anthropic.claude-sonnet-4-20250514-v1:0" {
|
|
t.Fatalf("model = %q, want preserved bedrock model ID", ref.Model)
|
|
}
|
|
}
|