package relay import ( "io" "net/http" "net/http/httptest" "strings" "testing" "github.com/QuantumNous/new-api/common" "github.com/QuantumNous/new-api/constant" relaycommon "github.com/QuantumNous/new-api/relay/common" "github.com/QuantumNous/new-api/relaykit/dto" "github.com/QuantumNous/new-api/setting/model_setting" "github.com/gin-gonic/gin" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/tidwall/gjson" ) func TestPrepareResponsesRequestDeepSeekEffectiveReasoning(t *testing.T) { settings := model_setting.GetGlobalSettings() previous := settings.PassThroughRequestEnabled t.Cleanup(func() { settings.PassThroughRequestEnabled = previous }) settings.PassThroughRequestEnabled = false const input = `[{"type":"function_call","call_id":"c1","name":"lookup","arguments":"{}"}]` for _, tc := range []struct { name, effort, override, endpoint string passthrough, replaceInput, wantReasoning bool globalPassthrough bool }{ {name: "override enables thinking", effort: "none", override: "high", wantReasoning: true}, {name: "override disables thinking", effort: "high", override: "none"}, {name: "override replaces history", effort: "high", override: "high", replaceInput: true, wantReasoning: true}, {name: "no override", effort: "high", wantReasoning: true}, {name: "thinking disabled", effort: "none"}, {name: "third party endpoint", effort: "none", override: "high", endpoint: "https://other.example"}, {name: "passthrough bypasses overrides and normalization", effort: "none", override: "high", passthrough: true}, {name: "global passthrough bypasses normalization", effort: "high", globalPassthrough: true}, } { t.Run(tc.name, func(t *testing.T) { settings.PassThroughRequestEnabled = tc.globalPassthrough endpoint := tc.endpoint if endpoint == "" { endpoint = "https://API.DEEPSEEK.COM:443/v1" } raw := `{"model":"deepseek-flash","reasoning":{"effort":"` + tc.effort + `"},"input":` + input + `}` c, _ := gin.CreateTestContext(httptest.NewRecorder()) c.Request = httptest.NewRequest(http.MethodPost, "/v1/responses", strings.NewReader(raw)) c.Request.Header.Set("Content-Type", "application/json") t.Cleanup(func() { common.CleanupBodyStorage(c) }) common.SetContextKey(c, constant.ContextKeyOriginalModel, "deepseek-flash") common.SetContextKey(c, constant.ContextKeyChannelType, constant.ChannelTypeDeepSeek) common.SetContextKey(c, constant.ContextKeyChannelBaseUrl, endpoint) common.SetContextKey(c, constant.ContextKeyChannelSetting, dto.ChannelSettings{PassThroughBodyEnabled: tc.passthrough}) if tc.override != "" { ops := []any{map[string]any{"path": "reasoning.effort", "mode": "set", "value": tc.override}, map[string]any{"path": "vendor_extension", "mode": "set", "value": "preserved"}} if tc.replaceInput { var replacement any require.NoError(t, common.Unmarshal([]byte(input), &replacement)) ops = append(ops, map[string]any{"path": "input", "mode": "set", "value": replacement}) } common.SetContextKey(c, constant.ContextKeyChannelParamOverride, map[string]any{"operations": ops}) } var req dto.OpenAIResponsesRequest require.NoError(t, common.Unmarshal([]byte(raw), &req)) info := relaycommon.GenRelayInfoResponses(c, &req) _, body, closer, apiErr := PrepareResponsesRequest(c, info, &req) require.Nil(t, apiErr) t.Cleanup(func() { require.NoError(t, closer.Close()) }) wire, err := io.ReadAll(body) require.NoError(t, err) if tc.passthrough || tc.globalPassthrough { assert.JSONEq(t, raw, string(wire)) return } wantEffort := tc.effort if tc.override != "" { wantEffort = tc.override assert.Equal(t, "preserved", gjson.GetBytes(wire, "vendor_extension").String()) } assert.Equal(t, wantEffort, gjson.GetBytes(wire, "reasoning.effort").String()) if tc.wantReasoning { assert.Equal(t, "reasoning", gjson.GetBytes(wire, "input.0.type").String()) assert.Equal(t, " ", gjson.GetBytes(wire, "input.0.content.0.text").String()) assert.Equal(t, "function_call", gjson.GetBytes(wire, "input.1.type").String()) } else { assert.JSONEq(t, input, gjson.GetBytes(wire, "input").Raw) } }) } }