From e2beb6cd45d634cdc6183287d2dce6cb7b414862 Mon Sep 17 00:00:00 2001 From: johnlanni Date: Sat, 11 Apr 2026 07:57:38 +0800 Subject: [PATCH] =?UTF-8?q?Revert=20"feat(model-mapper):=20=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=20modelToHeader=20=E9=85=8D=E7=BD=AE=E9=A1=B9?= =?UTF-8?q?=E5=B9=B6=E4=BC=98=E5=8C=96=20header=20=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E9=80=BB=E8=BE=91=20||=20feat(model-mapper):=20Added=20modelTo?= =?UTF-8?q?Header=20configuration=20item=20and=20optimized=20header=20upda?= =?UTF-8?q?te=20logic=20(#3689)"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 60ce07d29722f9678fc854f1534781fe02f076e7. --- .../wasm-go/extensions/model-mapper/main.go | 13 -- .../extensions/model-mapper/main_test.go | 203 ------------------ 2 files changed, 216 deletions(-) diff --git a/plugins/wasm-go/extensions/model-mapper/main.go b/plugins/wasm-go/extensions/model-mapper/main.go index 44986f6fc..68f5becb4 100644 --- a/plugins/wasm-go/extensions/model-mapper/main.go +++ b/plugins/wasm-go/extensions/model-mapper/main.go @@ -42,7 +42,6 @@ type Config struct { prefixModelMapping []ModelMapping defaultModel string enableOnPathSuffix []string - modelToHeader string } func parseConfig(json gjson.Result, config *Config) error { @@ -50,10 +49,6 @@ func parseConfig(json gjson.Result, config *Config) error { if config.modelKey == "" { config.modelKey = "model" } - config.modelToHeader = json.Get("modelToHeader").String() - if config.modelToHeader == "" { - config.modelToHeader = "x-higress-llm-model" - } modelMapping := json.Get("modelMapping") if modelMapping.Exists() && !modelMapping.IsObject() { @@ -149,8 +144,6 @@ func onHttpRequestHeaders(ctx wrapper.HttpContext, config Config) types.Action { return types.ActionContinue } - // Disable re-route since the plugin may modify some headers related to the chosen route. - ctx.DisableReroute() // Prepare for body processing proxywasm.RemoveHttpRequestHeader("content-length") // 100MB buffer limit @@ -190,12 +183,6 @@ func onHttpRequestBody(ctx wrapper.HttpContext, config Config, body []byte) type } if newModel != "" && newModel != oldModel { - // if x-higress-llm-model header is set, and it is not the same as the new model, update it - // this is to support fallback and token rate limit - model, _ := proxywasm.GetHttpRequestHeader(config.modelToHeader) - if model != "" && model != newModel { - proxywasm.ReplaceHttpRequestHeader(config.modelToHeader, newModel) - } newBody, err := sjson.SetBytes(body, config.modelKey, newModel) if err != nil { log.Errorf("failed to update model: %v", err) diff --git a/plugins/wasm-go/extensions/model-mapper/main_test.go b/plugins/wasm-go/extensions/model-mapper/main_test.go index d8084a33d..7be9c7851 100644 --- a/plugins/wasm-go/extensions/model-mapper/main_test.go +++ b/plugins/wasm-go/extensions/model-mapper/main_test.go @@ -42,20 +42,6 @@ var ( }) return data }() - - customHeaderConfig = func() json.RawMessage { - data, _ := json.Marshal(map[string]interface{}{ - "modelKey": "model", - "modelToHeader": "x-custom-model-header", - "modelMapping": map[string]string{ - "gpt-3.5-turbo": "gpt-4", - }, - "enableOnPathSuffix": []string{ - "/v1/chat/completions", - }, - }) - return data - }() ) func TestParseConfig(t *testing.T) { @@ -109,21 +95,6 @@ func TestParseConfig(t *testing.T) { require.Contains(t, cfg.enableOnPathSuffix, "/v1/embeddings") }) - t.Run("custom modelToHeader", func(t *testing.T) { - var cfg Config - jsonData := []byte(`{ - "modelKey": "model", - "modelToHeader": "x-custom-model-header", - "modelMapping": { - "gpt-3.5-turbo": "gpt-4" - } - }`) - err := parseConfig(gjson.ParseBytes(jsonData), &cfg) - require.NoError(t, err) - - require.Equal(t, "model", cfg.modelKey) - }) - t.Run("modelMapping must be object", func(t *testing.T) { var cfg Config jsonData := []byte(`{ @@ -275,179 +246,5 @@ func TestOnHttpRequestBody_ModelMapping(t *testing.T) { require.NotNil(t, processed) require.Equal(t, "gpt-4-mini", gjson.GetBytes(processed, "request.model").String()) }) - - t.Run("update model header when model changes", func(t *testing.T) { - host, status := test.NewTestHost(basicConfig) - defer host.Reset() - require.Equal(t, types.OnPluginStartStatusOK, status) - - host.CallOnHttpRequestHeaders([][2]string{ - {":authority", "example.com"}, - {":path", "/v1/chat/completions"}, - {":method", "POST"}, - {"content-type", "application/json"}, - {"x-higress-llm-model", "gpt-3.5-turbo-fallback"}, - }) - - origBody := []byte(`{ - "model": "gpt-3.5-turbo", - "messages": [{"role": "user", "content": "hello"}] - }`) - action := host.CallOnHttpRequestBody(origBody) - require.Equal(t, types.ActionContinue, action) - - // verify x-higress-llm-model header was updated to the mapped target - newHeaders := host.GetRequestHeaders() - foundUpdatedHeader := false - for _, h := range newHeaders { - if strings.ToLower(h[0]) == "x-higress-llm-model" { - require.Equal(t, "gpt-4", h[1]) - foundUpdatedHeader = true - break - } - } - require.True(t, foundUpdatedHeader, "x-higress-llm-model header should be updated") - }) - - t.Run("skip model header update when header not set", func(t *testing.T) { - host, status := test.NewTestHost(basicConfig) - defer host.Reset() - require.Equal(t, types.OnPluginStartStatusOK, status) - - host.CallOnHttpRequestHeaders([][2]string{ - {":authority", "example.com"}, - {":path", "/v1/chat/completions"}, - {":method", "POST"}, - {"content-type", "application/json"}, - }) - - origBody := []byte(`{ - "model": "gpt-3.5-turbo", - "messages": [{"role": "user", "content": "hello"}] - }`) - action := host.CallOnHttpRequestBody(origBody) - require.Equal(t, types.ActionContinue, action) - - // verify x-higress-llm-model header was NOT added (should not exist) - newHeaders := host.GetRequestHeaders() - for _, h := range newHeaders { - require.NotEqual(t, strings.ToLower(h[0]), "x-higress-llm-model") - } - }) - - t.Run("skip model header update when header already matches new model", func(t *testing.T) { - host, status := test.NewTestHost(basicConfig) - defer host.Reset() - require.Equal(t, types.OnPluginStartStatusOK, status) - - host.CallOnHttpRequestHeaders([][2]string{ - {":authority", "example.com"}, - {":path", "/v1/chat/completions"}, - {":method", "POST"}, - {"content-type", "application/json"}, - {"x-higress-llm-model", "gpt-4"}, - }) - - origBody := []byte(`{ - "model": "gpt-3.5-turbo", - "messages": [{"role": "user", "content": "hello"}] - }`) - action := host.CallOnHttpRequestBody(origBody) - require.Equal(t, types.ActionContinue, action) - - // verify x-higress-llm-model header has the correct value - newHeaders := host.GetRequestHeaders() - for _, h := range newHeaders { - if strings.ToLower(h[0]) == "x-higress-llm-model" { - require.Equal(t, "gpt-4", h[1]) - break - } - } - }) - - t.Run("no model mapping keeps header unchanged", func(t *testing.T) { - host, status := test.NewTestHost(basicConfig) - defer host.Reset() - require.Equal(t, types.OnPluginStartStatusOK, status) - - host.CallOnHttpRequestHeaders([][2]string{ - {":authority", "example.com"}, - {":path", "/v1/chat/completions"}, - {":method", "POST"}, - {"content-type", "application/json"}, - {"x-higress-llm-model", "some-other-model"}, - }) - - origBody := []byte(`{ - "model": "unknown-model", - "messages": [{"role": "user", "content": "hello"}] - }`) - action := host.CallOnHttpRequestBody(origBody) - require.Equal(t, types.ActionContinue, action) - - // model should remain unchanged (no mapping) - processed := host.GetRequestBody() - require.NotNil(t, processed) - require.Equal(t, "unknown-model", gjson.GetBytes(processed, "model").String()) - }) - - t.Run("use custom modelToHeader config", func(t *testing.T) { - host, status := test.NewTestHost(customHeaderConfig) - defer host.Reset() - require.Equal(t, types.OnPluginStartStatusOK, status) - - host.CallOnHttpRequestHeaders([][2]string{ - {":authority", "example.com"}, - {":path", "/v1/chat/completions"}, - {":method", "POST"}, - {"content-type", "application/json"}, - {"x-custom-model-header", "original-model"}, - }) - - origBody := []byte(`{ - "model": "gpt-3.5-turbo", - "messages": [{"role": "user", "content": "hello"}] - }`) - action := host.CallOnHttpRequestBody(origBody) - require.Equal(t, types.ActionContinue, action) - - // verify custom header was updated to the mapped target - newHeaders := host.GetRequestHeaders() - foundUpdatedHeader := false - for _, h := range newHeaders { - if strings.ToLower(h[0]) == "x-custom-model-header" { - require.Equal(t, "gpt-4", h[1]) - foundUpdatedHeader = true - break - } - } - require.True(t, foundUpdatedHeader, "x-custom-model-header should be updated") - }) - - t.Run("use custom modelToHeader with empty header value", func(t *testing.T) { - host, status := test.NewTestHost(customHeaderConfig) - defer host.Reset() - require.Equal(t, types.OnPluginStartStatusOK, status) - - host.CallOnHttpRequestHeaders([][2]string{ - {":authority", "example.com"}, - {":path", "/v1/chat/completions"}, - {":method", "POST"}, - {"content-type", "application/json"}, - }) - - origBody := []byte(`{ - "model": "gpt-3.5-turbo", - "messages": [{"role": "user", "content": "hello"}] - }`) - action := host.CallOnHttpRequestBody(origBody) - require.Equal(t, types.ActionContinue, action) - - // verify custom header was NOT added when not present - newHeaders := host.GetRequestHeaders() - for _, h := range newHeaders { - require.NotEqual(t, strings.ToLower(h[0]), "x-custom-model-header") - } - }) }) }