Merge branch 'main' into ui/refactor
# Conflicts: # web/src/components/ChannelsTable.js # web/src/pages/Home/index.js # web/src/pages/Playground/Playground.js
This commit is contained in:
@@ -53,6 +53,7 @@ type GeneralOpenAIRequest struct {
|
|||||||
Audio any `json:"audio,omitempty"`
|
Audio any `json:"audio,omitempty"`
|
||||||
EnableThinking any `json:"enable_thinking,omitempty"` // ali
|
EnableThinking any `json:"enable_thinking,omitempty"` // ali
|
||||||
ExtraBody any `json:"extra_body,omitempty"`
|
ExtraBody any `json:"extra_body,omitempty"`
|
||||||
|
WebSearchOptions *WebSearchOptions `json:"web_search_options,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ToolCallRequest struct {
|
type ToolCallRequest struct {
|
||||||
@@ -371,6 +372,11 @@ func (m *Message) ParseContent() []MediaContent {
|
|||||||
return contentList
|
return contentList
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type WebSearchOptions struct {
|
||||||
|
SearchContextSize string `json:"search_context_size,omitempty"`
|
||||||
|
UserLocation json.RawMessage `json:"user_location,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
type OpenAIResponsesRequest struct {
|
type OpenAIResponsesRequest struct {
|
||||||
Model string `json:"model"`
|
Model string `json:"model"`
|
||||||
Input json.RawMessage `json:"input,omitempty"`
|
Input json.RawMessage `json:"input,omitempty"`
|
||||||
|
|||||||
@@ -57,6 +57,12 @@ func (a *Adaptor) ConvertOpenAIRequest(c *gin.Context, info *relaycommon.RelayIn
|
|||||||
if request == nil {
|
if request == nil {
|
||||||
return nil, errors.New("request is nil")
|
return nil, errors.New("request is nil")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fix: ali parameter.enable_thinking must be set to false for non-streaming calls
|
||||||
|
if !info.IsStream {
|
||||||
|
request.EnableThinking = false
|
||||||
|
}
|
||||||
|
|
||||||
switch info.RelayMode {
|
switch info.RelayMode {
|
||||||
default:
|
default:
|
||||||
aliReq := requestOpenAI2Ali(*request)
|
aliReq := requestOpenAI2Ali(*request)
|
||||||
|
|||||||
@@ -47,6 +47,20 @@ func getAndValidateTextRequest(c *gin.Context, relayInfo *relaycommon.RelayInfo)
|
|||||||
if textRequest.Model == "" {
|
if textRequest.Model == "" {
|
||||||
return nil, errors.New("model is required")
|
return nil, errors.New("model is required")
|
||||||
}
|
}
|
||||||
|
if textRequest.WebSearchOptions != nil {
|
||||||
|
if textRequest.WebSearchOptions.SearchContextSize != "" {
|
||||||
|
validSizes := map[string]bool{
|
||||||
|
"high": true,
|
||||||
|
"medium": true,
|
||||||
|
"low": true,
|
||||||
|
}
|
||||||
|
if !validSizes[textRequest.WebSearchOptions.SearchContextSize] {
|
||||||
|
return nil, errors.New("invalid search_context_size, must be one of: high, medium, low")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
textRequest.WebSearchOptions.SearchContextSize = "medium"
|
||||||
|
}
|
||||||
|
}
|
||||||
switch relayInfo.RelayMode {
|
switch relayInfo.RelayMode {
|
||||||
case relayconstant.RelayModeCompletions:
|
case relayconstant.RelayModeCompletions:
|
||||||
if textRequest.Prompt == "" {
|
if textRequest.Prompt == "" {
|
||||||
@@ -76,6 +90,10 @@ func TextHelper(c *gin.Context) (openaiErr *dto.OpenAIErrorWithStatusCode) {
|
|||||||
|
|
||||||
// get & validate textRequest 获取并验证文本请求
|
// get & validate textRequest 获取并验证文本请求
|
||||||
textRequest, err := getAndValidateTextRequest(c, relayInfo)
|
textRequest, err := getAndValidateTextRequest(c, relayInfo)
|
||||||
|
if textRequest.WebSearchOptions != nil {
|
||||||
|
c.Set("chat_completion_web_search_context_size", textRequest.WebSearchOptions.SearchContextSize)
|
||||||
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
common.LogError(c, fmt.Sprintf("getAndValidateTextRequest failed: %s", err.Error()))
|
common.LogError(c, fmt.Sprintf("getAndValidateTextRequest failed: %s", err.Error()))
|
||||||
return service.OpenAIErrorWrapperLocal(err, "invalid_text_request", http.StatusBadRequest)
|
return service.OpenAIErrorWrapperLocal(err, "invalid_text_request", http.StatusBadRequest)
|
||||||
@@ -370,9 +388,20 @@ func postConsumeQuota(ctx *gin.Context, relayInfo *relaycommon.RelayInfo,
|
|||||||
dWebSearchQuota = decimal.NewFromFloat(webSearchPrice).
|
dWebSearchQuota = decimal.NewFromFloat(webSearchPrice).
|
||||||
Mul(decimal.NewFromInt(int64(webSearchTool.CallCount))).
|
Mul(decimal.NewFromInt(int64(webSearchTool.CallCount))).
|
||||||
Div(decimal.NewFromInt(1000)).Mul(dGroupRatio).Mul(dQuotaPerUnit)
|
Div(decimal.NewFromInt(1000)).Mul(dGroupRatio).Mul(dQuotaPerUnit)
|
||||||
extraContent += fmt.Sprintf("Web Search 调用 %d 次,上下文大小 %s,调用花费 $%s",
|
extraContent += fmt.Sprintf("Web Search 调用 %d 次,上下文大小 %s,调用花费 %s",
|
||||||
webSearchTool.CallCount, webSearchTool.SearchContextSize, dWebSearchQuota.String())
|
webSearchTool.CallCount, webSearchTool.SearchContextSize, dWebSearchQuota.String())
|
||||||
}
|
}
|
||||||
|
} else if strings.HasSuffix(modelName, "search-preview") {
|
||||||
|
// search-preview 模型不支持 response api
|
||||||
|
searchContextSize := ctx.GetString("chat_completion_web_search_context_size")
|
||||||
|
if searchContextSize == "" {
|
||||||
|
searchContextSize = "medium"
|
||||||
|
}
|
||||||
|
webSearchPrice = operation_setting.GetWebSearchPricePerThousand(modelName, searchContextSize)
|
||||||
|
dWebSearchQuota = decimal.NewFromFloat(webSearchPrice).
|
||||||
|
Div(decimal.NewFromInt(1000)).Mul(dGroupRatio).Mul(dQuotaPerUnit)
|
||||||
|
extraContent += fmt.Sprintf("Web Search 调用 1 次,上下文大小 %s,调用花费 %s",
|
||||||
|
searchContextSize, dWebSearchQuota.String())
|
||||||
}
|
}
|
||||||
// file search tool 计费
|
// file search tool 计费
|
||||||
var dFileSearchQuota decimal.Decimal
|
var dFileSearchQuota decimal.Decimal
|
||||||
@@ -463,10 +492,16 @@ func postConsumeQuota(ctx *gin.Context, relayInfo *relaycommon.RelayInfo,
|
|||||||
other["image_ratio"] = imageRatio
|
other["image_ratio"] = imageRatio
|
||||||
other["image_output"] = imageTokens
|
other["image_output"] = imageTokens
|
||||||
}
|
}
|
||||||
if !dWebSearchQuota.IsZero() && relayInfo.ResponsesUsageInfo != nil {
|
if !dWebSearchQuota.IsZero() {
|
||||||
if webSearchTool, exists := relayInfo.ResponsesUsageInfo.BuiltInTools[dto.BuildInToolWebSearchPreview]; exists {
|
if relayInfo.ResponsesUsageInfo != nil {
|
||||||
|
if webSearchTool, exists := relayInfo.ResponsesUsageInfo.BuiltInTools[dto.BuildInToolWebSearchPreview]; exists {
|
||||||
|
other["web_search"] = true
|
||||||
|
other["web_search_call_count"] = webSearchTool.CallCount
|
||||||
|
other["web_search_price"] = webSearchPrice
|
||||||
|
}
|
||||||
|
} else if strings.HasSuffix(modelName, "search-preview") {
|
||||||
other["web_search"] = true
|
other["web_search"] = true
|
||||||
other["web_search_call_count"] = webSearchTool.CallCount
|
other["web_search_call_count"] = 1
|
||||||
other["web_search_price"] = webSearchPrice
|
other["web_search_price"] = webSearchPrice
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user