Compare commits

...

3 Commits
v2.2.1 ... main

7 changed files with 1440 additions and 246 deletions

View File

@@ -11,6 +11,7 @@ import (
"errors"
"fmt"
"net/http"
"net/url"
"regexp"
"strings"
"time"
@@ -224,6 +225,34 @@ func (v *vertexProvider) getToken() (cached bool, err error) {
return false, err
}
func appendOrReplaceAPIKey(path, apiKey string) string {
if apiKey == "" {
return path
}
parsedPath, err := url.ParseRequestURI(path)
if err != nil {
// Fallback to simple append when path is not parseable.
if strings.Contains(path, "?") {
return path + "&key=" + apiKey
}
return path + "?key=" + apiKey
}
query := parsedPath.Query()
query.Set("key", apiKey)
parsedPath.RawQuery = query.Encode()
return parsedPath.RequestURI()
}
func (v *vertexProvider) getExpressAPIKey(ctx wrapper.HttpContext) string {
apiKey := v.config.GetApiTokenInUse(ctx)
if apiKey == "" {
apiKey = v.config.GetRandomToken()
}
return apiKey
}
func (v *vertexProvider) OnRequestBody(ctx wrapper.HttpContext, apiName ApiName, body []byte) (types.Action, error) {
if !v.config.isSupportedAPI(apiName) {
return types.ActionContinue, errUnsupportedApiName
@@ -234,8 +263,14 @@ func (v *vertexProvider) OnRequestBody(ctx wrapper.HttpContext, apiName ApiName,
// 注意:此检查必须在 IsOriginal() 之前,因为 Vertex Raw 模式通常与 original 协议一起使用
if apiName == ApiNameVertexRaw {
ctx.SetContext(contextVertexRawMarker, true)
// Express Mode 不需要 OAuth 认证
// Express Mode: 将 API Key 追加到 URL query 参数中
if v.isExpressMode() {
headers := util.GetRequestHeaders()
path := headers.Get(":path")
path = appendOrReplaceAPIKey(path, v.getExpressAPIKey(ctx))
util.OverwriteRequestPathHeader(headers, path)
headers.Del("Authorization")
util.ReplaceRequestHeaders(headers)
return types.ActionContinue, nil
}
// 标准模式需要获取 OAuth token
@@ -354,7 +389,7 @@ func (v *vertexProvider) onChatCompletionRequestBody(ctx wrapper.HttpContext, bo
}
if strings.HasPrefix(request.Model, "claude") {
ctx.SetContext(contextClaudeMarker, true)
path := v.getAhthropicRequestPath(ApiNameChatCompletion, request.Model, request.Stream)
path := v.getAhthropicRequestPath(ctx, ApiNameChatCompletion, request.Model, request.Stream)
util.OverwriteRequestPathHeader(headers, path)
claudeRequest := v.claude.buildClaudeTextGenRequest(request)
@@ -366,7 +401,7 @@ func (v *vertexProvider) onChatCompletionRequestBody(ctx wrapper.HttpContext, bo
}
return claudeBody, nil
} else {
path := v.getRequestPath(ApiNameChatCompletion, request.Model, request.Stream)
path := v.getRequestPath(ctx, ApiNameChatCompletion, request.Model, request.Stream)
util.OverwriteRequestPathHeader(headers, path)
vertexRequest, err := v.buildVertexChatRequest(request)
@@ -382,7 +417,7 @@ func (v *vertexProvider) onEmbeddingsRequestBody(ctx wrapper.HttpContext, body [
if err := v.config.parseRequestAndMapModel(ctx, request, body); err != nil {
return nil, err
}
path := v.getRequestPath(ApiNameEmbeddings, request.Model, false)
path := v.getRequestPath(ctx, ApiNameEmbeddings, request.Model, false)
util.OverwriteRequestPathHeader(headers, path)
vertexRequest := v.buildEmbeddingRequest(request)
@@ -395,7 +430,7 @@ func (v *vertexProvider) onImageGenerationRequestBody(ctx wrapper.HttpContext, b
return nil, err
}
// 图片生成不使用流式端点,需要完整响应
path := v.getRequestPath(ApiNameImageGeneration, request.Model, false)
path := v.getRequestPath(ctx, ApiNameImageGeneration, request.Model, false)
util.OverwriteRequestPathHeader(headers, path)
vertexRequest, err := v.buildVertexImageGenerationRequest(request)
@@ -442,7 +477,7 @@ func (v *vertexProvider) onImageEditRequestBody(ctx wrapper.HttpContext, body []
return nil, fmt.Errorf("missing prompt in request")
}
path := v.getRequestPath(ApiNameImageEdit, request.Model, false)
path := v.getRequestPath(ctx, ApiNameImageEdit, request.Model, false)
util.OverwriteRequestPathHeader(headers, path)
headers.Set("Content-Type", util.MimeTypeApplicationJson)
vertexRequest, err := v.buildVertexImageRequest(request.Prompt, request.Size, request.OutputFormat, imageURLs)
@@ -485,7 +520,7 @@ func (v *vertexProvider) onImageVariationRequestBody(ctx wrapper.HttpContext, bo
prompt = vertexImageVariationDefaultPrompt
}
path := v.getRequestPath(ApiNameImageVariation, request.Model, false)
path := v.getRequestPath(ctx, ApiNameImageVariation, request.Model, false)
util.OverwriteRequestPathHeader(headers, path)
headers.Set("Content-Type", util.MimeTypeApplicationJson)
vertexRequest, err := v.buildVertexImageRequest(prompt, request.Size, request.OutputFormat, imageURLs)
@@ -909,7 +944,7 @@ func (v *vertexProvider) appendResponse(responseBuilder *strings.Builder, respon
responseBuilder.WriteString(fmt.Sprintf("%s %s\n\n", streamDataItemKey, responseBody))
}
func (v *vertexProvider) getAhthropicRequestPath(apiName ApiName, modelId string, stream bool) string {
func (v *vertexProvider) getAhthropicRequestPath(ctx wrapper.HttpContext, apiName ApiName, modelId string, stream bool) string {
action := ""
if stream {
action = vertexAnthropicMessageStreamAction
@@ -920,22 +955,15 @@ func (v *vertexProvider) getAhthropicRequestPath(apiName ApiName, modelId string
if v.isExpressMode() {
// Express Mode: 简化路径 + API Key 参数
basePath := fmt.Sprintf(vertexExpressPathAnthropicTemplate, modelId, action)
apiKey := v.config.GetRandomToken()
// 如果 action 已经包含 ?,使用 & 拼接
var fullPath string
if strings.Contains(action, "?") {
fullPath = basePath + "&key=" + apiKey
} else {
fullPath = basePath + "?key=" + apiKey
}
return fullPath
apiKey := v.getExpressAPIKey(ctx)
return appendOrReplaceAPIKey(basePath, apiKey)
}
path := fmt.Sprintf(vertexPathAnthropicTemplate, v.config.vertexProjectId, v.config.vertexRegion, modelId, action)
return path
}
func (v *vertexProvider) getRequestPath(apiName ApiName, modelId string, stream bool) string {
func (v *vertexProvider) getRequestPath(ctx wrapper.HttpContext, apiName ApiName, modelId string, stream bool) string {
action := ""
switch apiName {
case ApiNameEmbeddings:
@@ -954,15 +982,8 @@ func (v *vertexProvider) getRequestPath(apiName ApiName, modelId string, stream
if v.isExpressMode() {
// Express Mode: 简化路径 + API Key 参数
basePath := fmt.Sprintf(vertexExpressPathTemplate, modelId, action)
apiKey := v.config.GetRandomToken()
// 如果 action 已经包含 ?(如 streamGenerateContent?alt=sse使用 & 拼接
var fullPath string
if strings.Contains(action, "?") {
fullPath = basePath + "&key=" + apiKey
} else {
fullPath = basePath + "?key=" + apiKey
}
return fullPath
apiKey := v.getExpressAPIKey(ctx)
return appendOrReplaceAPIKey(basePath, apiKey)
}
path := fmt.Sprintf(vertexPathTemplate, v.config.vertexProjectId, v.config.vertexRegion, modelId, action)

View File

@@ -8,6 +8,42 @@ import (
"github.com/stretchr/testify/require"
)
func TestAppendOrReplaceAPIKey(t *testing.T) {
t.Run("empty apiKey returns path unchanged", func(t *testing.T) {
path := "/v1/publishers/google/models/gemini:generateContent"
assert.Equal(t, path, appendOrReplaceAPIKey(path, ""))
})
t.Run("path without query appends ?key=", func(t *testing.T) {
result := appendOrReplaceAPIKey("/v1/models/gemini:generateContent", "my-key")
assert.Equal(t, "/v1/models/gemini:generateContent?key=my-key", result)
})
t.Run("path with existing query appends &key=", func(t *testing.T) {
result := appendOrReplaceAPIKey("/v1/models/gemini:streamGenerateContent?alt=sse", "my-key")
assert.Contains(t, result, "alt=sse")
assert.Contains(t, result, "key=my-key")
})
t.Run("existing key parameter is replaced", func(t *testing.T) {
result := appendOrReplaceAPIKey("/v1/models/gemini:generateContent?key=old-key&trace=1", "new-key")
assert.Contains(t, result, "key=new-key")
assert.NotContains(t, result, "old-key")
assert.Contains(t, result, "trace=1")
})
t.Run("unparseable path without query falls back to ?key= append", func(t *testing.T) {
// A bare string with no leading slash is not a valid RequestURI
result := appendOrReplaceAPIKey("not-a-valid-uri", "my-key")
assert.Equal(t, "not-a-valid-uri?key=my-key", result)
})
t.Run("unparseable path with query falls back to &key= append", func(t *testing.T) {
result := appendOrReplaceAPIKey("not-a-valid-uri?foo=bar", "my-key")
assert.Equal(t, "not-a-valid-uri?foo=bar&key=my-key", result)
})
}
func TestVertexProviderBuildChatRequestStructuredOutputMapping(t *testing.T) {
t.Run("json_object response format", func(t *testing.T) {
v := &vertexProvider{}

View File

@@ -3,7 +3,9 @@ package test
import (
"bytes"
"encoding/json"
"math/rand"
"mime/multipart"
"net/url"
"strings"
"testing"
@@ -37,6 +39,17 @@ var vertexExpressModeConfig = func() json.RawMessage {
return data
}()
// 测试配置Vertex Express Mode 配置(多 API Token
var vertexExpressModeMultiTokensConfig = func() json.RawMessage {
data, _ := json.Marshal(map[string]interface{}{
"provider": map[string]interface{}{
"type": "vertex",
"apiTokens": []string{"test-api-key-express-a", "test-api-key-express-b"},
},
})
return data
}()
// 测试配置Vertex Express Mode 配置(含模型映射)
var vertexExpressModeWithModelMappingConfig = func() json.RawMessage {
data, _ := json.Marshal(map[string]interface{}{
@@ -167,6 +180,18 @@ var vertexRawModeWithBasePathConfig = func() json.RawMessage {
return data
}()
// 测试配置Vertex Raw 模式配置Express Mode + 多 API Token
var vertexRawModeExpressMultiTokensConfig = func() json.RawMessage {
data, _ := json.Marshal(map[string]interface{}{
"provider": map[string]interface{}{
"type": "vertex",
"apiTokens": []string{"test-api-key-raw-a", "test-api-key-raw-b"},
"protocol": "original",
},
})
return data
}()
func RunVertexParseConfigTests(t *testing.T) {
test.RunGoTest(t, func(t *testing.T) {
// 测试 Vertex 标准模式配置解析
@@ -380,6 +405,149 @@ func RunVertexExpressModeOnHttpRequestBodyTests(t *testing.T) {
require.True(t, hasVertexLogs, "Should have vertex processing logs")
})
// 测试 Vertex Express Mode 请求体处理(多 token - Google 路径使用请求上下文中的 apiTokenInUse
t.Run("vertex express mode chat completion should reuse api token in context", func(t *testing.T) {
host, status := test.NewTestHost(vertexExpressModeMultiTokensConfig)
defer host.Reset()
require.Equal(t, types.OnPluginStartStatusOK, status)
tokens := []string{"test-api-key-express-a", "test-api-key-express-b"}
host.CallOnHttpRequestHeaders([][2]string{
{":authority", "example.com"},
{":path", "/v1/chat/completions"},
{":method", "POST"},
{"Content-Type", "application/json"},
})
// 从 debug log 中提取请求头阶段固定的 apiTokenInUse
var apiTokenInUse string
for _, debugLog := range host.GetDebugLogs() {
const prefix = "Use apiToken "
const suffix = " to send request"
start := strings.Index(debugLog, prefix)
if start == -1 {
continue
}
start += len(prefix)
end := strings.Index(debugLog[start:], suffix)
if end == -1 {
continue
}
apiTokenInUse = debugLog[start : start+end]
break
}
require.Contains(t, tokens, apiTokenInUse, "apiTokenInUse should be selected from configured tokens")
// 强制设置随机种子让旧实现OnRequestBody 再次随机)必然选到不同 token
targetIndex := 0
if apiTokenInUse == tokens[0] {
targetIndex = 1
}
seed := int64(1)
for {
if rand.New(rand.NewSource(seed)).Intn(len(tokens)) == targetIndex {
break
}
seed++
}
rand.Seed(seed)
requestBody := `{"model":"gemini-2.5-flash","messages":[{"role":"user","content":"token consistency test"}]}`
action := host.CallOnHttpRequestBody([]byte(requestBody))
require.Equal(t, types.ActionContinue, action)
requestHeaders := host.GetRequestHeaders()
pathHeader := ""
for _, header := range requestHeaders {
if header[0] == ":path" {
pathHeader = header[1]
break
}
}
require.NotEmpty(t, pathHeader, "Path header should not be empty")
require.Contains(t, pathHeader, "/v1/publishers/google/models/", "Path should use Google publisher endpoint")
parsedPath, err := url.ParseRequestURI(pathHeader)
require.NoError(t, err)
query := parsedPath.Query()
require.Len(t, query["key"], 1, "Path should contain exactly one key query parameter")
require.Equal(t, apiTokenInUse, query.Get("key"),
"Path key should use apiTokenInUse selected in request headers phase")
})
// 测试 Vertex Express Mode 请求体处理(多 token - Anthropic 路径使用请求上下文中的 apiTokenInUse
t.Run("vertex express mode anthropic request should reuse api token in context", func(t *testing.T) {
host, status := test.NewTestHost(vertexExpressModeMultiTokensConfig)
defer host.Reset()
require.Equal(t, types.OnPluginStartStatusOK, status)
tokens := []string{"test-api-key-express-a", "test-api-key-express-b"}
host.CallOnHttpRequestHeaders([][2]string{
{":authority", "example.com"},
{":path", "/v1/chat/completions"},
{":method", "POST"},
{"Content-Type", "application/json"},
})
// 从 debug log 中提取请求头阶段固定的 apiTokenInUse
var apiTokenInUse string
for _, debugLog := range host.GetDebugLogs() {
const prefix = "Use apiToken "
const suffix = " to send request"
start := strings.Index(debugLog, prefix)
if start == -1 {
continue
}
start += len(prefix)
end := strings.Index(debugLog[start:], suffix)
if end == -1 {
continue
}
apiTokenInUse = debugLog[start : start+end]
break
}
require.Contains(t, tokens, apiTokenInUse, "apiTokenInUse should be selected from configured tokens")
// 强制设置随机种子让旧实现OnRequestBody 再次随机)必然选到不同 token
targetIndex := 0
if apiTokenInUse == tokens[0] {
targetIndex = 1
}
seed := int64(1)
for {
if rand.New(rand.NewSource(seed)).Intn(len(tokens)) == targetIndex {
break
}
seed++
}
rand.Seed(seed)
requestBody := `{"model":"claude-sonnet-4@20250514","messages":[{"role":"user","content":"hello anthropic"}]}`
action := host.CallOnHttpRequestBody([]byte(requestBody))
require.Equal(t, types.ActionContinue, action)
requestHeaders := host.GetRequestHeaders()
pathHeader := ""
for _, header := range requestHeaders {
if header[0] == ":path" {
pathHeader = header[1]
break
}
}
require.NotEmpty(t, pathHeader, "Path header should not be empty")
require.Contains(t, pathHeader, "/v1/publishers/anthropic/models/claude-sonnet-4@20250514:rawPredict",
"Path should use Anthropic publisher endpoint")
parsedPath, err := url.ParseRequestURI(pathHeader)
require.NoError(t, err)
query := parsedPath.Query()
require.Len(t, query["key"], 1, "Path should contain exactly one key query parameter")
require.Equal(t, apiTokenInUse, query.Get("key"),
"Path key should use apiTokenInUse selected in request headers phase")
})
// 测试 Vertex Express Mode structured outputs: json_schema 映射
t.Run("vertex express mode structured outputs json_schema request body mapping", func(t *testing.T) {
host, status := test.NewTestHost(vertexExpressModeConfig)
@@ -2202,7 +2370,7 @@ func RunVertexRawModeOnHttpRequestHeadersTests(t *testing.T) {
func RunVertexRawModeOnHttpRequestBodyTests(t *testing.T) {
test.RunTest(t, func(t *testing.T) {
// 测试 Vertex Raw 模式请求体处理Express Mode - 透传请求体)
// 测试 Vertex Raw 模式请求体处理Express Mode - 透传请求体 + API Key 认证
t.Run("vertex raw mode express - request body passthrough", func(t *testing.T) {
host, status := test.NewTestHost(vertexRawModeExpressConfig)
defer host.Reset()
@@ -2214,6 +2382,7 @@ func RunVertexRawModeOnHttpRequestBodyTests(t *testing.T) {
{":path", "/v1/projects/test-project/locations/us-central1/publishers/google/models/gemini-2.0-flash:generateContent"},
{":method", "POST"},
{"Content-Type", "application/json"},
{"Authorization", "Bearer some-token"},
})
// 设置原生 Vertex 格式的请求体
@@ -2229,6 +2398,22 @@ func RunVertexRawModeOnHttpRequestBodyTests(t *testing.T) {
// 请求体应该保持原样
require.Equal(t, requestBody, string(processedBody), "Request body should be passed through unchanged")
// 验证 API Key 被追加到 URL path 中
requestHeaders := host.GetRequestHeaders()
var pathHeader string
for _, header := range requestHeaders {
if header[0] == ":path" {
pathHeader = header[1]
break
}
}
require.Contains(t, pathHeader, "?key=test-api-key-for-raw-mode",
"API key should be appended to path as query parameter")
// 验证 Authorization header 被删除
require.False(t, test.HasHeaderWithValue(requestHeaders, "Authorization", "Bearer some-token"),
"Authorization header should be removed in Express Mode")
})
// 测试 Vertex Raw 模式请求体处理(标准模式 - 需要 OAuth token
@@ -2304,13 +2489,13 @@ func RunVertexRawModeOnHttpRequestBodyTests(t *testing.T) {
require.NotContains(t, pathHeader, "/vertex-proxy", "Path should have basePath prefix removed")
})
// 测试 Vertex Raw 模式请求体处理(流式请求)
// 测试 Vertex Raw 模式请求体处理(流式请求 - path 已含 ? 时用 & 拼接 API Key
t.Run("vertex raw mode express - streaming request body passthrough", func(t *testing.T) {
host, status := test.NewTestHost(vertexRawModeExpressConfig)
defer host.Reset()
require.Equal(t, types.OnPluginStartStatusOK, status)
// 先设置请求头(流式端点)
// 先设置请求头(流式端点path 已含 ?alt=sse
host.CallOnHttpRequestHeaders([][2]string{
{":authority", "example.com"},
{":path", "/v1/projects/test-project/locations/us-central1/publishers/google/models/gemini-2.0-flash:streamGenerateContent?alt=sse"},
@@ -2328,6 +2513,194 @@ func RunVertexRawModeOnHttpRequestBodyTests(t *testing.T) {
processedBody := host.GetRequestBody()
require.NotNil(t, processedBody)
require.Equal(t, requestBody, string(processedBody), "Request body should be passed through unchanged")
// 验证 API Key 使用 & 拼接(因为 path 已含 ?alt=sse
requestHeaders := host.GetRequestHeaders()
var pathHeader string
for _, header := range requestHeaders {
if header[0] == ":path" {
pathHeader = header[1]
break
}
}
require.Contains(t, pathHeader, "?alt=sse&key=test-api-key-for-raw-mode",
"API key should be appended with & when path already contains ?")
})
// 测试 Vertex Raw 模式请求体处理Express Mode + Anthropic 模型路径)
t.Run("vertex raw mode express - anthropic model request body with api key", func(t *testing.T) {
host, status := test.NewTestHost(vertexRawModeExpressConfig)
defer host.Reset()
require.Equal(t, types.OnPluginStartStatusOK, status)
// 使用 Anthropic 模型的原生 Vertex AI REST API 路径
host.CallOnHttpRequestHeaders([][2]string{
{":authority", "example.com"},
{":path", "/v1/projects/test-project/locations/us-east5/publishers/anthropic/models/claude-sonnet-4@20250514:rawPredict"},
{":method", "POST"},
{"Content-Type", "application/json"},
})
requestBody := `{"anthropic_version":"vertex-2023-10-16","messages":[{"role":"user","content":"Hello"}],"max_tokens":1024}`
action := host.CallOnHttpRequestBody([]byte(requestBody))
require.Equal(t, types.ActionContinue, action)
// 验证请求体被透传
processedBody := host.GetRequestBody()
require.Equal(t, requestBody, string(processedBody), "Request body should be passed through unchanged")
// 验证 API Key 被追加到 path
requestHeaders := host.GetRequestHeaders()
var pathHeader string
for _, header := range requestHeaders {
if header[0] == ":path" {
pathHeader = header[1]
break
}
}
require.Contains(t, pathHeader, "?key=test-api-key-for-raw-mode",
"API key should be appended to anthropic model path")
})
// 测试 Vertex Raw 模式请求体处理Express Mode + basePath - API Key 正确追加)
t.Run("vertex raw mode with basePath express - request body with api key", func(t *testing.T) {
host, status := test.NewTestHost(vertexRawModeWithBasePathConfig)
defer host.Reset()
require.Equal(t, types.OnPluginStartStatusOK, status)
// 带 basePath 前缀的请求
host.CallOnHttpRequestHeaders([][2]string{
{":authority", "example.com"},
{":path", "/vertex-proxy/v1/projects/test-project/locations/us-central1/publishers/google/models/gemini-2.0-flash:generateContent"},
{":method", "POST"},
{"Content-Type", "application/json"},
})
requestBody := `{"contents":[{"role":"user","parts":[{"text":"Hello"}]}]}`
action := host.CallOnHttpRequestBody([]byte(requestBody))
require.Equal(t, types.ActionContinue, action)
// 验证路径basePath 被移除 + API Key 被追加
requestHeaders := host.GetRequestHeaders()
var pathHeader string
for _, header := range requestHeaders {
if header[0] == ":path" {
pathHeader = header[1]
break
}
}
require.NotContains(t, pathHeader, "/vertex-proxy",
"Path should have basePath prefix removed")
require.Contains(t, pathHeader, "?key=test-api-key-for-raw-mode",
"API key should be appended after basePath removal")
})
// 测试 Vertex Raw 模式请求体处理Express Mode + 多 token使用请求上下文中的 apiTokenInUse
t.Run("vertex raw mode express - should reuse api token in context for query key", func(t *testing.T) {
host, status := test.NewTestHost(vertexRawModeExpressMultiTokensConfig)
defer host.Reset()
require.Equal(t, types.OnPluginStartStatusOK, status)
// 选择一个保证前两次 Intn(2) 结果不同的种子:
// 第一次用于 SetApiTokenInUse第二次仅在旧实现中用于 OnRequestBody.GetRandomToken。
seed := int64(1)
for {
r := rand.New(rand.NewSource(seed))
if r.Intn(2) != r.Intn(2) {
break
}
seed++
}
rand.Seed(seed)
host.CallOnHttpRequestHeaders([][2]string{
{":authority", "example.com"},
{":path", "/v1/projects/test-project/locations/us-central1/publishers/google/models/gemini-2.0-flash:generateContent"},
{":method", "POST"},
{"Content-Type", "application/json"},
})
requestBody := `{"contents":[{"role":"user","parts":[{"text":"Hello"}]}]}`
action := host.CallOnHttpRequestBody([]byte(requestBody))
require.Equal(t, types.ActionContinue, action)
requestHeaders := host.GetRequestHeaders()
var pathHeader string
for _, header := range requestHeaders {
if header[0] == ":path" {
pathHeader = header[1]
break
}
}
require.NotEmpty(t, pathHeader, "Path header should not be empty")
parsedPath, err := url.ParseRequestURI(pathHeader)
require.NoError(t, err)
query := parsedPath.Query()
require.Len(t, query["key"], 1, "Path should contain exactly one key query parameter")
keyInPath := query.Get("key")
require.NotEmpty(t, keyInPath, "Path should contain key query parameter")
// 从 debug log 中提取本次请求固定的 apiTokenInUse
var apiTokenInUse string
for _, debugLog := range host.GetDebugLogs() {
const prefix = "Use apiToken "
const suffix = " to send request"
start := strings.Index(debugLog, prefix)
if start == -1 {
continue
}
start += len(prefix)
end := strings.Index(debugLog[start:], suffix)
if end == -1 {
continue
}
apiTokenInUse = debugLog[start : start+end]
break
}
require.NotEmpty(t, apiTokenInUse, "apiTokenInUse should be logged")
require.Equal(t, apiTokenInUse, keyInPath,
"Query key must use apiTokenInUse from request context")
})
// 测试 Vertex Raw 模式请求体处理Express Mode + 已有 key 参数时应覆盖而不是追加重复)
t.Run("vertex raw mode express - should replace existing key query parameter", func(t *testing.T) {
host, status := test.NewTestHost(vertexRawModeExpressConfig)
defer host.Reset()
require.Equal(t, types.OnPluginStartStatusOK, status)
host.CallOnHttpRequestHeaders([][2]string{
{":authority", "example.com"},
{":path", "/v1/projects/test-project/locations/us-central1/publishers/google/models/gemini-2.0-flash:streamGenerateContent?alt=sse&key=client-key&trace=1"},
{":method", "POST"},
{"Content-Type", "application/json"},
})
requestBody := `{"contents":[{"role":"user","parts":[{"text":"Hello"}]}]}`
action := host.CallOnHttpRequestBody([]byte(requestBody))
require.Equal(t, types.ActionContinue, action)
requestHeaders := host.GetRequestHeaders()
var pathHeader string
for _, header := range requestHeaders {
if header[0] == ":path" {
pathHeader = header[1]
break
}
}
require.NotEmpty(t, pathHeader, "Path header should not be empty")
parsedPath, err := url.ParseRequestURI(pathHeader)
require.NoError(t, err)
query := parsedPath.Query()
require.Len(t, query["key"], 1, "Path should contain exactly one key query parameter")
require.Equal(t, "test-api-key-for-raw-mode", query.Get("key"),
"Existing key query parameter should be replaced by configured API key")
require.Equal(t, "sse", query.Get("alt"), "Existing query parameter alt should be preserved")
require.Equal(t, "1", query.Get("trace"), "Existing query parameter trace should be preserved")
})
})
}

View File

@@ -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)

View File

@@ -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")
}
})
})
}

View File

@@ -0,0 +1,489 @@
# Higress
## 📋 Release Overview
This release includes **65** updates, covering feature enhancements, bug fixes, and performance optimizations.
### Distribution of Updates
- **New Features**: 29
- **Bug Fixes**: 26
- **Refactoring & Optimizations**: 3
- **Documentation Updates**: 7
---
## 📝 Full Changelog
### 🚀 New Features (Features)
- **Related PR**: [#3692](https://github.com/alibaba/higress/pull/3692) \
**Contributor**: @EndlessSeeker \
**Change Log**: This PR updates the Higress project version number to 2.2.1, modifying version fields in `Makefile.core.mk`, the Envoy submodule commit hash, and `Chart.yaml` and `Chart.lock` files under `helm/core` and `helm/higress`, thereby synchronizing dependency versions with the application version identifier. \
**Feature Value**: Provides users with an official release package for version 2.2.1, ensuring correct component and Envoy image versions are pulled during Helm Chart deployment—enhancing version consistency and traceability while reducing deployment failures caused by version mismatches.
- **Related PR**: [#3689](https://github.com/alibaba/higress/pull/3689) \
**Contributor**: @rinfx \
**Change Log**: Introduces a new `modelToHeader` configuration option for the `model-mapper` plugin, enabling users to customize the HTTP request header name into which the mapped model is written. The default value is `x-higress-llm-model`. Additionally, refactors the header update logic to support dynamic configuration and backward compatibility. \
**Feature Value**: Allows users to flexibly specify the request header field name used to propagate LLM model identifiers—meeting diverse backend service integration requirements. Prevents hard-codinginduced compatibility issues and enhances the plugins adaptability and governance flexibility in multi-cloud and hybrid deployment scenarios.
- **Related PR**: [#3686](https://github.com/alibaba/higress/pull/3686) \
**Contributor**: @rinfx \
**Change Log**: Adds a new `providerBasePath` configuration option, allowing definition of a base path prefix in `ProviderConfig`. This prefix is automatically injected into all provider request paths during path rewriting. Also optimizes `providerDomain` handling logic to improve flexibility and reliability when combining domains and paths. \
**Feature Value**: Enables unified API path prefix management via `providerBasePath`, facilitating gateway-level route aggregation, multi-tenancy isolation, and reverse proxy path rewriting. Significantly enhances the AI proxy plugins adaptability to complex deployment scenarios such as nested routing and SaaS multi-instance deployments.
- **Related PR**: [#3651](https://github.com/alibaba/higress/pull/3651) \
**Contributor**: @wydream \
**Change Log**: Refactors multipart image request handling logic for the Azure Provider, fixing JSON model mapping errors and inconsistent model mapping in domain-only scenarios. Optimizes memory usage and eliminates redundant reads for large images or high-concurrency workloads, and adds comprehensive test coverage. \
**Feature Value**: Improves stability and performance of Azure image editing/variation APIs, ensuring correct parsing of multipart requests during large image uploads and high-concurrency scenarios—preventing request interruptions due to model mapping failures and increasing user call success rates and response efficiency.
- **Related PR**: [#3649](https://github.com/alibaba/higress/pull/3649) \
**Contributor**: @wydream \
**Change Log**: Implements mapping from OpenAI `response_format` to Vertex `generationConfig` for the Vertex Provider in `ai-proxy`, with focused support for structured output in `gemini-2.5+`. For `gemini-2.0-*`, adopts a safe-ignore strategy and adds extensive test cases validating structured output logic. \
**Feature Value**: Enables stable use of OpenAI-standard JSON Schema response formats on Vertex backends (especially `gemini-2.5+`), improving model output controllability and downstream system integration efficiency. Ensures compatibility with legacy models for seamless service upgrades and reduces migration costs.
- **Related PR**: [#3642](https://github.com/alibaba/higress/pull/3642) \
**Contributor**: @JianweiWang \
**Change Log**: Replaces the original plain-text `denyMessage` in the AI Security Guard plugin with a structured `DenyResponseBody`, introducing a response schema containing `blockedDetails`, `requestId`, and `guardCode`. Adds JSON serialization support and corresponding construction/parsing helper functions within the `config` package. \
**Feature Value**: Delivers richer, standardized denial-response metadata—enabling clients to precisely identify interception reasons, trace request chains, and integrate with risk control systems. Significantly improves troubleshooting efficiency and collaborative security incident analysis capabilities.
- **Related PR**: [#3638](https://github.com/alibaba/higress/pull/3638) \
**Contributor**: @rinfx \
**Change Log**: Adds a universal `providerDomain` configuration field and `resolveDomain` DNS resolution logic to the `ai-proxy` plugin, supporting custom domain configuration for Gemini and Claude providers. Integrates this capability into `CreateProvider` and `TransformRequestHeaders`, and supplements full unit test coverage. \
**Feature Value**: Allows users to flexibly connect Gemini and Claude services across different network environments via custom domains—improving deployment flexibility and network adaptability. Particularly beneficial for enterprise intranets, proxy relays, or compliance-driven domain governance scenarios—reducing service invocation failure rates.
- **Related PR**: [#3632](https://github.com/alibaba/higress/pull/3632) \
**Contributor**: @lexburner \
**Change Log**: Introduces a GitHub Actions workflow that automatically builds and pushes the `plugin-server` Docker image when an `higress` `v*.*.*` tag is released. Supports specifying the `plugin-server` branch/tag/commit via `workflow_dispatch`, enhancing automation for plugin service deployment. \
**Feature Value**: Eliminates manual `plugin-server` image building and publishing—significantly simplifying version synchronization and deployment processes across the Higress plugin ecosystem. Enhances delivery reliability and efficiency of plugin services while lowering operational overhead.
- **Related PR**: [#3625](https://github.com/alibaba/higress/pull/3625) \
**Contributor**: @johnlanni \
**Change Log**: Adds a new `promoteThinkingOnEmpty` configuration option: when a model response contains only `reasoning_content` and no `text`, it automatically promotes `reasoning_content` to `text`. Also introduces the `hiclawMode` shortcut toggle, simultaneously enabling `mergeConsecutiveMessages` and `promoteThinkingOnEmpty`, supporting HiClaw multi-agent collaboration scenarios—including both streaming (SSE) and non-streaming response paths. \
**Feature Value**: Significantly improves response completeness and downstream compatibility of AI proxies in complex reasoning-chain scenarios—avoiding client exceptions caused by empty responses. `hiclawMode` simplifies multi-agent coordination configuration, lowers user integration barriers, and enhances robustness and usability in real-world business scenarios.
- **Related PR**: [#3624](https://github.com/alibaba/higress/pull/3624) \
**Contributor**: @rinfx \
**Change Log**: Increases the default `value_length_limit` in the `ai-statistics` plugin from 4000 to 32000 and writes token usage to `AILog` immediately upon parsing it during streaming—rather than waiting until stream completion—enhancing large-field support and observability for streaming responses. \
**Feature Value**: Enables more complete logging of long attribute values and real-time token consumption when using coding tools like Codex—improving accuracy of AI invocation behavior analytics. Particularly mitigates token-usage loss caused by premature client disconnections in streaming scenarios—enhancing production monitoring reliability.
- **Related PR**: [#3620](https://github.com/alibaba/higress/pull/3620) \
**Contributor**: @wydream \
**Change Log**: Adds path recognition and routing support for OpenAI speech transcription (`/v1/audio/transcriptions`), translation (`/v1/audio/translations`), real-time communication (`/v1/realtime`), and Qwen-compatible mode Responses API (`/api/v2/apps/protocols/compatible-mode/v1/responses`). Extends provider mapping relationships and test coverage. \
**Feature Value**: Enables the `ai-proxy` plugin to fully support OpenAI speech and real-time API standards, as well as the Bailian Qwen compatibility protocol—allowing users to seamlessly invoke advanced capabilities like speech processing and real-time streaming interaction. Improves multimodal AI service integration efficiency and protocol compatibility.
- **Related PR**: [#3609](https://github.com/alibaba/higress/pull/3609) \
**Contributor**: @wydream \
**Change Log**: Adds configurable Prompt Cache retention policies for the Amazon Bedrock Provider—supporting both request-level dynamic overrides and provider-level default fallbacks. Unifies and corrects the `cached_tokens` measurement metric and integrates native Bedrock usage fields like `cacheReadInputTokens`. \
**Feature Value**: Empowers users to flexibly manage Prompt cache lifecycles—improving cache hit rates and cost-effectiveness. Default configuration capability lowers API invocation complexity and improves integration usability. Accurate usage metrics enable granular cost accounting and consumption analytics.
- **Related PR**: [#3598](https://github.com/alibaba/higress/pull/3598) \
**Contributor**: @johnlanni \
**Change Log**: Adds a new `mergeConsecutiveMessages` configuration option. During AI proxy request preprocessing, it automatically merges consecutive messages of the same role (e.g., multiple `user` messages) by traversing and reconstructing the `messages` array—ensuring compatibility with strict alternating-message requirements of non-OpenAI models such as GLM, Kimi, and Qwen. \
**Feature Value**: Enables seamless adaptation of the `ai-proxy` plugin to mainstream domestic and local LLM services—preventing API rejection errors caused by message format noncompliance and significantly improving request success rates and user experience consistency across multi-model scenarios.
- **Related PR**: [#3585](https://github.com/alibaba/higress/pull/3585) \
**Contributor**: @CH3CHO \
**Change Log**: Adds `/responses` to the default path suffix list in both the `model-router` and `model-mapper` plugins—natively enabling `/v1/responses` interface invocations without additional configuration required for routing or mapping response-related requests. \
**Feature Value**: Allows users to directly invoke model service response functionality via the `/v1/responses` path—improving API consistency and usability. Reduces customization overhead and strengthens the model gateways out-of-the-box support for emerging OpenAI-compatible interfaces.
- **Related PR**: [#3570](https://github.com/alibaba/higress/pull/3570) \
**Contributor**: @CH3CHO \
**Change Log**: Upgrades the Console component to v2.2.1 and synchronously releases the main Higress version v2.2.1—updating the `VERSION` file, `appVersion` in `Chart.yaml`, and dependency versions and digests in `Chart.lock` to ensure the correct Console subchart version is pulled during Helm deployment. \
**Feature Value**: Delivers the latest Console features and UX enhancements—improving management interface stability and compatibility. Semantic version synchronization strengthens cluster deployment consistency, reduces operational risks from version mismatches, and simplifies upgrade procedures.
- **Related PR**: [#3563](https://github.com/alibaba/higress/pull/3563) \
**Contributor**: @wydream \
**Change Log**: Adds OpenAI Prompt Cache parameter support to the Bedrock Provider—implementing conversion of request-side `prompt_cache_retention`/`prompt_cache_key` to Bedrocks `cachePoint`, and mapping response-side `cacheRead`/`cacheWrite` tokens to OpenAIs `cached_tokens` field in `usage`. \
**Feature Value**: Enables seamless enjoyment of OpenAI Prompt Cache functionality when using Bedrock backends—reducing repeated prompt inference overhead, improving response speed, and saving costs—while delivering standard OpenAI cache-usage metrics for monitoring and billing.
- **Related PR**: [#3550](https://github.com/alibaba/higress/pull/3550) \
**Contributor**: @icylord \
**Change Log**: Adds configurable `imagePullPolicy` support for the `gateway`, `plugin server`, and `controller` components in the Helm Chart—achieving flexible image pull strategy control via template conditionals and new fields in `values.yaml`, enhancing deployment flexibility. \
**Feature Value**: Enables users to define image pull strategies (`Always`/`IfNotPresent`/`Never`) per environment (e.g., dev/staging/prod)—avoiding service disruptions due to image caching issues and improving deployment reliability and operational controllability.
- **Related PR**: [#3536](https://github.com/alibaba/higress/pull/3536) \
**Contributor**: @wydream \
**Change Log**: Adds support for OpenAI image editing (`/v1/images/edits`) and variation generation (`/v1/images/variations`) APIs in the Vertex Provider of `ai-proxy`, implementing multipart/form-data request parsing and transformation, adding JSON `image_url` compatibility logic, and introducing `multipart_helper.go` for binary image upload handling. \
**Feature Value**: Allows users to directly call Vertex AI image editing and variation features via standard OpenAI SDKs (Python/Node)—without modifying client code—enhancing seamless cross-cloud AI service integration and development efficiency.
- **Related PR**: [#3523](https://github.com/alibaba/higress/pull/3523) \
**Contributor**: @johnlanni \
**Change Log**: Adds tool-call parsing capability for Claude/Anthropic streaming responses in the `ai-statistics` plugin—supporting event-driven format: identifying `tool_use` blocks, accumulating JSON parameter fragments, and fully assembling tool call information. Extends the `StreamingParser` struct to track content-block states. \
**Feature Value**: Enables accurate statistics and analysis of streaming tool calls when using Claude models—boosting AI application observability and debugging efficiency. Provides critical support for unified multi-model monitoring and enhances platform compatibility with the Anthropic ecosystem.
- **Related PR**: [#3521](https://github.com/alibaba/higress/pull/3521) \
**Contributor**: @johnlanni \
**Change Log**: Refactors the `global.hub` parameter into a foundational image registry configuration shared across Higress deployments and Wasm plugins—and introduces an independent `pluginNamespace` namespace so plugin image paths can be distinguished from core components. Simultaneously unifies image reference logic across multiple Helm templates. \
**Feature Value**: Empowers users to more flexibly manage image sources for different components (e.g., gateway, controller, plugin, Redis)—supporting distinct repositories or paths for plugins versus core components. Improves multi-environment deployment consistency and private customization capabilities—reducing image-pull failure risks.
- **Related PR**: [#3518](https://github.com/alibaba/higress/pull/3518) \
**Contributor**: @johnlanni \
**Change Log**: Adds logic in the Claude-to-OpenAI request transformation process to parse and strip the dynamically changing `cch` field from system messages—ensuring `x-anthropic-billing-header` remains cacheable. Modifies core transformation code and adds comprehensive unit tests covering this behavior. \
**Feature Value**: Solves Prompt cache invalidation caused by dynamic `cch` fields—significantly improving AI proxy response speed and service stability, lowering redundant request overhead, and enhancing user interaction experience and CLI tool performance.
- **Related PR**: [#3512](https://github.com/alibaba/higress/pull/3512) \
**Contributor**: @johnlanni \
**Change Log**: Introduces a lightweight mode configuration option `use_default_response_attributes`, skipping buffering of large request/response bodies (e.g., `messages`, `answer`, `reasoning`) to dramatically reduce memory footprint—suitable for high-concurrency AI observability scenarios in production. \
**Feature Value**: Helps users balance AI observability and resource overhead in production—avoiding OOM risks from full-message-body buffering and improving service stability and throughput. Especially beneficial for long conversations and streaming-response scenarios.
- **Related PR**: [#3511](https://github.com/alibaba/higress/pull/3511) \
**Contributor**: @johnlanni \
**Change Log**: Adds built-in `system` field support to the `ai-statistics` plugin—parsing the top-level `system` field in Claude `/v1/messages` API responses, extending structured collection capability for Claude system prompts—implemented via defining the `BuiltinSystemKey` constant in `main.go`. \
**Feature Value**: Enables accurate statistics and analysis of system prompt content in Claude model invocations—improving AI call observability and compliance auditing capabilities. Supports finer-grained evaluation of prompt engineering effectiveness and implementation of security policies.
- **Related PR**: [#3499](https://github.com/alibaba/higress/pull/3499) \
**Contributor**: @johnlanni \
**Change Log**: Introduces consumer affinity for OpenAI stateful APIs (e.g., `Responses`, `Files`, `Batches`)—parsing the `x-mse-consumer` request header and consistently selecting the same API token using the FNV-1a hash algorithm—ensuring session stickiness and state continuity across requests. \
**Feature Value**: Solves 404 errors in stateful APIs caused by inconsistent routing under multi-token configurations—significantly enhancing stability and reliability in fine-tuning and response-chaining scenarios. Users receive correct responses without needing to perceive underlying load-distribution logic.
- **Related PR**: [#3489](https://github.com/alibaba/higress/pull/3489) \
**Contributor**: @johnlanni \
**Change Log**: Adds support for z.ai model services—including multilingual brand name display (Chinese “智谱”, English “z.ai”) and an auto-region detection script that determines user region based on system timezone—automatically configuring the `api.z.ai` domain and code plan mode options. \
**Feature Value**: Improves out-of-the-box experience for the z.ai service in the Higress AI Gateway—lowering configuration barriers for Chinese and international users. Automatic domain adaptation prevents manual misconfiguration, enhancing deployment reliability and localization friendliness—accelerating AI capability integration.
- **Related PR**: [#3488](https://github.com/alibaba/higress/pull/3488) \
**Contributor**: @johnlanni \
**Change Log**: Adds configurable domain support (China/international dual endpoints), code planning mode routing switching, and thinking mode support for the ZhipuAI provider—extending API request path and authentication adaptation capabilities—to increase flexibility in multi-regional deployments and specialized code-scenario model invocations. \
**Feature Value**: Enables users to flexibly switch ZhipuAI service endpoints per deployment region. Enabling code planning mode delivers superior programming-assistance responses; thinking mode further improves complex reasoning-task outcomes—enhancing AI proxy practicality and adaptability in development scenarios.
- **Related PR**: [#3482](https://github.com/alibaba/higress/pull/3482) \
**Contributor**: @johnlanni \
**Change Log**: Optimizes the OSS skill sync workflow—packing each skill directory into an individual ZIP file (e.g., `my-skill.zip`) and uploading to `oss://higress-ai/skills/`, while maintaining backward compatibility with the AI Gateway installation script. \
**Feature Value**: Enables on-demand download and deployment of specific skills—increasing skill distribution flexibility and reuse efficiency. Avoids full skill-package pulls—reducing bandwidth consumption and deployment time—and enhances edge-scenario adaptability.
- **Related PR**: [#3481](https://github.com/alibaba/higress/pull/3481) \
**Contributor**: @johnlanni \
**Change Log**: Adds a GitHub Action workflow listening for changes in the `.claude/skills` directory on the `.main` branch—automatically triggering sync to OSS object storage for real-time, automated cloud backup and distribution of skill files. \
**Feature Value**: Eliminates manual skill-file uploads—improving developer collaboration efficiency. Ensures skill version consistency and high availability—facilitating team sharing and rapid deployment—while lowering operational costs and human-error risk.
- **Related PR**: [#3479](https://github.com/alibaba/higress/pull/3479) \
**Contributor**: @johnlanni \
**Change Log**: Adds compatibility logic for non-OpenAI AI providers—automatically converting unsupported `'developer'` roles to `'system'` roles in chat completion requests via modifications to `provider.go` to unify role mapping adaptation. \
**Feature Value**: Enhances cross-platform compatibility of the AI proxy plugin—enabling developers to use Claude, Anthropic, and other vendor APIs without manually modifying requests—lowering integration barriers and avoiding runtime errors.
### 🐛 Bug Fixes (Bug Fixes)
- **Related PR**: [#3667](https://github.com/alibaba/higress/pull/3667) \
**Contributor**: @wydream \
**Change Log**: Fixes incorrect passthrough of non-standard fields `thinking` and `reasoning_max_tokens` in Claude-to-OpenAI protocol conversion—retaining only the OpenAI-compliant `reasoning_effort` field—to prevent HTTP 400 errors from Azure and other providers. \
**Feature Value**: Improves `ai-proxy` compatibility and stability with Azure and other standard OpenAI-compatible providers—ensuring successful user requests when invoking Azure via Anthropic protocols and preventing service unavailability due to invalid fields.
- **Related PR**: [#3652](https://github.com/alibaba/higress/pull/3652) \
**Contributor**: @CH3CHO \
**Change Log**: Fixes a regex matching error in the template processor when mixing default and non-default namespaces—strictly restricting `/` and `}` characters in `type`/`name`/`namespace`, permitting `/` only in `key` while forbidding `}`—ensuring accurate template reference resolution. \
**Feature Value**: Resolves template parsing failures caused by mixed-namespace usage—improving configuration loading stability and reliability. Prevents silent errors or service anomalies due to illegal character misuse—enhancing system robustness.
- **Related PR**: [#3599](https://github.com/alibaba/higress/pull/3599) \
**Contributor**: @wydream \
**Change Log**: Fixes JSON event fragmentation across network boundaries causing parsing failures in Vertex Provider streaming responses—refactoring chunk buffering and line-boundary detection logic to retain and merge partial JSON payloads—and correcting premature `[DONE]` marker returns that caused valid data loss. \
**Feature Value**: Improves stability and data integrity of Vertex streaming responses—preventing content truncation or parsing errors for large-model streaming outputs (e.g., extended reasoning chains)—significantly enhancing AI proxy service availability and user experience.
- **Related PR**: [#3590](https://github.com/alibaba/higress/pull/3590) \
**Contributor**: @wydream \
**Change Log**: Fixes a regression in the Bedrock Providers SigV4 canonical URI encoding logic: restores `encodeSigV4Path` to apply `PathEscape` directly to path segments—avoiding distortion from double-parsing already-encoded characters (e.g., `%3A`, `%2F`) after `PathUnescape`—ensuring signature alignment with AWS service endpoints. \
**Feature Value**: Resolves frequent 403 errors caused by signature failures—particularly affecting model names with special characters (e.g., `nova-2-lite-v1:0` or ARN-formatted inference profiles)—significantly boosting production stability and API call success rates.
- **Related PR**: [#3587](https://github.com/alibaba/higress/pull/3587) \
**Contributor**: @Sunrisea \
**Change Log**: Upgrades `nacos-sdk-go/v2` to v2.3.5—fixing cancellation logic for multi-callback scenarios, supporting multi-cluster service re-subscription, resolving memory leaks, fixing log file handle leaks, and addressing logger initialization regressions—while updating gRPC and Go dependencies. \
**Feature Value**: Improves Nacos client stability and reliability—preventing OOM or resource exhaustion in production due to memory/file-handle leaks. Enhances multi-cluster service discovery capability—improving registration/discovery resilience for microservices in complex topologies.
- **Related PR**: [#3582](https://github.com/alibaba/higress/pull/3582) \
**Contributor**: @lx1036 \
**Change Log**: Removes duplicate `"istio.io/istio/pilot/pkg/model"` package imports in `pkg/ingress/translation/translation.go`, retaining only the aliased import statement—eliminating compiler warnings and potential symbol collision risks—improving code robustness and maintainability. \
**Feature Value**: Fixes duplicate imports to avoid Go compiler warnings and potential package-initialization conflicts—enhancing code stability. Improves build reliability and long-term maintainability of the Istio Ingress translation module—reducing unexpected error probability.
- **Related PR**: [#3580](https://github.com/alibaba/higress/pull/3580) \
**Contributor**: @shiyan2016 \
**Change Log**: Fixes a defect in the KIngress controllers duplicate route detection logic—incorporating request header matching conditions into deduplication key computation—preventing legitimate routes from being erroneously discarded due to header differences. \
**Feature Value**: Ensures header-differentiated routes are correctly identified and retained—enhancing route configuration reliability and preventing service unavailability or traffic loss from accidental route deletion.
- **Related PR**: [#3575](https://github.com/alibaba/higress/pull/3575) \
**Contributor**: @shiyan2016 \
**Change Log**: Fixes a status-update logic error in `pkg/ingress/kube/kingress/status.go`s `updateStatus` method—correcting an inverted condition for determining whether to update KIngress status—and avoiding abnormal status synchronization. Adds 186 lines of unit test coverage for this logic. \
**Feature Value**: Ensures accurate and timely updates of KIngress resource statuses (e.g., `LoadBalancerIngress`)—preventing service unavailability or inaccurate monitoring alerts due to status misjudgment—enhancing Ingress controller stability and observability.
- **Related PR**: [#3567](https://github.com/alibaba/higress/pull/3567) \
**Contributor**: @DamosChen \
**Change Log**: Fixes occasional endpoint handshake event loss for SSE connections under high load—replacing Redis Pub/Subbased event publishing with direct asynchronous `InjectData` writes to the SSE response stream via local goroutines—eliminating subscribe-goroutine startup latency and timing races. \
**Feature Value**: Improves SSE connection reliability—ensuring all clients reliably receive endpoint events even under high load or CPU-constrained scenarios—preventing session initialization anomalies and functionality loss from handshake failures—enhancing user experience and system robustness.
- **Related PR**: [#3549](https://github.com/alibaba/higress/pull/3549) \
**Contributor**: @wydream \
**Change Log**: Fixes incomplete SigV4 signature coverage for the `ai-proxy` plugins Bedrock Provider in AWS AK/SK auth mode—centralizing `setAuthHeaders` calls from scattered request handlers into the `TransformRequestBodyHeaders` entrypoint—ensuring all Bedrock APIs (including embeddings and other extensions) undergo full SigV4 signing. \
**Feature Value**: Resolves AWS authentication failures caused by missing SigV4 signatures on some APIs—improving Bedrock Provider stability and compatibility across multifaceted capabilities—enabling reliable use of various Bedrock services (e.g., embedding, converse) without authentication concerns.
- **Related PR**: [#3530](https://github.com/alibaba/higress/pull/3530) \
**Contributor**: @Jing-ze \
**Change Log**: Fixes the Anthropic-compatible API message endpoint path for the Qwen provider—updating the legacy path `/api/v2/apps/claude-code-proxy/v1/messages` to the official new path `/apps/anthropic/v1/messages`—ensuring alignment with the Bailian Anthropic API compatibility documentation. \
**Feature Value**: Enables correct AI proxy invocation of Qwens Anthropic-compatible interface—preventing message-request failures from outdated paths—improving service stability and compatibility. Users achieve seamless integration with the latest API without code changes.
- **Related PR**: [#3517](https://github.com/alibaba/higress/pull/3517) \
**Contributor**: @johnlanni \
**Change Log**: Fixes incorrect mapping of OpenAI `tool`-role messages during conversion to Claude protocol—adding logic to transform OpenAI `tool` messages into Claude-compatible `user`-role messages embedding `tool_result` content—ensuring request format compliance with Claude API specifications. \
**Feature Value**: Enables correct forwarding of OpenAI requests containing tool-call results to Claude models—preventing API rejection errors—improving multi-model protocol compatibility and user stability. Users seamlessly switch backends without modifying existing tool-call logic.
- **Related PR**: [#3513](https://github.com/alibaba/higress/pull/3513) \
**Contributor**: @johnlanni \
**Change Log**: Fixes the absence of `question` and `model` fields in the AI statistics plugin under lightweight mode—adjusting request-phase attribute extraction logic to extract key fields upfront without buffering response bodies—and updating default attribute configurations. \
**Feature Value**: Makes AI observability data more complete and accurate under lightweight mode—enabling users to obtain question content and model information for analysis—improving debugging efficiency and statistical dimension completeness while preserving low-overhead characteristics.
- **Related PR**: [#3510](https://github.com/alibaba/higress/pull/3510) \
**Contributor**: @johnlanni \
**Change Log**: Fixes improper nesting of the `type` field within `delta` objects in `message_delta` events during Claude protocol conversion—correcting struct definitions in `claude.go`, updating conversion logic in `claude_to_openai.go`, and synchronizing test cases and model config structures. \
**Feature Value**: Ensures AI proxy compliance with Claude protocol specs when interfacing with OpenAI-compatible services like ZhipuAI—avoiding message parsing failures or streaming response interruptions from malformed formats—enhancing stability and compatibility across multi-model services.
- **Related PR**: [#3507](https://github.com/alibaba/higress/pull/3507) \
**Contributor**: @johnlanni \
**Change Log**: Fixes missing `tool_calls` data in Claude AI proxys OpenAI-compatible streaming responses—adding correct parsing and conversion of `thinking` content—and implementing mapping of OpenAI `reasoning_effort` to Claude `thinking.budget_tokens`. \
**Feature Value**: Enables users to fully retrieve tool-call information and reasoning-process content in streaming responses when using Claude as a backend—improving reliability and debuggability of multi-step AI workflows—and enhancing practicality of the OpenAI compatibility layer.
- **Related PR**: [#3506](https://github.com/alibaba/higress/pull/3506) \
**Contributor**: @johnlanni \
**Change Log**: Fixes incorrect conversion of Claude API `stop_reason = 'tool_use'` responses into OpenAI-compatible `tool_calls` format—unifying handling for both non-streaming and streaming responses—and supplementing missing `tool_calls` arrays and `finish_reason` mappings. \
**Feature Value**: Enables `ai-proxy` to correctly relay Claude tool-call responses to OpenAI clients—improving multi-model proxy compatibility and stability—and preventing downstream application failures from format mismatches.
- **Related PR**: [#3505](https://github.com/alibaba/higress/pull/3505) \
**Contributor**: @johnlanni \
**Change Log**: Fixes `answer` field extraction failure in streaming responses—where `extractStreamingBodyByJsonPath` returned `nil` due to an empty default rule when `use_default_attributes` was enabled. Sets `BuiltinAnswerKey`s rule default to `RuleAppend` to ensure proper concatenation and extraction of streaming content. \
**Feature Value**: Users reliably capture `answer` field content when using AI streaming-response statistics—avoiding `ai_log` entries with `response_type = stream` but missing `answer`—enhancing observation data completeness and debugging efficiency.
- **Related PR**: [#3503](https://github.com/alibaba/higress/pull/3503) \
**Contributor**: @johnlanni \
**Change Log**: Fixes text content loss in Claude protocol conversions when both `tool_result` and `text` are present—adding logic in `claude_to_openai.go` to preserve `text content` and supplementing test cases for multi-content coexistence scenarios. \
**Feature Value**: Ensures user-provided text messages are not lost in tool-call scenarios (e.g., Claude Code)—improving AI proxy compatibility and reliability for mixed-content messages—and enhancing developer experience and debugging efficiency in complex interactive workflows.
- **Related PR**: [#3502](https://github.com/alibaba/higress/pull/3502) \
**Contributor**: @johnlanni \
**Change Log**: Fixes missing `event` field in SSE format for Claude streaming responses—adding necessary event identifiers (`event: message_delta`, `event: message_stop`) in `[DONE]` message handling to ensure full compliance with the official Claude streaming protocol. \
**Feature Value**: Enables correct parsing of Claude model streaming responses—preventing frontend message loss or parsing failures due to malformed formats—enhancing stability and user experience for unified multi-model access.
- **Related PR**: [#3500](https://github.com/alibaba/higress/pull/3500) \
**Contributor**: @johnlanni \
**Change Log**: Changes GitHub Actions workflow runtime environment from `ubuntu-latest` to fixed `ubuntu-22.04`—resolving CI stability issues where underlying image upgrades caused `kind` cluster container image loading failures (`ctr images import` errors). \
**Feature Value**: Fixes persistent failures in critical CI tasks like `higress-conformance-test`—ensuring reliable code-merge workflows and automated validation—preventing developers from being blocked by CI false positives.
- **Related PR**: [#3496](https://github.com/alibaba/higress/pull/3496) \
**Contributor**: @johnlanni \
**Change Log**: Fixes serialization of empty `Content` fields in `system` prompts for Claude Code mode—adjusting JSON tags in `claudeChatMessageContent` struct to omit empty `content` fields instead of outputting `null`—preventing API request rejections. \
**Feature Value**: Resolves request failures caused by invalid `system` fields in Claude API calls—enhancing system stability and compatibility—ensuring users receive normal responses in Claude Code mode without manually avoiding empty-content scenarios.
- **Related PR**: [#3491](https://github.com/alibaba/higress/pull/3491) \
**Contributor**: @johnlanni \
**Change Log**: Fixes streaming-response body buffering failure in the AI statistics plugin—explicitly setting `ValueSource = ResponseStreamingBody` for built-in attributes—ensuring `answer` fields are correctly extracted and logged to `ai_log` when `use_default_attributes` is enabled. \
**Feature Value**: Enables accurate capture and logging of streaming AI response `answer` content when default attribute collection is enabled—improving log observability and debugging capability—avoiding critical response-data loss leading to analytical blind spots.
- **Related PR**: [#3485](https://github.com/alibaba/higress/pull/3485) \
**Contributor**: @johnlanni \
**Change Log**: Fixes incorrect model-reference prefix logic in Higress providers—removing conditional checks and universally prepending `'higress/'` to all model IDs (including `higress/auto`)—ensuring correct model-reference formatting in configurations generated by OpenClaw integration plugins. \
**Feature Value**: Resolves configuration-parsing failures caused by missing model-reference prefixes—improving stability and compatibility between Higress and OpenClaw integration—enabling correct use of `higress/auto` and other auto-models without manual configuration corrections.
- **Related PR**: [#3484](https://github.com/alibaba/higress/pull/3484) \
**Contributor**: @johnlanni \
**Change Log**: Fixes installation path issues for the `higress-openclaw-integration` skill—adding `mkdir -p higress-install` and `cd higress-install` commands—and updating the log path from `./higress/logs/access.log` to `./higress-install/logs/access.log` to avoid polluting the current working directory. \
**Feature Value**: Isolates Higress installation artifacts in a dedicated directory—improving workspace cleanliness. Enables easy cleanup or reinstallation—reducing environment conflict risks—and enhancing skill-deployment reliability and maintainability.
- **Related PR**: [#3483](https://github.com/alibaba/higress/pull/3483) \
**Contributor**: @johnlanni \
**Change Log**: Fixes path-resolution issues in the skill-packaging workflow—replacing error-prone relative paths with absolute paths based on `$GITHUB_WORKSPACE`, using subshells to avoid directory-change side effects, and adding output-directory existence checks—improving CI robustness. \
**Feature Value**: Ensures stable ZIP-package generation regardless of execution subdirectory—preventing build failures from path errors—and enhancing OSS skill-sync reliability and developer collaboration efficiency.
- **Related PR**: [#3477](https://github.com/alibaba/higress/pull/3477) \
**Contributor**: @johnlanni \
**Change Log**: Fixes redundant `/v1` path concatenation in the OpenClaw plugins `baseUrl`—removing manual `/v1` additions from functions like `testGatewayConnection` to prevent invalid URLs (e.g., `http://localhost:8080/v1/v1`)—ensuring correct gateway request paths. \
**Feature Value**: Resolves API call failures caused by duplicate paths—improving plugin connection stability and compatibility. Users can use model services normally without manual URL adjustments—lowering deployment and debugging barriers.
### ♻️ Refactoring & Optimizations (Refactoring)
- **Related PR**: [#3657](https://github.com/alibaba/higress/pull/3657) \
**Contributor**: @CH3CHO \
**Change Log**: Removes 29 unused Pilot configuration items (e.g., `autoscaleEnabled`, `replicaCount`) from `higress-core/values.yaml` in the Helm Chart—and updates parameter descriptions in `README.md`—streamlining the configuration file and improving chart maintainability and clarity. \
**Feature Value**: Reduces user configuration confusion and avoids deployment anomalies from residual deprecated parameters. Simplifies chart structure—lowering operational complexity and improving upgrade/customization efficiency—helping users focus on core configuration parameters.
- **Related PR**: [#3516](https://github.com/alibaba/higress/pull/3516) \
**Contributor**: @johnlanni \
**Change Log**: Migrates the MCP SDK from an external repository into the main repo—moving `mcp-servers/all-in-one` to `extensions/mcp-server`, introducing `pkg/mcp`, deleting obsolete modules like `pkg/log`, and unifying all MCP import paths and dependency references. \
**Feature Value**: Improves code maintainability and build consistency—avoiding cross-repository dependency issues. Users gain more stable MCP functionality—significantly improving plugin development and debugging efficiency—and laying a unified foundation for future MCP capability expansion.
- **Related PR**: [#3475](https://github.com/alibaba/higress/pull/3475) \
**Contributor**: @johnlanni \
**Change Log**: Renames the skill from `higress-clawdbot-integration` to `higress-openclaw-integration`, removes deprecated `agent-session-monitor` documentation content, and updates model IDs across multiple scripts (e.g., `claude-opus-4.5``4.6`, `gpt-5.2``5.3-codex`)—ensuring configuration consistency and naming accuracy. \
**Feature Value**: Enhances project naming standardization and maintainability—avoiding confusion from legacy names. Updated model IDs support newer large-model versions—enabling users to seamlessly leverage higher-performance, more stable models—enhancing AI gateway integration experiences.
### 📚 Documentation Updates (Documentation)
- **Related PR**: [#3644](https://github.com/alibaba/higress/pull/3644) \
**Contributor**: @Jholly2008 \
**Change Log**: Fixes two broken `higress.io` links in `README.md` and `docs/architecture.md`: replacing the Quick Start link in the English README and the Admin SDK blog link in the architecture doc—ensuring link accuracy and accessibility. \
**Feature Value**: Improves documentation usability and user experience—preventing information-access disruption from broken links. Ensures smooth onboarding for new users and seamless architecture-resource lookup for developers—enhancing project professionalism and credibility.
- **Related PR**: [#3524](https://github.com/alibaba/higress/pull/3524) \
**Contributor**: @github-actions[bot] \
**Change Log**: Adds bilingual (Chinese/English) Release Notes documents for v2.1.11—including release overview, update distribution stats (4 new features, 2 bug fixes), and full changelog structure—automatically generated and maintained by GitHub Actions to ensure version information is traceable and searchable. \
**Feature Value**: Provides users with clear, structured version-upgrade references—helping them quickly understand new features, fixes, and compatibility changes. Enhances product transparency and usability—reducing upgrade risks and learning costs.
- **Related PR**: [#3490](https://github.com/alibaba/higress/pull/3490) \
**Contributor**: @johnlanni \
**Change Log**: Optimizes the model provider list in the OpenClaw integration skill documentation—topping 8 frequently used providers (Zhipu, Claude Code, Moonshot, etc.) and collapsing infrequent ones into expandable sections—to improve readability and information hierarchy. \
**Feature Value**: Significantly improves the new-user configuration experience for Higress AI Gateway—lowering learning costs. Structured presentation of provider options helps users rapidly identify mainstream supported models—enhancing OpenClaw skill usability and adoption efficiency.
- **Related PR**: [#3480](https://github.com/alibaba/higress/pull/3480) \
**Contributor**: @johnlanni \
**Change Log**: Updates the OpenClaw integration documentation `SKILL.md`—adding dynamic configuration update instructions covering LLM provider hot-addition, online API key updates, and multi-model auto-routing mechanisms—and adding configuration-update guidance prompts in plugin hints. \
**Feature Value**: Helps users understand how to dynamically extend and update AI service configurations without restarts—lowering operational barriers and improving multi-model switching and management flexibility—enhancing product usability and enterprise-grade configuration governance.
- **Related PR**: [#3478](https://github.com/alibaba/higress/pull/3478) \
**Contributor**: @johnlanni \
**Change Log**: Explicitly labels OpenClaws Higress plugin-related commands in `SKILL.md` as interactive operations—adding warning prompts and separating user-manual-execution steps—to avoid AI agents executing them incorrectly. \
**Feature Value**: Helps users clearly identify commands requiring manual intervention—improving integration process predictability and success rates—while reducing operation failures and debugging costs caused by AI agents attempting interactive command execution.
- **Related PR**: [#3476](https://github.com/alibaba/higress/pull/3476) \
**Contributor**: @johnlanni \
**Change Log**: Refactors the `higress-openclaw-integration` skill documentation—simplifying deployment from 6 steps to 3, collecting all necessary information upfront—and adding a 21+-provider comparison table clarifying model-prefix patterns and OAuth token requirements for Claude. \
**Feature Value**: Significantly boosts skill invocation success rates and stability—even for weaker AI agents—reducing user comprehension and usage barriers. Minimizes configuration errors from verbose steps or missing info—accelerating Higress AI Gateway adoption within the OpenClaw ecosystem.
- **Related PR**: [#3468](https://github.com/alibaba/higress/pull/3468) \
**Contributor**: @github-actions[bot] \
**Change Log**: Adds bilingual (Chinese/English) release notes for v2.2.0—including release overview, update distribution stats (48 new features, 20 bug fixes, etc.), and full changelog—automatically generated by GitHub Actions to ensure authoritative, timely, and bilingual version information. \
**Feature Value**: Provides users and developers with clear, structured version-upgrade references—lowering usage barriers and migration costs. Bilingual support improves accessibility for international users—enhancing project professionalism and community trust.
---
## 📊 Release Statistics
- 🚀 New Features: 29
- 🐛 Bug Fixes: 26
- ♻️ Refactoring & Optimizations: 3
- 📚 Documentation Updates: 7
**Total**: 65 changes
Thank you to all contributors for your hard work! 🎉
# Higress Console
## 📋 Overview of This Release
This release includes **18** updates, covering feature enhancements, bug fixes, and performance optimizations.
### Distribution of Updates
- **New Features**: 7
- **Bug Fixes**: 9
- **Documentation Updates**: 2
---
## 📝 Complete Change Log
### 🚀 New Features (Features)
- **Related PR**: [#621](https://github.com/higress-group/higress-console/pull/621) \
**Contributor**: @Thomas-Eliot \
**Change Log**: Enhanced MCP Server interaction capabilities: supports automatic Host header rewriting for DNS backends; improves transport protocol selection and full-path configuration in direct routing scenarios; refines parsing of DSN special characters (e.g., `@`) in DB-to-MCP Server scenarios. \
**Feature Value**: Improves the flexibility and compatibility of MCP Server integration, reduces user configuration complexity, prevents connection failures caused by path prefix ambiguity or DSN special characters, and significantly enhances multi-environment deployment experience and system stability.
- **Related PR**: [#608](https://github.com/higress-group/higress-console/pull/608) \
**Contributor**: @Libres-coder \
**Change Log**: Added plugin display functionality to the AI Route Management page, supporting expansion to view enabled plugins and showing an "Enabled" badge in the configuration panel; reused the standard route plugin display logic, involving frontend AI route components, plugin list query logic, and route page initialization optimization. \
**Feature Value**: Enables users to intuitively view and verify enabled plugins directly within the AI Route Management interface, improving observability and operational consistency of AI route configurations, reducing misconfiguration risks, and enhancing unified platform management experience and operational efficiency.
- **Related PR**: [#604](https://github.com/higress-group/higress-console/pull/604) \
**Contributor**: @CH3CHO \
**Change Log**: Added support for regular expression-based path rewriting via the `higress.io/rewrite-target` annotation; extended Kubernetes annotation constants, updated route transformation logic, introduced a regex rewrite type enumeration, and added frontend i18n support. \
**Feature Value**: Empowers users to define flexible path rewriting rules using regular expressions, enhancing routing match precision and adaptability—ideal for complex URL transformation scenarios—while lowering gateway configuration barriers and strengthening business integration capability.
- **Related PR**: [#603](https://github.com/higress-group/higress-console/pull/603) \
**Contributor**: @CH3CHO \
**Change Log**: Introduced the constant `STATIC_SERVICE_PORT = 80` in the static service source form component and explicitly displays this fixed port in the UI, enabling users to clearly understand the default HTTP port bound to static services and thereby improving configuration transparency and comprehensibility. \
**Feature Value**: Users can visually identify the default port `80` when configuring static service sources, preventing service access failures caused by port misunderstanding; lowers operational overhead and improves deployment efficiency and user experience consistency.
- **Related PR**: [#602](https://github.com/higress-group/higress-console/pull/602) \
**Contributor**: @CH3CHO \
**Change Log**: Added search functionality to the upstream service selection component in AI Routes, enabling frontend input filtering of the service list to improve selection efficiency for long lists; achieved via minimal code changes to the `RouteForm` component to enhance interactivity. \
**Feature Value**: Allows users to quickly search and locate target upstream services during AI route configuration, significantly improving usability when numerous services exist, reducing configuration error rates, and boosting both operational and development efficiency.
- **Related PR**: [#566](https://github.com/higress-group/higress-console/pull/566) \
**Contributor**: @OuterCyrex \
**Change Log**: Added support for Tongyi Qwen large language model (LLM) services, including a dedicated `QwenLlmProviderHandler` implementation, frontend i18n adaptation, and a configuration form supporting custom service endpoints, internet search, and file ID uploads. \
**Feature Value**: Enables flexible integration of private or customized Qwen services, improving AI gateway compatibility with domestic LLMs; simplifies deployment workflows via the configuration UI, lowers enterprise-level AI service integration barriers, and strengthens platform extensibility.
- **Related PR**: [#552](https://github.com/higress-group/higress-console/pull/552) \
**Contributor**: @lcfang \
**Change Log**: Added support for the `vport` (virtual port) attribute to extend MCP Bridge registry configuration capabilities; introduced the `VPort` class into `ServiceSource`, enhanced Kubernetes model conversion logic, and made service virtual ports configurable—resolving routing failures caused by dynamic backend instance port changes in registries such as Eureka/Nacos. \
**Feature Value**: Allows users to specify a service virtual port (`vport`) in registry configurations, ensuring routing rules remain effective despite backend port changes; enhances service governance stability and compatibility, reduces traffic forwarding anomalies due to port mismatches, and simplifies multi-environment deployment and operational complexity.
### 🐛 Bug Fixes (Bug Fixes)
- **Related PR**: [#620](https://github.com/higress-group/higress-console/pull/620) \
**Contributor**: @CH3CHO \
**Change Log**: Fixed a typo in the `sortWasmPluginMatchRules` logic, correcting variable or method name errors that could cause latent logic anomalies during matching rule sorting—ensuring Wasm plugin rules are sorted correctly according to their intended priority. \
**Feature Value**: Prevents matching rule sorting errors caused by typos, guaranteeing accurate application order of Wasm plugins in Kubernetes CRs; improves reliability of plugin-based routing and policy enforcement, reducing issues where configured behavior deviates from expectations.
- **Related PR**: [#619](https://github.com/higress-group/higress-console/pull/619) \
**Contributor**: @CH3CHO \
**Change Log**: Fixed redundant version information storage when converting `AiRoute` to `ConfigMap`: removed the `version` field from the `data` JSON payload, retaining it solely in the `ConfigMap` metadata to eliminate data redundancy and potential inconsistency. \
**Feature Value**: Improves configuration management accuracy and consistency, preventing parsing errors or synchronization anomalies caused by duplicate version fields; enhances system stability and operational reliability—delivering direct benefits to users managing route configurations via Kubernetes ConfigMaps.
- **Related PR**: [#618](https://github.com/higress-group/higress-console/pull/618) \
**Contributor**: @CH3CHO \
**Change Log**: Refactored API authentication logic in `SystemController`, introducing an `@AllowAnonymous` annotation mechanism for unified handling of unauthenticated endpoints; replaced hardcoded path whitelists with AOP-based fine-grained access control, resolving a security vulnerability permitting unauthorized access to sensitive system interfaces. \
**Feature Value**: Addresses a latent unauthorized access vulnerability in the system controller, significantly improving platform security; delivers stronger permission guarantees for users and mitigates risks of data leakage or privilege escalation caused by authentication logic defects—enhancing compliance and stability in production environments.
- **Related PR**: [#617](https://github.com/higress-group/higress-console/pull/617) \
**Contributor**: @CH3CHO \
**Change Log**: Fixed three critical frontend console issues: missing unique `key` props causing React warnings during list rendering; Content Security Policy (CSP) blocking remote image loading; and incorrect type definition for the `Consumer.name` field (corrected from `boolean` to `string`). \
**Feature Value**: Improves frontend application stability and user experience, eliminating console errors that interfere with development debugging, ensuring proper avatar rendering and accurate consumer information parsing, and preventing runtime exceptions or data display issues caused by type mismatches.
- **Related PR**: [#614](https://github.com/higress-group/higress-console/pull/614) \
**Contributor**: @lc0138 \
**Change Log**: Corrected the type definition of the `type` field (indicating service source) in the `ServiceSource` class and added validation logic to ensure incoming registry types belong to a predefined set, preventing illegal values from triggering runtime exceptions. \
**Feature Value**: Enhances system robustness and data consistency, avoiding configuration parsing failures or backend exceptions caused by invalid service source types; ensures reliable operation of service registration and discovery functions and reduces operational troubleshooting effort.
- **Related PR**: [#613](https://github.com/higress-group/higress-console/pull/613) \
**Contributor**: @lc0138 \
**Change Log**: Fixed a frontend Content Security Policy (CSP) configuration defect by adding essential `<meta>` tags and security policy declarations in `document.tsx`, preventing XSS and other malicious script injections and strengthening security header control during page loading. \
**Feature Value**: Significantly reduces the risk of cross-site scripting (XSS) attacks and data injection vulnerabilities in the frontend application, enhancing user access security and trust; aligns with modern web security best practices and provides more reliable security assurance for production environments.
- **Related PR**: [#612](https://github.com/higress-group/higress-console/pull/612) \
**Contributor**: @zhwaaaaaa \
**Change Log**: Added logic in `DashboardServiceImpl` to ignore hop-to-hop headers (e.g., `Transfer-Encoding`) per RFC 2616, filtering headers that must not be forwarded by proxies—resolving Grafana frontend page load failures caused by reverse proxies transmitting `Transfer-Encoding: chunked`. \
**Feature Value**: Fixes the issue where `Transfer-Encoding: chunked` headers transmitted by reverse proxies cause Grafana frontend pages to crash, improving stability and compatibility when integrating external monitoring services in the console; enables seamless dashboard access for users.
- **Related PR**: [#609](https://github.com/higress-group/higress-console/pull/609) \
**Contributor**: @CH3CHO \
**Change Log**: Fixed a type error in the `Consumer` interfaces `name` field, correcting it from `boolean` to `string` to ensure frontend data structures align with actual backend response values and avoid runtime type errors and UI rendering anomalies. \
**Feature Value**: Enhances accuracy and stability of consumer information display, preventing page crashes or incorrect data rendering due to type mismatches, and improving user experience and system reliability during consumer management.
- **Related PR**: [#605](https://github.com/higress-group/higress-console/pull/605) \
**Contributor**: @SaladDay \
**Change Log**: Corrected the frontend form validation regex for AI route names, adding support for periods (`.`) and restricting alphabetic characters to lowercase only; simultaneously updated Chinese and English error messages to accurately reflect the revised rules. \
**Feature Value**: Resolves issues where users incorrectly receive rejection errors when creating AI routes with names containing periods or uppercase letters; improves consistency between form validation logic and UI prompts, reduces configuration failure rates, and enhances overall usability.
### 📚 Documentation Updates (Documentation)
- **Related PR**: [#611](https://github.com/higress-group/higress-console/pull/611) \
**Contributor**: @qshuai \
**Change Log**: Corrected the OpenAPI documentation summary comment for the `@PostMapping` endpoint in `LlmProvidersController`, replacing the inaccurate description “Add a new route” with a precise one reflecting its actual purpose (adding an LLM provider). Ensures API documentation matches real functionality. \
**Feature Value**: Improves API documentation accuracy, helping developers correctly understand the endpoints purpose—reducing integration misunderstandings and debugging effort—and enhancing the maintainability and user experience of the consoles APIs.
- **Related PR**: [#610](https://github.com/higress-group/higress-console/pull/610) \
**Contributor**: @heimanba \
**Change Log**: Updated frontend canary plugin documentation: changed `rewrite`, `backendVersion`, and `enabled` fields from required to optional; corrected the associated path for the `name` field within `rules` (from `deploy.gray[].name` to `grayDeployments[].name`); and synchronized field descriptions and requirements across Chinese/English `README`s and `spec.yaml`. \
**Feature Value**: Increases configuration flexibility and compatibility, lowering the barrier to adopting canary capabilities; provides more precise terminology and path references, minimizing configuration errors caused by documentation ambiguity and enhancing developer experience and documentation credibility.
---
## 📊 Release Statistics
- 🚀 New Features: 7
- 🐛 Bug Fixes: 9
- 📚 Documentation Updates: 2
**Total**: 18 changes
Thank you to all contributors for your hard work! 🎉

View File

@@ -0,0 +1,491 @@
# Higress
## 📋 本次发布概览
本次发布包含 **65** 项更新涵盖了功能增强、Bug修复、性能优化等多个方面。
### 更新内容分布
- **新功能**: 29项
- **Bug修复**: 26项
- **重构优化**: 3项
- **文档更新**: 7项
---
## 📝 完整变更日志
### 🚀 新功能 (Features)
- **Related PR**: [#3692](https://github.com/alibaba/higress/pull/3692) \
**Contributor**: @EndlessSeeker \
**Change Log**: PR更新了Higress项目版本号至2.2.1涉及Makefile.core.mk、envoy子模块提交哈希、helm/core和helm/higress的Chart.yaml及Chart.lock文件中的版本字段同步了依赖版本与应用版本标识。 \
**Feature Value**: 为用户提供了新版本2.2.1的正式发布包确保Helm Chart部署时拉取正确版本的组件与Envoy镜像提升版本一致性与可追溯性降低因版本错配导致的部署失败风险。
- **Related PR**: [#3689](https://github.com/alibaba/higress/pull/3689) \
**Contributor**: @rinfx \
**Change Log**: 为model-mapper插件新增modelToHeader配置项允许用户自定义模型映射后写入的HTTP请求头名称默认为x-higress-llm-model并重构header更新逻辑以支持动态配置和向后兼容。 \
**Feature Value**: 用户可灵活指定LLM模型标识透传的请求头字段名满足不同后端服务对接规范避免硬编码导致的兼容性问题提升插件在多云、混合部署场景下的适配能力和治理灵活性。
- **Related PR**: [#3686](https://github.com/alibaba/higress/pull/3686) \
**Contributor**: @rinfx \
**Change Log**: 新增 providerBasePath 配置项,支持在 ProviderConfig 中定义基础路径前缀,并在所有 provider 请求路径改写时自动注入;同时优化 providerDomain 处理逻辑,提升域名与路径组合的灵活性和可靠性。 \
**Feature Value**: 用户可通过 providerBasePath 实现统一 API 路径前缀管理,便于网关层路由聚合、多租户隔离及反向代理路径重写;显著增强 AI 代理插件对复杂部署场景如嵌套路由、SaaS 多实例)的适配能力。
- **Related PR**: [#3651](https://github.com/alibaba/higress/pull/3651) \
**Contributor**: @wydream \
**Change Log**: 重构Azure Provider的multipart图像请求处理逻辑修复JSON模型映射错误、domain-only场景下model映射不一致问题优化大图/高并发时的内存占用与重复读取,并新增完整测试覆盖。 \
**Feature Value**: 提升Azure图像编辑/变体API的稳定性与性能确保大图片上传和高并发场景下正确解析multipart请求避免模型映射失败导致的请求中断增强用户调用成功率和响应效率。
- **Related PR**: [#3649](https://github.com/alibaba/higress/pull/3649) \
**Contributor**: @wydream \
**Change Log**: 为ai-proxy的Vertex Provider实现了OpenAI response_format到Vertex generationConfig的映射重点支持gemini-2.5+结构化输出对gemini-2.0-*采用安全忽略策略,并新增大量测试用例验证结构化输出逻辑。 \
**Feature Value**: 用户可在Vertex后端尤其gemini-2.5+稳定使用OpenAI标准的JSON Schema响应格式提升模型输出可控性与下游系统集成效率兼容旧版模型确保服务平滑升级降低迁移成本。
- **Related PR**: [#3642](https://github.com/alibaba/higress/pull/3642) \
**Contributor**: @JianweiWang \
**Change Log**: 将AI安全守卫插件中原始的纯文本denyMessage替换为结构化的DenyResponseBody新增包含blockedDetails、requestId和guardCode字段的响应结构并在config包中引入JSON序列化支持及配套构建与解析辅助函数。 \
**Feature Value**: 用户可获得更丰富、标准化的拒绝响应元数据,便于客户端精准识别拦截原因、追溯请求链路及对接风控系统,显著提升故障排查效率与安全事件协同分析能力。
- **Related PR**: [#3638](https://github.com/alibaba/higress/pull/3638) \
**Contributor**: @rinfx \
**Change Log**: 为ai-proxy插件新增providerDomain通用配置字段及resolveDomain域名解析逻辑支持Gemini和Claude provider自定义域名配置并在CreateProvider和TransformRequestHeaders中集成该能力同时补充了完整的单元测试覆盖。 \
**Feature Value**: 用户可通过配置自定义域名灵活对接不同网络环境下的Gemini与Claude服务提升部署灵活性与网络适应性尤其适用于企业内网、代理中转或合规域名管控场景降低服务调用失败率。
- **Related PR**: [#3632](https://github.com/alibaba/higress/pull/3632) \
**Contributor**: @lexburner \
**Change Log**: 新增GitHub Actions工作流在higress发布v*.*.*标签时自动构建并推送plugin-server Docker镜像支持通过workflow_dispatch指定plugin-server的分支/标签/提交,提升插件服务部署自动化能力。 \
**Feature Value**: 用户无需手动构建和发布plugin-server镜像显著简化Higress插件生态的版本同步与部署流程增强插件服务交付的可靠性与效率降低运维门槛。
- **Related PR**: [#3625](https://github.com/alibaba/higress/pull/3625) \
**Contributor**: @johnlanni \
**Change Log**: 新增promoteThinkingOnEmpty配置项当模型响应仅含reasoning_content而无text内容时自动将其提升为text内容新增hiclawMode快捷开关同时启用mergeConsecutiveMessages和promoteThinkingOnEmpty支持HiClaw多智能体协作场景并兼容流式(SSE)与非流式响应路径。 \
**Feature Value**: 显著提升AI代理在复杂推理链场景下的响应完整性与下游兼容性避免空响应导致的客户端异常hiclawMode简化多Agent协同配置降低用户集成门槛增强系统在真实业务场景中的鲁棒性和易用性。
- **Related PR**: [#3624](https://github.com/alibaba/higress/pull/3624) \
**Contributor**: @rinfx \
**Change Log**: 提升ai-statistics插件默认value_length_limit从4000至32000并在streaming过程中解析到token usage时立即写入AILog而非仅在流结束时落盘增强大字段支持与流式响应的可观测性。 \
**Feature Value**: 用户在使用Codex等编码工具时可更完整记录长属性值和实时token用量提升AI调用行为分析精度尤其改善流式响应因主动断连导致用量丢失的问题增强生产环境监控可靠性。
- **Related PR**: [#3620](https://github.com/alibaba/higress/pull/3620) \
**Contributor**: @wydream \
**Change Log**: 新增对OpenAI语音转录(/v1/audio/transcriptions)、翻译(/v1/audio/translations)、实时通信(/v1/realtime)及Qwen兼容模式Responses API(/api/v2/apps/protocols/compatible-mode/v1/responses)的路径识别与路由支持扩展了provider映射关系和测试覆盖。 \
**Feature Value**: 使ai-proxy插件全面支持OpenAI语音与实时API标准及百炼Qwen兼容协议用户可无缝调用语音处理、实时流式交互等高级能力提升多模态AI服务集成效率与协议兼容性。
- **Related PR**: [#3609](https://github.com/alibaba/higress/pull/3609) \
**Contributor**: @wydream \
**Change Log**: 为Amazon Bedrock Provider新增Prompt Cache保留策略的配置能力支持请求级动态覆盖与Provider级默认兜底双模式统一并修正cached_tokens统计口径整合cacheReadInputTokens等Bedrock原生usage字段。 \
**Feature Value**: 用户可灵活控制Prompt缓存生命周期提升缓存命中率与成本效益默认配置能力降低API调用复杂度提升集成易用性准确的usage统计助力精细化成本核算与用量分析。
- **Related PR**: [#3598](https://github.com/alibaba/higress/pull/3598) \
**Contributor**: @johnlanni \
**Change Log**: 新增mergeConsecutiveMessages配置选项在AI代理请求预处理阶段自动合并连续同角色消息如多个user消息通过遍历并重组messages数组实现兼容GLM、Kimi、Qwen等非OpenAI系模型严格交替要求。 \
**Feature Value**: 使ai-proxy插件无缝适配主流国产及本地LLM服务避免因消息格式不合规导致的API拒绝错误显著提升多模型场景下的请求成功率与用户体验一致性。
- **Related PR**: [#3585](https://github.com/alibaba/higress/pull/3585) \
**Contributor**: @CH3CHO \
**Change Log**: 该PR在model-router和model-mapper插件的默认路径后缀列表中新增了"/responses",使两者原生支持/v1/responses接口调用无需额外配置即可路由和映射响应相关请求。 \
**Feature Value**: 用户可直接通过/v1/responses路径调用模型服务响应功能提升API一致性与易用性降低定制化配置成本增强模型网关对新兴OpenAI兼容接口的开箱即用支持能力。
- **Related PR**: [#3570](https://github.com/alibaba/higress/pull/3570) \
**Contributor**: @CH3CHO \
**Change Log**: 升级控制台组件至v2.2.1版本并同步发布Higress主版本v2.2.1涉及VERSION文件、Chart.yaml中appVersion及Chart.lock中依赖版本和digest的更新确保Helm部署时拉取正确版本的控制台子chart。 \
**Feature Value**: 为用户提供最新版控制台功能与体验优化,提升管理界面稳定性与兼容性;通过语义化版本同步,增强集群部署一致性,降低因版本错配导致的运维风险,简化升级流程。
- **Related PR**: [#3563](https://github.com/alibaba/higress/pull/3563) \
**Contributor**: @wydream \
**Change Log**: 为Bedrock Provider新增OpenAI Prompt Cache参数支持实现请求侧prompt_cache_retention/prompt_cache_key到Bedrock cachePoint的转换以及响应侧cacheRead/cacheWrite tokens到OpenAI usage中cached_tokens的映射。 \
**Feature Value**: 用户可在使用Bedrock后端时无缝享受OpenAI Prompt Cache功能降低重复提示词推理开销提升响应速度并节省成本同时获得标准OpenAI缓存用量指标便于监控和计费。
- **Related PR**: [#3550](https://github.com/alibaba/higress/pull/3550) \
**Contributor**: @icylord \
**Change Log**: 为Helm Chart中的gateway、plugin server和controller组件增加了imagePullPolicy的可配置能力通过模板条件判断和values.yaml中新增字段实现灵活的镜像拉取策略控制提升部署灵活性。 \
**Feature Value**: 用户可根据不同环境如开发、生产自定义镜像拉取策略Always/IfNotPresent/Never避免因镜像缓存问题导致服务异常增强部署可靠性与运维可控性。
- **Related PR**: [#3536](https://github.com/alibaba/higress/pull/3536) \
**Contributor**: @wydream \
**Change Log**: 为ai-proxy的Vertex Provider新增支持OpenAI图像编辑/v1/images/edits与变体生成/v1/images/variationsAPI实现multipart/form-data请求解析与转换补充JSON image_url兼容逻辑并新增multipart_helper.go处理二进制图像上传。 \
**Feature Value**: 使用户可通过标准OpenAI SDKPython/Node直接调用Vertex AI图像编辑和变体功能无需修改客户端代码提升跨云平台AI服务的无缝集成体验与开发效率。
- **Related PR**: [#3523](https://github.com/alibaba/higress/pull/3523) \
**Contributor**: @johnlanni \
**Change Log**: 为ai-statistics插件新增Claude/Anthropic流式响应的tool calls解析能力支持事件驱动格式识别tool_use块、累积JSON参数片段、完整组装工具调用信息扩展了StreamingParser结构体以跟踪内容块状态。 \
**Feature Value**: 使用户在使用Claude模型时能准确统计和分析流式工具调用行为提升AI应用可观测性与调试效率为多模型统一监控提供关键支持增强平台对Anthropic生态的兼容性。
- **Related PR**: [#3521](https://github.com/alibaba/higress/pull/3521) \
**Contributor**: @johnlanni \
**Change Log**: 将global.hub参数重构为跨Higress部署与Wasm插件共享的基础镜像仓库配置并引入独立的pluginNamespace命名空间使插件镜像路径可区分于主组件同时统一更新多处Helm模板中的镜像引用逻辑。 \
**Feature Value**: 用户可更灵活地管理不同组件如网关、控制器、插件、Redis的镜像源支持插件与核心组件使用不同仓库或路径提升多环境部署一致性与私有化定制能力降低镜像拉取失败风险。
- **Related PR**: [#3518](https://github.com/alibaba/higress/pull/3518) \
**Contributor**: @johnlanni \
**Change Log**: 在Claude到OpenAI请求转换过程中新增逻辑解析并剥离系统消息中动态变化的cch字段确保x-anthropic-billing-header可缓存修改核心转换代码并新增完整单元测试覆盖该行为。 \
**Feature Value**: 解决因cch字段动态变化导致的Prompt缓存失效问题显著提升AI代理响应速度与服务稳定性降低重复请求开销改善用户交互体验和CLI工具整体性能。
- **Related PR**: [#3512](https://github.com/alibaba/higress/pull/3512) \
**Contributor**: @johnlanni \
**Change Log**: 新增轻量模式配置项use_default_response_attributes通过跳过缓冲大型请求/响应体如messages、answer、reasoning来显著降低内存占用适用于生产环境高并发AI可观测性场景。 \
**Feature Value**: 帮助用户在生产环境中平衡AI可观测性与资源开销避免因完整消息体缓存导致的OOM风险提升服务稳定性与吞吐能力尤其适用于长对话和流式响应场景。
- **Related PR**: [#3511](https://github.com/alibaba/higress/pull/3511) \
**Contributor**: @johnlanni \
**Change Log**: 为ai-statistics插件新增内置system字段支持解析Claude /v1/messages API中顶层的system字段扩展了对Claude系统提示的结构化采集能力通过在main.go中定义BuiltinSystemKey常量实现。 \
**Feature Value**: 使用户能准确统计和分析Claude模型调用中的系统提示内容提升AI调用可观测性与合规审计能力支持更精细化的提示工程效果评估和安全策略落地。
- **Related PR**: [#3499](https://github.com/alibaba/higress/pull/3499) \
**Contributor**: @johnlanni \
**Change Log**: 为OpenAI有状态API如Responses、Files、Batches等引入消费者亲和性机制通过解析x-mse-consumer请求头并使用FNV-1a哈希算法一致选择同一API token确保跨请求的会话粘性与状态连续性。 \
**Feature Value**: 解决多token配置下有状态API因路由不一致导致的404错误问题显著提升Fine-tuning、Response链式调用等场景的稳定性与可靠性使用户无需感知底层负载分发逻辑即可获得正确响应。
- **Related PR**: [#3489](https://github.com/alibaba/higress/pull/3489) \
**Contributor**: @johnlanni \
**Change Log**: 新增z.ai模型服务支持实现品牌名多语言显示中文'智谱'、英文'z.ai'并添加自动区域检测脚本根据系统时区判断用户地域自动配置api.z.ai域名及code plan模式选项。 \
**Feature Value**: 提升Higress AI网关对z.ai服务的开箱即用体验降低中国与国际用户配置门槛自动域名适配避免手动错误增强部署可靠性与本地化友好性加速AI能力集成落地。
- **Related PR**: [#3488](https://github.com/alibaba/higress/pull/3488) \
**Contributor**: @johnlanni \
**Change Log**: 为ZhipuAI provider新增可配置域名支持中国/国际双端点、代码规划模式路由切换及思考模式支持扩展了API请求路径和认证适配能力提升了多区域部署与代码场景专用模型调用的灵活性。 \
**Feature Value**: 用户可根据部署区域灵活切换ZhipuAI服务端点启用代码规划模式可获得更优的编程辅助响应思考模式支持进一步提升复杂推理任务效果增强AI代理在开发场景下的实用性与适应性。
- **Related PR**: [#3482](https://github.com/alibaba/higress/pull/3482) \
**Contributor**: @johnlanni \
**Change Log**: 优化OSS技能同步工作流将每个技能目录独立打包为ZIP文件如my-skill.zip并上传至oss://higress-ai/skills/同时保持AI网关安装脚本的兼容性。 \
**Feature Value**: 用户可按需单独下载和部署特定技能,提升技能分发灵活性与复用效率;避免全量拉取技能包,降低带宽消耗和部署时间,增强边缘场景适配能力。
- **Related PR**: [#3481](https://github.com/alibaba/higress/pull/3481) \
**Contributor**: @johnlanni \
**Change Log**: 新增GitHub Action工作流监听.main分支上.claude/skills目录的变更自动触发同步至OSS对象存储实现技能文件的实时、自动化云端备份与分发。 \
**Feature Value**: 用户无需手动上传技能文件,提升开发协作效率;确保技能版本一致性与高可用性,便于团队共享与快速部署,降低运维成本和人为失误风险。
- **Related PR**: [#3479](https://github.com/alibaba/higress/pull/3479) \
**Contributor**: @johnlanni \
**Change Log**: 新增对非OpenAI系AI提供商的兼容逻辑在chat completion请求中自动将不支持的'developer'角色转换为'system'角色通过修改provider.go文件实现统一角色映射适配。 \
**Feature Value**: 提升AI代理插件的跨平台兼容性使开发者在使用Claude、Anthropic等不支持developer角色的厂商API时无需手动修改请求降低集成门槛并避免运行时错误。
### 🐛 Bug修复 (Bug Fixes)
- **Related PR**: [#3667](https://github.com/alibaba/higress/pull/3667) \
**Contributor**: @wydream \
**Change Log**: 修复Claude-to-OpenAI协议转换中错误透传非标准字段thinking和reasoning_max_tokens的问题仅保留OpenAI标准字段reasoning_effort避免Azure等provider返回HTTP 400错误。 \
**Feature Value**: 提升ai-proxy对Azure等标准OpenAI兼容provider的兼容性与稳定性确保用户在使用Anthropic协议调用Azure时请求成功避免因非法字段导致服务不可用。
- **Related PR**: [#3652](https://github.com/alibaba/higress/pull/3652) \
**Contributor**: @CH3CHO \
**Change Log**: 修复了模板处理器在混合使用默认与非默认命名空间时的正则表达式匹配错误严格限制type/name/namespace中不允许出现'/'和'}'仅key允许'/'但禁止'}',确保模板引用解析的准确性。 \
**Feature Value**: 解决了因命名空间混用导致的模板解析失败问题,提升了配置加载的稳定性和可靠性,避免用户因非法字符误配而遭遇静默错误或服务异常,增强系统健壮性。
- **Related PR**: [#3599](https://github.com/alibaba/higress/pull/3599) \
**Contributor**: @wydream \
**Change Log**: 修复 Vertex Provider 流式响应中 JSON 事件跨网络分片导致的解析失败问题,通过重构 chunk 缓冲与行边界识别逻辑,确保半截 JSON 被暂存并合并解析,同时修正 [DONE] 标记提前返回导致有效数据丢失的问题。 \
**Feature Value**: 提升 Vertex 流式响应的稳定性和数据完整性,避免用户在使用大模型流式输出(如长思考链)时出现内容截断或解析错误,显著改善 AI 代理服务的可用性与用户体验。
- **Related PR**: [#3590](https://github.com/alibaba/higress/pull/3590) \
**Contributor**: @wydream \
**Change Log**: 修复 Bedrock Provider 的 SigV4 canonical URI 编码逻辑回归问题:将 encodeSigV4Path 恢复为直接 PathEscape 路径段,避免 PathUnescape 后重建导致已编码字符(如 %3A、%2F二次解析失真确保签名与 AWS 服务端一致。 \
**Feature Value**: 解决因签名失败导致的 Bedrock 模型调用频繁 403 错误,尤其影响含冒号、斜杠等特殊字符的模型名(如 nova-2-lite-v1:0 或 ARN 格式 inference-profile显著提升生产环境稳定性与 API 调用成功率。
- **Related PR**: [#3587](https://github.com/alibaba/higress/pull/3587) \
**Contributor**: @Sunrisea \
**Change Log**: 升级nacos-sdk-go/v2至v2.3.5修复了多回调场景下的取消订阅逻辑、跨集群服务多重订阅支持、内存泄漏、日志文件句柄泄漏及logger初始化回归等问题同时更新gRPC和Go依赖版本。 \
**Feature Value**: 提升Nacos客户端稳定性与可靠性避免生产环境因内存/文件句柄泄漏导致的OOM或资源耗尽增强多集群服务发现能力改善微服务在复杂拓扑下的注册发现健壮性。
- **Related PR**: [#3582](https://github.com/alibaba/higress/pull/3582) \
**Contributor**: @lx1036 \
**Change Log**: 移除了 pkg/ingress/translation/translation.go 中重复的 "istio.io/istio/pilot/pkg/model" 包导入,保留带别名的导入语句,消除了编译警告和潜在符号冲突风险,提升代码健壮性与可维护性。 \
**Feature Value**: 修复重复导入可避免 Go 编译器警告及潜在的包初始化冲突,增强代码稳定性;对用户而言,提升了 Istio Ingress 转换模块的构建可靠性与长期可维护性,降低意外错误发生概率。
- **Related PR**: [#3580](https://github.com/alibaba/higress/pull/3580) \
**Contributor**: @shiyan2016 \
**Change Log**: 修复KIngress控制器中重复路由检测逻辑缺陷将请求头匹配条件纳入去重键计算避免因Header差异导致的合法路由被错误丢弃。 \
**Feature Value**: 确保Header差异化路由能被正确识别和保留提升路由配置可靠性避免用户因误删路由导致服务不可达或流量丢失。
- **Related PR**: [#3575](https://github.com/alibaba/higress/pull/3575) \
**Contributor**: @shiyan2016 \
**Change Log**: 修复了 pkg/ingress/kube/kingress/status.go 中 updateStatus 方法的状态更新逻辑错误,修正了判断是否更新 KIngress 状态的逆向条件,避免状态同步异常;同时新增 186 行单元测试覆盖该逻辑,提升可靠性。 \
**Feature Value**: 确保 KIngress 资源的状态(如 LoadBalancerIngress能被准确、及时地更新防止因状态误判导致服务不可达或监控告警失真增强 Ingress 控制器的稳定性和可观测性。
- **Related PR**: [#3567](https://github.com/alibaba/higress/pull/3567) \
**Contributor**: @DamosChen \
**Change Log**: 修复高负载下SSE连接偶发丢失endpoint握手事件的问题将原本依赖Redis Pub/Sub的事件发送改为通过本地goroutine异步调用InjectData直写SSE响应流规避subscribe goroutine启动延迟与时序竞争。 \
**Feature Value**: 提升SSE建连可靠性确保所有客户端在高负载或CPU受限场景下均能稳定收到endpoint事件避免因握手失败导致的会话初始化异常和功能不可用改善用户体验和系统健壮性。
- **Related PR**: [#3549](https://github.com/alibaba/higress/pull/3549) \
**Contributor**: @wydream \
**Change Log**: 修复了ai-proxy插件Bedrock Provider在AWS AK/SK鉴权模式下SigV4签名覆盖不全的问题将setAuthHeaders调用从分散的请求处理函数统一收口至TransformRequestBodyHeaders入口确保所有Bedrock API含embeddings等扩展能力均经过完整SigV4签名流程。 \
**Feature Value**: 解决了因部分API缺失SigV4签名导致的AWS鉴权失败问题提升Bedrock Provider在多能力场景下的稳定性和兼容性使用户能可靠使用各类Bedrock服务如embedding、converse等而无需担心认证异常。
- **Related PR**: [#3530](https://github.com/alibaba/higress/pull/3530) \
**Contributor**: @Jing-ze \
**Change Log**: 修复Qwen提供程序的Anthropic兼容API消息端点路径将旧路径/api/v2/apps/claude-code-proxy/v1/messages更新为官方新路径/apps/anthropic/v1/messages确保与Bailian Anthropic API兼容文档一致。 \
**Feature Value**: 使AI代理能正确调用Qwen的Anthropic兼容接口避免因路径过期导致的消息请求失败提升服务稳定性与兼容性用户无需修改代码即可无缝对接最新API。
- **Related PR**: [#3517](https://github.com/alibaba/higress/pull/3517) \
**Contributor**: @johnlanni \
**Change Log**: 修复了OpenAI协议中tool角色消息在转换为Claude协议时未正确映射的问题新增逻辑将OpenAI的tool角色消息转换为Claude兼容的user角色并嵌入tool_result内容确保请求格式符合Claude API规范。 \
**Feature Value**: 使AI代理能正确转发含工具调用结果的OpenAI请求至Claude模型避免API拒绝错误提升多模型协议兼容性与用户使用稳定性用户无需修改现有工具调用逻辑即可无缝切换后端模型。
- **Related PR**: [#3513](https://github.com/alibaba/higress/pull/3513) \
**Contributor**: @johnlanni \
**Change Log**: 修复轻量模式下AI统计插件未包含question和model字段的问题调整请求阶段属性提取逻辑在不缓冲响应体前提下提前提取关键字段并更新默认属性配置。 \
**Feature Value**: 使轻量模式下的AI可观测性数据更完整准确用户可获取问题内容与模型信息用于分析提升调试效率与统计维度完整性同时保持低开销特性。
- **Related PR**: [#3510](https://github.com/alibaba/higress/pull/3510) \
**Contributor**: @johnlanni \
**Change Log**: 修复Claude协议转换中message_delta事件delta对象错误嵌套type字段的问题修正claude.go结构体定义、更新claude_to_openai.go转换逻辑并同步调整测试用例和模型配置结构。 \
**Feature Value**: 确保AI代理在对接ZhipuAI等OpenAI兼容服务时正确遵循Claude协议规范避免因格式错误导致的消息解析失败或流式响应中断提升多模型服务的稳定性和兼容性。
- **Related PR**: [#3507](https://github.com/alibaba/higress/pull/3507) \
**Contributor**: @johnlanni \
**Change Log**: 修复Claude AI代理在OpenAI兼容流式响应中缺失tool_calls数据的问题新增对thinking内容的正确解析与转换并实现OpenAI reasoning_effort参数到Claude thinking.budget_tokens的映射。 \
**Feature Value**: 使用户在使用Claude作为后端时能完整获取流式响应中的工具调用信息和推理过程内容提升多步骤AI工作流的可靠性与可调试性增强OpenAI兼容层的实用性。
- **Related PR**: [#3506](https://github.com/alibaba/higress/pull/3506) \
**Contributor**: @johnlanni \
**Change Log**: 修复Claude API响应中stop_reason为'tool_use'时未正确转换为OpenAI兼容的tool_calls格式的问题统一处理非流式和流式响应补充缺失的tool_calls数组及finish_reason映射。 \
**Feature Value**: 使ai-proxy插件能正确透传Claude的工具调用响应给OpenAI客户端提升多模型代理的兼容性与稳定性避免下游应用因格式不匹配导致解析失败或功能异常。
- **Related PR**: [#3505](https://github.com/alibaba/higress/pull/3505) \
**Contributor**: @johnlanni \
**Change Log**: 修复流式响应中answer字段提取失败的问题当启用use_default_attributes时因默认Rule为空导致extractStreamingBodyByJsonPath返回nil现将BuiltinAnswerKey的Rule默认设为RuleAppend确保流式内容能正确拼接提取。 \
**Feature Value**: 用户在使用AI流式响应统计功能时能稳定获取answer字段内容避免ai_log中response_type为stream却缺失answer的问题提升观测数据完整性和调试效率。
- **Related PR**: [#3503](https://github.com/alibaba/higress/pull/3503) \
**Contributor**: @johnlanni \
**Change Log**: 修复Claude协议中同时包含tool_result和text内容时文本内容在转换为OpenAI格式时被丢弃的问题在claude_to_openai.go中新增逻辑保留text content并补充对应测试用例验证多类型content共存场景。 \
**Feature Value**: 确保Claude Code等工具调用场景下用户输入的文本消息不丢失提升AI代理对混合内容消息的兼容性与可靠性改善开发者在复杂交互流程中的体验与调试效率。
- **Related PR**: [#3502](https://github.com/alibaba/higress/pull/3502) \
**Contributor**: @johnlanni \
**Change Log**: 修复Claude流式响应中SSE格式缺失event字段的问题在[DONE]消息处理时补充了event: message_delta和event: message_stop等必要事件标识确保与Claude官方流式协议完全兼容。 \
**Feature Value**: 使AI代理能正确解析Claude模型的流式响应避免前端因格式错误导致的消息丢失或解析失败提升多模型统一接入的稳定性与用户体验。
- **Related PR**: [#3500](https://github.com/alibaba/higress/pull/3500) \
**Contributor**: @johnlanni \
**Change Log**: 将GitHub Actions工作流中的运行环境从ubuntu-latest统一固定为ubuntu-22.04解决了因底层镜像升级导致kind集群容器镜像加载失败ctr images import错误的CI稳定性问题。 \
**Feature Value**: 修复了higress-conformance-test等关键CI任务持续失败的问题保障了代码合入流程的可靠性与自动化验证能力避免开发者因CI误报阻塞开发进度。
- **Related PR**: [#3496](https://github.com/alibaba/higress/pull/3496) \
**Contributor**: @johnlanni \
**Change Log**: 修复了Claude Code模式下system prompt中空Content字段被序列化为null的问题通过调整claudeChatMessageContent结构体的JSON标签使空content字段正确省略而非输出null避免API请求被拒绝。 \
**Feature Value**: 解决了AI代理调用Claude API时因无效system字段导致的请求失败问题提升系统稳定性与兼容性确保用户在使用Claude Code模式时能正常接收响应无需手动规避空内容场景。
- **Related PR**: [#3491](https://github.com/alibaba/higress/pull/3491) \
**Contributor**: @johnlanni \
**Change Log**: 修复了AI统计插件中流式响应body缓冲失效的问题通过为内置属性显式设置ValueSource=ResponseStreamingBody确保use_default_attributes启用时answer字段能被正确提取并记录到ai_log中。 \
**Feature Value**: 用户启用默认属性采集时, now 能准确捕获和记录流式AI响应的answer内容提升日志可观测性与调试能力避免关键响应数据丢失导致的分析盲区。
- **Related PR**: [#3485](https://github.com/alibaba/higress/pull/3485) \
**Contributor**: @johnlanni \
**Change Log**: 修复了 Higress 提供商模型引用前缀逻辑错误,移除了条件判断,统一为所有模型 ID包括 higress/auto强制添加 'higress/' 前缀,确保 OpenClaw 集成插件生成的配置中模型引用格式正确。 \
**Feature Value**: 解决了因模型引用前缀缺失导致的配置解析失败问题,提升 Higress 与 OpenClaw 集成的稳定性与兼容性,使用户能正确使用 higress/auto 等自动模型而无需手动修正配置。
- **Related PR**: [#3484](https://github.com/alibaba/higress/pull/3484) \
**Contributor**: @johnlanni \
**Change Log**: 修复higress-openclaw-integration技能的安装路径问题新增mkdir -p higress-install和cd higress-install命令并将日志路径从./higress/logs/access.log更新为./higress-install/logs/access.log避免污染当前工作目录。 \
**Feature Value**: 使Higress安装文件隔离在专用目录中提升工作区整洁性用户可轻松清理或重装降低环境冲突风险增强技能部署的可靠性和可维护性。
- **Related PR**: [#3483](https://github.com/alibaba/higress/pull/3483) \
**Contributor**: @johnlanni \
**Change Log**: 修复技能打包工作流中的路径解析问题,改用绝对路径(基于$GITHUB_WORKSPACE替代易出错的相对路径并通过子shell避免目录切换同时增加输出目录存在性检查提升CI健壮性。 \
**Feature Value**: 确保技能打包流程在任意子目录执行时均能稳定生成ZIP包避免因路径错误导致的构建失败提升OSS技能同步可靠性与开发者协作效率。
- **Related PR**: [#3477](https://github.com/alibaba/higress/pull/3477) \
**Contributor**: @johnlanni \
**Change Log**: 修复OpenClaw插件中baseUrl重复拼接/v1路径的问题移除了testGatewayConnection等函数中手动添加的/v1避免生成如http://localhost:8080/v1/v1的非法URL确保网关请求路径正确性。 \
**Feature Value**: 解决因重复路径导致的API调用失败问题提升插件连接稳定性与兼容性用户无需手动调整URL即可正常使用模型服务降低部署和调试门槛。
### ♻️ 重构优化 (Refactoring)
- **Related PR**: [#3657](https://github.com/alibaba/higress/pull/3657) \
**Contributor**: @CH3CHO \
**Change Log**: 移除了Helm Chart中higress-core/values.yaml里未使用的pilot配置项如autoscaleEnabled、replicaCount等共29行并同步更新了README.md中的参数说明精简了配置文件提升了Chart的可维护性和清晰度。 \
**Feature Value**: 减少用户配置混淆风险避免因残留废弃参数导致部署异常简化Chart结构降低运维复杂度提升升级和定制化效率使用户更聚焦于实际需配置的核心参数。
- **Related PR**: [#3516](https://github.com/alibaba/higress/pull/3516) \
**Contributor**: @johnlanni \
**Change Log**: 将MCP SDK从外部仓库迁移到主仓库移动mcp-servers/all-in-one至extensions/mcp-server引入pkg/mcp包删除已废弃的pkg/log等模块并统一更新所有MCP导入路径和依赖引用。 \
**Feature Value**: 提升代码可维护性与构建一致性避免跨仓库依赖问题用户可更稳定地使用MCP相关功能插件开发和调试效率显著提高同时为后续MCP能力扩展奠定统一基础。
- **Related PR**: [#3475](https://github.com/alibaba/higress/pull/3475) \
**Contributor**: @johnlanni \
**Change Log**: 将技能名称从higress-clawdbot-integration重命名为higress-openclaw-integration移除已弃用的agent-session-monitor文档内容并同步更新多个脚本中的模型ID如claude-opus-4.5→4.6、gpt-5.2→5.3-codex确保配置一致性与命名准确性。 \
**Feature Value**: 提升项目命名规范性与可维护性避免因旧名称引发的混淆更新模型ID支持最新大模型版本使用户能无缝对接更高性能、更稳定的新模型能力增强AI网关集成体验。
### 📚 文档更新 (Documentation)
- **Related PR**: [#3644](https://github.com/alibaba/higress/pull/3644) \
**Contributor**: @Jholly2008 \
**Change Log**: 该PR修复了README.md和docs/architecture.md中两处失效的higress.io链接分别替换了英文README中的Quick Start链接和architecture文档中的Admin SDK博客链接确保文档链接的准确性和可访问性。 \
**Feature Value**: 提升了文档的可用性和用户体验,避免用户点击无效链接导致信息获取中断;保障新用户快速上手和开发者查阅架构资料的顺畅性,增强项目专业形象和可信度。
- **Related PR**: [#3524](https://github.com/alibaba/higress/pull/3524) \
**Contributor**: @github-actions[bot] \
**Change Log**: 该PR新增了2.1.11版本的中英文Release Notes文档包含发布概览、更新分布统计4项新功能、2项Bug修复及完整变更日志结构由GitHub Actions自动生成并维护确保版本信息可追溯、可查阅。 \
**Feature Value**: 为用户提供清晰、结构化的版本升级参考,帮助用户快速了解新功能、修复项及兼容性变化,提升产品透明度与使用体验,降低升级风险和学习成本。
- **Related PR**: [#3490](https://github.com/alibaba/higress/pull/3490) \
**Contributor**: @johnlanni \
**Change Log**: 优化OpenClaw集成技能文档中的模型提供商列表将智谱、Claude Code、Moonshot等8个常用提供商置顶展示并将低频提供商折叠为可展开区域提升文档可读性与信息层级清晰度。 \
**Feature Value**: 显著改善新用户配置Higress AI Gateway的体验降低学习成本通过结构化呈现提供商选项帮助用户快速识别主流支持模型提升OpenClaw技能的易用性与落地效率。
- **Related PR**: [#3480](https://github.com/alibaba/higress/pull/3480) \
**Contributor**: @johnlanni \
**Change Log**: 更新了OpenClaw集成文档SKILL.md新增动态配置更新说明涵盖LLM提供商热添加、API密钥在线更新、多模型自动路由机制并在插件提示中加入配置更新引导提示。 \
**Feature Value**: 帮助用户理解无需重启即可动态扩展和更新AI服务配置降低运维门槛提升多模型切换与管理灵活性增强产品易用性与企业级配置治理能力。
- **Related PR**: [#3478](https://github.com/alibaba/higress/pull/3478) \
**Contributor**: @johnlanni \
**Change Log**: 在SKILL.md文档中明确标注OpenClaw的higress插件相关命令为交互式操作添加警告提示并分离出需用户手动执行的命令步骤避免AI代理误执行失败。 \
**Feature Value**: 帮助用户清晰识别哪些命令必须人工介入执行提升集成流程的可预测性和成功率同时减少因AI代理尝试执行交互命令导致的操作失败和调试成本。
- **Related PR**: [#3476](https://github.com/alibaba/higress/pull/3476) \
**Contributor**: @johnlanni \
**Change Log**: 重构了higress-openclaw-integration技能文档将部署流程从6步简化为3步前置收集全部必要信息新增21+模型提供商对照表明确各provider的模型前缀模式及Claude所需的OAuth令牌说明。 \
**Feature Value**: 显著提升AI代理尤其是能力较弱的模型调用该技能的成功率与稳定性降低用户理解和使用门槛减少因步骤繁琐或信息缺失导致的配置错误加快Higress AI网关在OpenClaw生态中的落地效率。
- **Related PR**: [#3468](https://github.com/alibaba/higress/pull/3468) \
**Contributor**: @github-actions[bot] \
**Change Log**: 该PR新增了2.2.0版本的中英文 release notes包含发布概览、更新分布统计48项新功能、20项Bug修复等及完整变更日志由GitHub Actions自动生成确保版本信息权威、及时、双语可用。 \
**Feature Value**: 为用户和开发者提供清晰、结构化的版本升级参考,降低使用门槛与迁移成本;中英文同步支持提升国际用户可访问性,增强项目专业形象与社区信任度。
---
## 📊 发布统计
- 🚀 新功能: 29项
- 🐛 Bug修复: 26项
- ♻️ 重构优化: 3项
- 📚 文档更新: 7项
**总计**: 65项更改
感谢所有贡献者的辛勤付出!🎉
# Higress Console
## 📋 本次发布概览
本次发布包含 **18** 项更新涵盖了功能增强、Bug修复、性能优化等多个方面。
### 更新内容分布
- **新功能**: 7项
- **Bug修复**: 9项
- **文档更新**: 2项
---
## 📝 完整变更日志
### 🚀 新功能 (Features)
- **Related PR**: [#621](https://github.com/higress-group/higress-console/pull/621) \
**Contributor**: @Thomas-Eliot \
**Change Log**: 优化MCP Server交互能力支持DNS后端自动重写Host头增强直接路由场景的传输协议选择与完整路径配置改进DB到MCP Server场景的DSN特殊字符如@)解析能力。 \
**Feature Value**: 提升MCP Server接入灵活性与兼容性降低用户配置复杂度避免因路径前缀歧义或DSN特殊字符导致的连接失败显著改善多环境部署体验和系统稳定性。
- **Related PR**: [#608](https://github.com/higress-group/higress-console/pull/608) \
**Contributor**: @Libres-coder \
**Change Log**: 为AI路由管理页面新增插件显示功能支持展开查看已启用插件及配置页中显示'Enabled'标签复用常规路由的插件展示逻辑涉及前端AI路由组件、插件列表查询逻辑及路由页面初始化优化。 \
**Feature Value**: 用户可在AI路由管理界面直观查看和确认已启用的插件提升AI路由配置的可观察性与操作一致性降低误配风险增强平台统一管理体验和运维效率。
- **Related PR**: [#604](https://github.com/higress-group/higress-console/pull/604) \
**Contributor**: @CH3CHO \
**Change Log**: 新增对正则表达式路径重写的支撑通过higress.io/rewrite-target注解实现扩展Kubernetes注解常量、更新路由转换逻辑、增加正则重写类型枚举及前端多语言支持。 \
**Feature Value**: 用户可通过正则表达式灵活定义路径重写规则提升路由匹配精度与灵活性适用于复杂URL变换场景降低网关配置门槛并增强业务适配能力。
- **Related PR**: [#603](https://github.com/higress-group/higress-console/pull/603) \
**Contributor**: @CH3CHO \
**Change Log**: 在静态服务源表单组件中新增常量STATIC_SERVICE_PORT = 80并在UI中显式展示该固定端口使用户清晰了解静态服务默认绑定的HTTP端口提升配置透明度与可理解性。 \
**Feature Value**: 用户在配置静态服务源时能直观看到默认端口80避免因端口认知偏差导致的服务访问失败降低运维门槛提升部署效率与用户体验一致性。
- **Related PR**: [#602](https://github.com/higress-group/higress-console/pull/602) \
**Contributor**: @CH3CHO \
**Change Log**: 在AI路由的上游服务选择组件中新增搜索功能通过前端输入过滤服务列表提升长列表场景下的选择效率仅修改RouteForm组件少量代码实现交互增强。 \
**Feature Value**: 用户在配置AI路由时可快速搜索并定位目标上游服务显著改善服务数量较多时的使用体验降低配置错误率提高运维和开发效率。
- **Related PR**: [#566](https://github.com/higress-group/higress-console/pull/566) \
**Contributor**: @OuterCyrex \
**Change Log**: 新增通义千问Qwen大模型服务支持包含独立的QwenLlmProviderHandler实现前端多语言适配及配置表单支持自定义服务地址、互联网搜索、文件ID上传等能力。 \
**Feature Value**: 用户可灵活接入私有化或定制化Qwen服务提升AI网关对国产大模型的兼容性通过配置界面简化部署流程降低企业级AI服务集成门槛增强平台扩展能力。
- **Related PR**: [#552](https://github.com/higress-group/higress-console/pull/552) \
**Contributor**: @lcfang \
**Change Log**: 新增vport属性支持扩展MCP Bridge注册中心配置能力在ServiceSource中引入VPort类增强Kubernetes模型转换逻辑使服务虚拟端口可配置化解决Eureka/Nacos等注册中心后端实例端口动态变化导致路由失效问题。 \
**Feature Value**: 用户可在注册中心配置中指定服务虚拟端口vport确保后端端口变更时路由规则仍有效提升服务治理稳定性与兼容性降低因端口不一致引发的流量转发异常风险简化多环境部署运维复杂度。
### 🐛 Bug修复 (Bug Fixes)
- **Related PR**: [#620](https://github.com/higress-group/higress-console/pull/620) \
**Contributor**: @CH3CHO \
**Change Log**: 修复了sortWasmPluginMatchRules逻辑中的拼写错误修正了匹配规则排序时因变量名或方法名误写导致的潜在逻辑异常确保Wasm插件规则按预期优先级正确排序。 \
**Feature Value**: 避免因拼写错误引发的匹配规则排序错误保障Wasm插件在Kubernetes CR中生效顺序的准确性提升插件路由与策略执行的可靠性减少用户配置后行为不符合预期的问题。
- **Related PR**: [#619](https://github.com/higress-group/higress-console/pull/619) \
**Contributor**: @CH3CHO \
**Change Log**: 修复了AiRoute转换为ConfigMap时重复存储版本信息的问题从data JSON中移除version字段仅保留在ConfigMap metadata中避免数据冗余和潜在不一致。 \
**Feature Value**: 提升了配置管理的准确性和一致性防止因版本信息重复导致的解析错误或同步异常增强系统稳定性和运维可靠性对使用Kubernetes ConfigMap管理路由配置的用户有直接收益。
- **Related PR**: [#618](https://github.com/higress-group/higress-console/pull/618) \
**Contributor**: @CH3CHO \
**Change Log**: 重构SystemController的API认证逻辑引入AllowAnonymous注解机制统一处理免认证接口移除硬编码的路径白名单通过AOP切面实现细粒度访问控制修复了未授权用户可能访问敏感系统接口的安全漏洞。 \
**Feature Value**: 修复了系统控制器中潜在的未授权访问安全漏洞,显著提升平台安全性;用户将获得更可靠的权限保障,避免因认证逻辑缺陷导致的数据泄露或越权操作风险,增强生产环境的合规性与稳定性。
- **Related PR**: [#617](https://github.com/higress-group/higress-console/pull/617) \
**Contributor**: @CH3CHO \
**Change Log**: 修复了前端控制台三个关键错误列表渲染缺少唯一key导致的React警告、CSP策略阻止远程图片加载问题以及Consumer.name字段类型定义错误由boolean修正为string。 \
**Feature Value**: 提升前端应用稳定性与用户体验,避免控制台报错干扰开发调试,确保用户头像正常显示及消费者信息正确解析,防止因类型错误引发的运行时异常或数据展示问题。
- **Related PR**: [#614](https://github.com/higress-group/higress-console/pull/614) \
**Contributor**: @lc0138 \
**Change Log**: 修正了ServiceSource类中服务来源type字段的类型定义增加了对字典值的校验逻辑确保传入的注册中心类型在预定义集合内防止非法值导致运行时异常。 \
**Feature Value**: 提升了系统健壮性与数据一致性,避免因错误的服务来源类型引发配置解析失败或后台异常,保障用户服务注册与发现功能稳定可靠,降低运维排查成本。
- **Related PR**: [#613](https://github.com/higress-group/higress-console/pull/613) \
**Contributor**: @lc0138 \
**Change Log**: 修复前端Content Security PolicyCSP配置缺陷通过在document.tsx中新增关键meta标签和安全策略声明防止XSS等恶意脚本注入提升页面加载时的安全头控制能力。 \
**Feature Value**: 显著降低前端应用遭受跨站脚本攻击XSS和数据注入的风险增强用户访问安全性与信任度符合现代Web安全最佳实践为生产环境提供更可靠的安全保障。
- **Related PR**: [#612](https://github.com/higress-group/higress-console/pull/612) \
**Contributor**: @zhwaaaaaa \
**Change Log**: 在DashboardServiceImpl中新增对hop-to-hop头部如Transfer-Encoding的忽略逻辑依据RFC 2616规范过滤代理转发时不应透传的逐跳头部避免因反向代理携带chunked编码头导致Grafana页面无法正常加载。 \
**Feature Value**: 修复了反向代理转发时携带Transfer-Encoding: chunked头导致Grafana前端页面崩溃的问题提升了控制台集成外部监控服务的稳定性和兼容性用户可无缝访问仪表盘功能。
- **Related PR**: [#609](https://github.com/higress-group/higress-console/pull/609) \
**Contributor**: @CH3CHO \
**Change Log**: 修复了Consumer接口中name字段的类型错误将其从boolean更正为string确保前端数据结构与后端实际返回值一致避免运行时类型错误和UI渲染异常。 \
**Feature Value**: 提升了消费者信息展示的准确性和稳定性,防止因类型不匹配导致的页面崩溃或数据显示错误,改善了用户在管理消费者时的操作体验和系统可靠性。
- **Related PR**: [#605](https://github.com/higress-group/higress-console/pull/605) \
**Contributor**: @SaladDay \
**Change Log**: 修正AI路由名称的前端表单验证正则表达式新增对点号(.)的支持,同时将字母限制从大小写改为仅小写,并同步更新中英文错误提示文案以准确反映新规则。 \
**Feature Value**: 解决了用户在创建AI路由时因名称含点号或大写字母被误拒的问题提升表单验证逻辑与UI提示的一致性降低用户配置失败率改善整体使用体验。
### 📚 文档更新 (Documentation)
- **Related PR**: [#611](https://github.com/higress-group/higress-console/pull/611) \
**Contributor**: @qshuai \
**Change Log**: 修复了LlmProvidersController中@PostMapping接口的OpenAPI文档摘要注释,将错误的'Add a new route'更正为更准确的描述确保API文档与实际功能一致。 \
**Feature Value**: 提升API文档准确性帮助开发者正确理解该接口用途应为添加LLM提供商而非路由减少集成误解和调试成本增强控制台API的可维护性与用户体验。
- **Related PR**: [#610](https://github.com/higress-group/higress-console/pull/610) \
**Contributor**: @heimanba \
**Change Log**: 更新前端灰度插件文档将rewrite、backendVersion、enabled字段调整为非必填并修正rules中name字段的关联路径从deploy.gray[].name改为grayDeployments[].name同步更新中英文README及spec.yaml中的字段描述与要求。 \
**Feature Value**: 提升配置灵活性与兼容性,降低用户接入灰度能力的门槛;术语和路径说明更准确,减少因文档歧义导致的配置错误,增强开发者体验和文档可信度。
---
## 📊 发布统计
- 🚀 新功能: 7项
- 🐛 Bug修复: 9项
- 📚 文档更新: 2项
**总计**: 18项更改
感谢所有贡献者的辛勤付出!🎉