feat: support openai websearch models

This commit is contained in:
Laisky.Cai
2025-03-13 03:37:38 +00:00
parent 6e634b85cf
commit 413fcde382
10 changed files with 341 additions and 120 deletions

View File

@@ -1,15 +1,17 @@
package openai
import (
"errors"
"fmt"
"io"
"math"
"net/http"
"strings"
"github.com/gin-gonic/gin"
"github.com/pkg/errors"
"github.com/songquanpeng/one-api/common/config"
"github.com/songquanpeng/one-api/common/ctxkey"
"github.com/songquanpeng/one-api/common/logger"
"github.com/songquanpeng/one-api/relay/adaptor"
"github.com/songquanpeng/one-api/relay/adaptor/alibailian"
@@ -19,6 +21,7 @@ import (
"github.com/songquanpeng/one-api/relay/adaptor/minimax"
"github.com/songquanpeng/one-api/relay/adaptor/novita"
"github.com/songquanpeng/one-api/relay/adaptor/openrouter"
"github.com/songquanpeng/one-api/relay/billing/ratio"
"github.com/songquanpeng/one-api/relay/channeltype"
"github.com/songquanpeng/one-api/relay/meta"
"github.com/songquanpeng/one-api/relay/model"
@@ -127,11 +130,16 @@ func (a *Adaptor) ConvertImageRequest(request *model.ImageRequest) (any, error)
return request, nil
}
func (a *Adaptor) DoRequest(c *gin.Context, meta *meta.Meta, requestBody io.Reader) (*http.Response, error) {
func (a *Adaptor) DoRequest(c *gin.Context,
meta *meta.Meta,
requestBody io.Reader) (*http.Response, error) {
return adaptor.DoRequestHelper(a, c, meta, requestBody)
}
func (a *Adaptor) DoResponse(c *gin.Context, resp *http.Response, meta *meta.Meta) (usage *model.Usage, err *model.ErrorWithStatusCode) {
func (a *Adaptor) DoResponse(c *gin.Context,
resp *http.Response,
meta *meta.Meta) (usage *model.Usage,
err *model.ErrorWithStatusCode) {
if meta.IsStream {
var responseText string
err, responseText, usage = StreamHandler(c, resp, meta.Mode)
@@ -150,6 +158,53 @@ func (a *Adaptor) DoResponse(c *gin.Context, resp *http.Response, meta *meta.Met
err, usage = Handler(c, resp, meta.PromptTokens, meta.ActualModelName)
}
}
// -------------------------------------
// calculate web-search tool cost
// -------------------------------------
searchContextSize := "medium"
var req *model.GeneralOpenAIRequest
if vi, ok := c.Get(ctxkey.ConvertedRequest); ok {
if req, ok = vi.(*model.GeneralOpenAIRequest); ok {
if req != nil &&
req.WebSearchOptions != nil &&
req.WebSearchOptions.SearchContextSize != nil {
searchContextSize = *req.WebSearchOptions.SearchContextSize
}
switch {
case strings.HasPrefix(meta.ActualModelName, "gpt-4o-search"):
switch searchContextSize {
case "low":
usage.ToolsCost += int64(math.Ceil(30 / 1000 * ratio.USD))
case "medium":
usage.ToolsCost += int64(math.Ceil(35 / 1000 * ratio.USD))
case "high":
usage.ToolsCost += int64(math.Ceil(40 / 1000 * ratio.USD))
default:
return nil, ErrorWrapper(
errors.Errorf("invalid search context size %q", searchContextSize),
"invalid search context size: "+searchContextSize,
http.StatusBadRequest)
}
case strings.HasPrefix(meta.ActualModelName, "gpt-4o-mini-search"):
switch searchContextSize {
case "low":
usage.ToolsCost += int64(math.Ceil(25 / 1000 * ratio.USD))
case "medium":
usage.ToolsCost += int64(math.Ceil(27.5 / 1000 * ratio.USD))
case "high":
usage.ToolsCost += int64(math.Ceil(30 / 1000 * ratio.USD))
default:
return nil, ErrorWrapper(
errors.Errorf("invalid search context size %q", searchContextSize),
"invalid search context size: "+searchContextSize,
http.StatusBadRequest)
}
}
}
}
return
}