mirror of
https://github.com/QuantumNous/new-api.git
synced 2026-03-30 02:25:00 +00:00
188 lines
5.6 KiB
Go
188 lines
5.6 KiB
Go
package service
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
relaycommon "github.com/QuantumNous/new-api/relay/common"
|
|
"github.com/QuantumNous/new-api/setting/operation_setting"
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func buildChannelAffinityTemplateContextForTest(meta channelAffinityMeta) *gin.Context {
|
|
rec := httptest.NewRecorder()
|
|
ctx, _ := gin.CreateTestContext(rec)
|
|
setChannelAffinityContext(ctx, meta)
|
|
return ctx
|
|
}
|
|
|
|
func TestApplyChannelAffinityOverrideTemplate_NoTemplate(t *testing.T) {
|
|
ctx := buildChannelAffinityTemplateContextForTest(channelAffinityMeta{
|
|
RuleName: "rule-no-template",
|
|
})
|
|
base := map[string]interface{}{
|
|
"temperature": 0.7,
|
|
}
|
|
|
|
merged, applied := ApplyChannelAffinityOverrideTemplate(ctx, base)
|
|
require.False(t, applied)
|
|
require.Equal(t, base, merged)
|
|
}
|
|
|
|
func TestApplyChannelAffinityOverrideTemplate_MergeTemplate(t *testing.T) {
|
|
ctx := buildChannelAffinityTemplateContextForTest(channelAffinityMeta{
|
|
RuleName: "rule-with-template",
|
|
ParamTemplate: map[string]interface{}{
|
|
"temperature": 0.2,
|
|
"top_p": 0.95,
|
|
},
|
|
UsingGroup: "default",
|
|
ModelName: "gpt-4.1",
|
|
RequestPath: "/v1/responses",
|
|
KeySourceType: "gjson",
|
|
KeySourcePath: "prompt_cache_key",
|
|
KeyHint: "abcd...wxyz",
|
|
KeyFingerprint: "abcd1234",
|
|
})
|
|
base := map[string]interface{}{
|
|
"temperature": 0.7,
|
|
"max_tokens": 2000,
|
|
}
|
|
|
|
merged, applied := ApplyChannelAffinityOverrideTemplate(ctx, base)
|
|
require.True(t, applied)
|
|
require.Equal(t, 0.7, merged["temperature"])
|
|
require.Equal(t, 0.95, merged["top_p"])
|
|
require.Equal(t, 2000, merged["max_tokens"])
|
|
require.Equal(t, 0.7, base["temperature"])
|
|
|
|
anyInfo, ok := ctx.Get(ginKeyChannelAffinityLogInfo)
|
|
require.True(t, ok)
|
|
info, ok := anyInfo.(map[string]interface{})
|
|
require.True(t, ok)
|
|
overrideInfoAny, ok := info["override_template"]
|
|
require.True(t, ok)
|
|
overrideInfo, ok := overrideInfoAny.(map[string]interface{})
|
|
require.True(t, ok)
|
|
require.Equal(t, true, overrideInfo["applied"])
|
|
require.Equal(t, "rule-with-template", overrideInfo["rule_name"])
|
|
require.EqualValues(t, 2, overrideInfo["param_override_keys"])
|
|
}
|
|
|
|
func TestApplyChannelAffinityOverrideTemplate_MergeOperations(t *testing.T) {
|
|
ctx := buildChannelAffinityTemplateContextForTest(channelAffinityMeta{
|
|
RuleName: "rule-with-ops-template",
|
|
ParamTemplate: map[string]interface{}{
|
|
"operations": []map[string]interface{}{
|
|
{
|
|
"mode": "pass_headers",
|
|
"value": []string{"Originator"},
|
|
},
|
|
},
|
|
},
|
|
})
|
|
base := map[string]interface{}{
|
|
"temperature": 0.7,
|
|
"operations": []map[string]interface{}{
|
|
{
|
|
"path": "model",
|
|
"mode": "trim_prefix",
|
|
"value": "openai/",
|
|
},
|
|
},
|
|
}
|
|
|
|
merged, applied := ApplyChannelAffinityOverrideTemplate(ctx, base)
|
|
require.True(t, applied)
|
|
require.Equal(t, 0.7, merged["temperature"])
|
|
|
|
opsAny, ok := merged["operations"]
|
|
require.True(t, ok)
|
|
ops, ok := opsAny.([]interface{})
|
|
require.True(t, ok)
|
|
require.Len(t, ops, 2)
|
|
|
|
firstOp, ok := ops[0].(map[string]interface{})
|
|
require.True(t, ok)
|
|
require.Equal(t, "pass_headers", firstOp["mode"])
|
|
|
|
secondOp, ok := ops[1].(map[string]interface{})
|
|
require.True(t, ok)
|
|
require.Equal(t, "trim_prefix", secondOp["mode"])
|
|
}
|
|
|
|
func TestChannelAffinityHitCodexTemplatePassHeadersEffective(t *testing.T) {
|
|
gin.SetMode(gin.TestMode)
|
|
|
|
setting := operation_setting.GetChannelAffinitySetting()
|
|
require.NotNil(t, setting)
|
|
|
|
var codexRule *operation_setting.ChannelAffinityRule
|
|
for i := range setting.Rules {
|
|
rule := &setting.Rules[i]
|
|
if strings.EqualFold(strings.TrimSpace(rule.Name), "codex cli trace") {
|
|
codexRule = rule
|
|
break
|
|
}
|
|
}
|
|
require.NotNil(t, codexRule)
|
|
|
|
affinityValue := fmt.Sprintf("pc-hit-%d", time.Now().UnixNano())
|
|
cacheKeySuffix := buildChannelAffinityCacheKeySuffix(*codexRule, "default", affinityValue)
|
|
|
|
cache := getChannelAffinityCache()
|
|
require.NoError(t, cache.SetWithTTL(cacheKeySuffix, 9527, time.Minute))
|
|
t.Cleanup(func() {
|
|
_, _ = cache.DeleteMany([]string{cacheKeySuffix})
|
|
})
|
|
|
|
rec := httptest.NewRecorder()
|
|
ctx, _ := gin.CreateTestContext(rec)
|
|
ctx.Request = httptest.NewRequest(http.MethodPost, "/v1/responses", strings.NewReader(fmt.Sprintf(`{"prompt_cache_key":"%s"}`, affinityValue)))
|
|
ctx.Request.Header.Set("Content-Type", "application/json")
|
|
|
|
channelID, found := GetPreferredChannelByAffinity(ctx, "gpt-5", "default")
|
|
require.True(t, found)
|
|
require.Equal(t, 9527, channelID)
|
|
|
|
baseOverride := map[string]interface{}{
|
|
"temperature": 0.2,
|
|
}
|
|
mergedOverride, applied := ApplyChannelAffinityOverrideTemplate(ctx, baseOverride)
|
|
require.True(t, applied)
|
|
require.Equal(t, 0.2, mergedOverride["temperature"])
|
|
|
|
info := &relaycommon.RelayInfo{
|
|
RequestHeaders: map[string]string{
|
|
"Originator": "Codex CLI",
|
|
"Session_id": "sess-123",
|
|
"User-Agent": "codex-cli-test",
|
|
},
|
|
ChannelMeta: &relaycommon.ChannelMeta{
|
|
ParamOverride: mergedOverride,
|
|
HeadersOverride: map[string]interface{}{
|
|
"X-Static": "legacy-static",
|
|
},
|
|
},
|
|
}
|
|
|
|
_, err := relaycommon.ApplyParamOverrideWithRelayInfo([]byte(`{"model":"gpt-5"}`), info)
|
|
require.NoError(t, err)
|
|
require.True(t, info.UseRuntimeHeadersOverride)
|
|
|
|
require.Equal(t, "legacy-static", info.RuntimeHeadersOverride["x-static"])
|
|
require.Equal(t, "Codex CLI", info.RuntimeHeadersOverride["originator"])
|
|
require.Equal(t, "sess-123", info.RuntimeHeadersOverride["session_id"])
|
|
require.Equal(t, "codex-cli-test", info.RuntimeHeadersOverride["user-agent"])
|
|
|
|
_, exists := info.RuntimeHeadersOverride["x-codex-beta-features"]
|
|
require.False(t, exists)
|
|
_, exists = info.RuntimeHeadersOverride["x-codex-turn-metadata"]
|
|
require.False(t, exists)
|
|
}
|