Files
higress/plugins/wasm-go/extensions/ai-proxy/provider/qwen_test.go
2026-05-20 11:34:07 +08:00

215 lines
6.0 KiB
Go

package provider
import (
"encoding/json"
"net/http"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/tidwall/gjson"
)
func TestChatMessage2QwenMessagePreservesReasoningContent(t *testing.T) {
t.Run("string content", func(t *testing.T) {
msg := chatMessage{
Role: "assistant",
Content: "visible answer",
ReasoningContent: "preserved reasoning",
ToolCalls: []toolCall{
{
Id: "call_1",
Type: "function",
Function: functionCall{
Name: "lookup",
Arguments: `{"q":"weather"}`,
},
},
},
}
qwenMsg := chatMessage2QwenMessage(msg)
assert.Equal(t, "assistant", qwenMsg.Role)
assert.Equal(t, "visible answer", qwenMsg.Content)
assert.Equal(t, "preserved reasoning", qwenMsg.ReasoningContent)
require.Len(t, qwenMsg.ToolCalls, 1)
assert.Equal(t, "call_1", qwenMsg.ToolCalls[0].Id)
})
t.Run("array content", func(t *testing.T) {
msg := chatMessage{
Role: "assistant",
Content: []any{
map[string]any{
"type": "text",
"text": "visible answer",
},
},
ReasoningContent: "preserved reasoning",
}
qwenMsg := chatMessage2QwenMessage(msg)
assert.Equal(t, "assistant", qwenMsg.Role)
assert.Equal(t, "preserved reasoning", qwenMsg.ReasoningContent)
contents, ok := qwenMsg.Content.([]qwenVlMessageContent)
require.True(t, ok)
require.Len(t, contents, 1)
assert.Equal(t, "visible answer", contents[0].Text)
})
t.Run("array image content", func(t *testing.T) {
msg := chatMessage{
Role: "assistant",
Content: []any{
map[string]any{
"type": "image_url",
"image_url": map[string]any{
"url": "https://example.com/image.png",
},
},
},
ReasoningContent: "preserved reasoning",
}
qwenMsg := chatMessage2QwenMessage(msg)
assert.Equal(t, "preserved reasoning", qwenMsg.ReasoningContent)
contents, ok := qwenMsg.Content.([]qwenVlMessageContent)
require.True(t, ok)
require.Len(t, contents, 1)
assert.Equal(t, "https://example.com/image.png", contents[0].Image)
})
}
func TestBuildQwenTextGenerationRequestEnablesPreserveThinkingForReasoningHistory(t *testing.T) {
provider := &qwenProvider{}
request := &chatCompletionRequest{
Model: "qwen3.6-plus",
Messages: []chatMessage{
{Role: "assistant", Content: "visible answer", ReasoningContent: "historical reasoning"},
},
MaxTokens: 256,
}
body, err := provider.buildQwenTextGenerationRequest(nil, request, false)
require.NoError(t, err)
var qwenRequest qwenTextGenRequest
require.NoError(t, json.Unmarshal(body, &qwenRequest))
assert.True(t, qwenRequest.Parameters.PreserveThinking)
}
func TestBuildQwenTextGenerationRequestOmitsPreserveThinkingForUnsupportedModel(t *testing.T) {
provider := &qwenProvider{}
request := &chatCompletionRequest{
Model: "qwen-plus",
Messages: []chatMessage{
{Role: "assistant", Content: "visible answer", ReasoningContent: "historical reasoning"},
},
MaxTokens: 256,
}
body, err := provider.buildQwenTextGenerationRequest(nil, request, false)
require.NoError(t, err)
assert.False(t, gjson.GetBytes(body, "parameters.preserve_thinking").Exists())
}
func TestBuildQwenTextGenerationRequestOmitsPreserveThinkingWithoutReasoningHistory(t *testing.T) {
provider := &qwenProvider{}
request := &chatCompletionRequest{
Model: "qwen-plus",
Messages: []chatMessage{
{Role: "assistant", Content: "visible answer"},
},
MaxTokens: 256,
}
body, err := provider.buildQwenTextGenerationRequest(nil, request, false)
require.NoError(t, err)
assert.False(t, gjson.GetBytes(body, "parameters.preserve_thinking").Exists())
}
func TestTransformRequestBodyHeadersCompatibleModeEnablesPreserveThinkingForReasoningHistory(t *testing.T) {
provider := &qwenProvider{
config: ProviderConfig{
qwenEnableCompatible: true,
},
}
body := []byte(`{
"model":"qwen3.6-plus",
"messages":[
{"role":"assistant","content":"visible answer","reasoning_content":"historical reasoning"}
]
}`)
modifiedBody, err := provider.TransformRequestBodyHeaders(nil, ApiNameChatCompletion, body, http.Header{})
require.NoError(t, err)
assert.Equal(t, true, gjson.GetBytes(modifiedBody, "preserve_thinking").Bool())
}
func TestTransformRequestBodyHeadersCompatibleModeOmitsPreserveThinkingForUnsupportedModel(t *testing.T) {
provider := &qwenProvider{
config: ProviderConfig{
qwenEnableCompatible: true,
},
}
body := []byte(`{
"model":"qwen-plus",
"messages":[
{"role":"assistant","content":"visible answer","reasoning_content":"historical reasoning"}
]
}`)
modifiedBody, err := provider.TransformRequestBodyHeaders(nil, ApiNameChatCompletion, body, http.Header{})
require.NoError(t, err)
assert.False(t, gjson.GetBytes(modifiedBody, "preserve_thinking").Exists())
}
func TestTransformRequestBodyHeadersCompatibleModeEnablesPreserveThinkingAfterModelMapping(t *testing.T) {
provider := &qwenProvider{
config: ProviderConfig{
qwenEnableCompatible: true,
modelMapping: map[string]string{
"alias-model": "qwen3.6-plus-2026-04-02",
},
},
}
body := []byte(`{
"model":"alias-model",
"messages":[
{"role":"assistant","content":"visible answer","reasoning_content":"historical reasoning"}
]
}`)
modifiedBody, err := provider.TransformRequestBodyHeaders(nil, ApiNameChatCompletion, body, http.Header{})
require.NoError(t, err)
assert.Equal(t, "qwen3.6-plus-2026-04-02", gjson.GetBytes(modifiedBody, "model").String())
assert.Equal(t, true, gjson.GetBytes(modifiedBody, "preserve_thinking").Bool())
}
func TestTransformRequestBodyHeadersCompatibleModeOmitsPreserveThinkingWithoutReasoningHistory(t *testing.T) {
provider := &qwenProvider{
config: ProviderConfig{
qwenEnableCompatible: true,
},
}
body := []byte(`{
"model":"qwen-plus",
"messages":[
{"role":"assistant","content":"visible answer"}
]
}`)
modifiedBody, err := provider.TransformRequestBodyHeaders(nil, ApiNameChatCompletion, body, http.Header{})
require.NoError(t, err)
assert.False(t, gjson.GetBytes(modifiedBody, "preserve_thinking").Exists())
}