diff --git a/internal/entity/models/common.go b/internal/entity/models/common.go index 20ac2e461f..bfc99bc280 100644 --- a/internal/entity/models/common.go +++ b/internal/entity/models/common.go @@ -45,7 +45,7 @@ func NormalizeModelFamily(modelType *string) string { family = family[slash+1:] } - if strings.HasPrefix(family, "qwen3") { + if family == "qwen3" || strings.HasPrefix(family, "qwen3-") || strings.HasPrefix(family, "qwen3.") { return "qwen3" } diff --git a/internal/entity/models/common_test.go b/internal/entity/models/common_test.go index f8bc589c59..09d5ca50b3 100644 --- a/internal/entity/models/common_test.go +++ b/internal/entity/models/common_test.go @@ -11,10 +11,13 @@ func TestNormalizeModelFamily(t *testing.T) { {name: "nil", input: nil, want: ""}, {name: "empty", input: modelFamilyTestString(""), want: ""}, {name: "qwen3", input: modelFamilyTestString("qwen3"), want: "qwen3"}, - {name: "qwen3 variant", input: modelFamilyTestString("qwen3-8b"), want: "qwen3"}, + {name: "qwen3 hyphen variant", input: modelFamilyTestString("qwen3-8b"), want: "qwen3"}, + {name: "qwen3 dot variant", input: modelFamilyTestString("qwen3.5-4b"), want: "qwen3"}, {name: "provider-prefixed qwen3", input: modelFamilyTestString("qwen/qwen3-8b"), want: "qwen3"}, {name: "case-varied qwen3", input: modelFamilyTestString("Qwen/Qwen3.5-4B"), want: "qwen3"}, {name: "provider-prefixed non-qwen", input: modelFamilyTestString("deepseek/deepseek-r1"), want: "deepseek"}, + {name: "qwen plus not qwen3", input: modelFamilyTestString("qwen-plus"), want: "qwen"}, + {name: "provider-prefixed qwen2.5 not qwen3", input: modelFamilyTestString("qwen/qwen2.5-32b-instruct"), want: "qwen2.5"}, } for _, tt := range tests { @@ -27,21 +30,19 @@ func TestNormalizeModelFamily(t *testing.T) { } func TestGetThinkingAndAnswerExtractsQwenThinking(t *testing.T) { - tests := []string{ + content := "\nplan\nanswer" + + for _, modelType := range []string{ "qwen3", "qwen3-8b", "qwen/qwen3", "qwen/qwen3-8b", "Qwen/Qwen3.5-4B", - } - - for _, modelFamily := range tests { - t.Run(modelFamily, func(t *testing.T) { - content := "\nreasoning\nanswer" - reasoning, answer := GetThinkingAndAnswer(&modelFamily, &content) - - if reasoning == nil || *reasoning != "reasoning" { - t.Fatalf("reasoning=%v, want reasoning", reasoning) + } { + t.Run(modelType, func(t *testing.T) { + thinking, answer := GetThinkingAndAnswer(&modelType, &content) + if thinking == nil || *thinking != "plan" { + t.Fatalf("thinking=%v, want plan", thinking) } if answer == nil || *answer != "answer" { t.Fatalf("answer=%v, want answer", answer) @@ -50,32 +51,49 @@ func TestGetThinkingAndAnswerExtractsQwenThinking(t *testing.T) { } } -func TestGetThinkingAndAnswerSkipsUnknownFamily(t *testing.T) { - modelFamily := "deepseek/deepseek-r1" - content := "reasoninganswer" +func TestGetThinkingAndAnswerLeavesUnknownModelFamiliesUnchanged(t *testing.T) { + content := "\nplan\nanswer" - reasoning, answer := GetThinkingAndAnswer(&modelFamily, &content) - if reasoning != nil { - t.Fatalf("reasoning=%q, want nil", *reasoning) - } - if answer == nil || *answer != content { - t.Fatalf("answer=%v, want original content", answer) + for _, modelType := range []string{ + "deepseek", + "deepseek/deepseek-r1", + "qwen-plus", + "qwen/qwen2.5-32b-instruct", + } { + t.Run(modelType, func(t *testing.T) { + thinking, answer := GetThinkingAndAnswer(&modelType, &content) + if thinking != nil { + t.Fatalf("thinking=%v, want nil", thinking) + } + if answer != &content { + t.Fatalf("answer pointer changed") + } + }) } } func TestGetThinkingAndAnswerHandlesNilInputs(t *testing.T) { - reasoning, answer := GetThinkingAndAnswer(nil, nil) - if reasoning != nil || answer != nil { - t.Fatalf("GetThinkingAndAnswer(nil, nil)=(%v, %v), want nils", reasoning, answer) + thinking, answer := GetThinkingAndAnswer(nil, nil) + if thinking != nil || answer != nil { + t.Fatalf("GetThinkingAndAnswer(nil, nil)=(%v, %v), want nils", thinking, answer) } - content := "answer" - reasoning, answer = GetThinkingAndAnswer(nil, &content) - if reasoning != nil { - t.Fatalf("reasoning=%q, want nil", *reasoning) + content := "\nplan\nanswer" + thinking, answer = GetThinkingAndAnswer(nil, &content) + if thinking != nil { + t.Fatalf("thinking=%v, want nil", thinking) } - if answer == nil || *answer != content { - t.Fatalf("answer=%v, want original content", answer) + if answer != &content { + t.Fatalf("answer pointer changed") + } + + modelType := "qwen3" + thinking, answer = GetThinkingAndAnswer(&modelType, nil) + if thinking != nil { + t.Fatalf("thinking=%v, want nil", thinking) + } + if answer != nil { + t.Fatalf("answer=%v, want nil", answer) } }