feat: support for wanxiang image/video generation in ai-proxy & ai-statistics (#2378)

This commit is contained in:
mirror
2025-06-16 09:39:37 +08:00
committed by GitHub
parent de8a4d0b03
commit 7040e4bd34
5 changed files with 47 additions and 19 deletions

View File

@@ -61,6 +61,8 @@ const (
// TODO: 以下是一些非标准的API名称需要进一步确认是否支持
ApiNameCohereV1Rerank ApiName = "cohere/v1/rerank"
ApiNameQwenAsyncAIGC ApiName = "api/v1/services/aigc"
ApiNameQwenAsyncTask ApiName = "api/v1/tasks/"
providerTypeMoonshot = "moonshot"
providerTypeAzure = "azure"

View File

@@ -37,6 +37,9 @@ const (
qwenBailianPath = "/api/v1/apps"
qwenMultimodalGenerationPath = "/api/v1/services/aigc/multimodal-generation/generation"
qwenAsyncAIGCPath = "/api/v1/services/aigc/"
qwenAsyncTaskPath = "/api/v1/tasks/"
qwenTopPMin = 0.000001
qwenTopPMax = 0.999999
@@ -74,6 +77,8 @@ func (m *qwenProviderInitializer) DefaultCapabilities(qwenEnableCompatible bool)
return map[string]string{
string(ApiNameChatCompletion): qwenChatCompletionPath,
string(ApiNameEmbeddings): qwenTextEmbeddingPath,
string(ApiNameQwenAsyncAIGC): qwenAsyncAIGCPath,
string(ApiNameQwenAsyncTask): qwenAsyncTaskPath,
}
}
}
@@ -689,6 +694,10 @@ func (m *qwenProvider) GetApiName(path string) ApiName {
case strings.Contains(path, qwenTextEmbeddingPath),
strings.Contains(path, qwenCompatibleTextEmbeddingPath):
return ApiNameEmbeddings
case strings.Contains(path, qwenAsyncAIGCPath):
return ApiNameQwenAsyncAIGC
case strings.Contains(path, qwenAsyncTaskPath):
return ApiNameQwenAsyncTask
default:
return ""
}

View File

@@ -23,6 +23,7 @@ description: AI可观测配置参考
| 名称 | 数据类型 | 填写要求 | 默认值 | 描述 |
|----------------|-------|------|-----|------------------------|
| `attributes` | []Attribute | 非必填 | - | 用户希望记录在log/span中的信息 |
| `disable_openai_usage` | bool | 非必填 | false | 非openai兼容协议时model、token的支持非标配置为true时可以避免报错 |
Attribute 配置说明:

View File

@@ -22,7 +22,8 @@ Users can also expand observable values through configuration:
| Name | Type | Required | Default | Description |
|----------------|-------|------|-----|------------------------|
| `attributes` | []Attribute | required | - | Information that the user wants to record in log/span |
| `attributes` | []Attribute | optional | - | Information that the user wants to record in log/span |
| `disable_openai_usage` | bool | optional | false | When using a non-OpenAI-compatible protocol, the support for model and token is non-standard. Setting the configuration to true can prevent errors. |
Attribute Configuration instructions:

View File

@@ -92,6 +92,8 @@ type AIStatisticsConfig struct {
attributes []Attribute
// If there exist attributes extracted from streaming body, chunks should be buffered
shouldBufferStreamingBody bool
// If disableOpenaiUsage is true, model/input_token/output_token logs will be skipped
disableOpenaiUsage bool
}
func generateMetricName(route, cluster, model, consumer, metricName string) string {
@@ -160,6 +162,10 @@ func parseConfig(configJson gjson.Result, config *AIStatisticsConfig, log wrappe
}
// Metric settings
config.counterMetrics = make(map[string]proxywasm.MetricCounter)
// Parse openai usage config setting.
config.disableOpenaiUsage = configJson.Get("disable_openai_usage").Bool()
return nil
}
@@ -264,15 +270,17 @@ func onHttpStreamingBody(ctx wrapper.HttpContext, config AIStatisticsConfig, dat
}
// Set information about this request
if model, inputToken, outputToken, ok := getUsage(data); ok {
ctx.SetUserAttribute(Model, model)
ctx.SetUserAttribute(InputToken, inputToken)
ctx.SetUserAttribute(OutputToken, outputToken)
// Set span attributes for ARMS.
setSpanAttribute(ArmsModelName, model, log)
setSpanAttribute(ArmsInputToken, inputToken, log)
setSpanAttribute(ArmsOutputToken, outputToken, log)
setSpanAttribute(ArmsTotalToken, inputToken+outputToken, log)
if !config.disableOpenaiUsage {
if model, inputToken, outputToken, ok := getUsage(data); ok {
ctx.SetUserAttribute(Model, model)
ctx.SetUserAttribute(InputToken, inputToken)
ctx.SetUserAttribute(OutputToken, outputToken)
// Set span attributes for ARMS.
setSpanAttribute(ArmsModelName, model, log)
setSpanAttribute(ArmsInputToken, inputToken, log)
setSpanAttribute(ArmsOutputToken, outputToken, log)
setSpanAttribute(ArmsTotalToken, inputToken+outputToken, log)
}
}
// If the end of the stream is reached, record metrics/logs/spans.
if endOfStream {
@@ -311,15 +319,17 @@ func onHttpResponseBody(ctx wrapper.HttpContext, config AIStatisticsConfig, body
}
// Set information about this request
if model, inputToken, outputToken, ok := getUsage(body); ok {
ctx.SetUserAttribute(Model, model)
ctx.SetUserAttribute(InputToken, inputToken)
ctx.SetUserAttribute(OutputToken, outputToken)
// Set span attributes for ARMS.
setSpanAttribute(ArmsModelName, model, log)
setSpanAttribute(ArmsInputToken, inputToken, log)
setSpanAttribute(ArmsOutputToken, outputToken, log)
setSpanAttribute(ArmsTotalToken, inputToken+outputToken, log)
if !config.disableOpenaiUsage {
if model, inputToken, outputToken, ok := getUsage(body); ok {
ctx.SetUserAttribute(Model, model)
ctx.SetUserAttribute(InputToken, inputToken)
ctx.SetUserAttribute(OutputToken, outputToken)
// Set span attributes for ARMS.
setSpanAttribute(ArmsModelName, model, log)
setSpanAttribute(ArmsInputToken, inputToken, log)
setSpanAttribute(ArmsOutputToken, outputToken, log)
setSpanAttribute(ArmsTotalToken, inputToken+outputToken, log)
}
}
// Set user defined log & span attributes.
@@ -471,6 +481,11 @@ func writeMetric(ctx wrapper.HttpContext, config AIStatisticsConfig, log wrapper
log.Warnf("ClusterName typd assert failed, skip metric record")
return
}
if config.disableOpenaiUsage {
return
}
if ctx.GetUserAttribute(Model) == nil || ctx.GetUserAttribute(InputToken) == nil || ctx.GetUserAttribute(OutputToken) == nil {
log.Warnf("get usage information failed, skip metric record")
return