Compare commits

..

1 Commits

Author SHA1 Message Date
抒情熊
fdd7bf41c0 feat: support multipart/form-data format request (#1690)
Some checks failed
CI / Unit tests (push) Has been cancelled
CI / commit_lint (push) Has been cancelled
* "add parser multipart/form-data"

* chore: fix impl

* chore: update impl

---------

Co-authored-by: JustSong <songquanpeng@foxmail.com>
2024-09-22 17:32:47 +08:00
10 changed files with 16 additions and 37 deletions

View File

@@ -5,16 +5,15 @@ COPY ./VERSION .
COPY ./web .
WORKDIR /web/default
RUN npm config set registry https://registry.npmmirror.com
RUN npm install
RUN DISABLE_ESLINT_PLUGIN='true' REACT_APP_VERSION=$(cat VERSION) npm run build
WORKDIR /web/berry
RUN npm install --force
RUN npm install
RUN DISABLE_ESLINT_PLUGIN='true' REACT_APP_VERSION=$(cat VERSION) npm run build
WORKDIR /web/air
RUN npm install --force
RUN npm install
RUN DISABLE_ESLINT_PLUGIN='true' REACT_APP_VERSION=$(cat VERSION) npm run build
FROM golang:alpine AS builder2
@@ -23,8 +22,7 @@ RUN apk add --no-cache g++
ENV GO111MODULE=on \
CGO_ENABLED=1 \
GOOS=linux \
GOPROXY=https://goproxy.cn,direct
GOOS=linux
WORKDIR /build
ADD go.mod go.sum ./

View File

@@ -31,15 +31,15 @@ func UnmarshalBodyReusable(c *gin.Context, v any) error {
contentType := c.Request.Header.Get("Content-Type")
if strings.HasPrefix(contentType, "application/json") {
err = json.Unmarshal(requestBody, &v)
c.Request.Body = io.NopCloser(bytes.NewBuffer(requestBody))
} else {
// skip for now
// TODO: someday non json request have variant model, we will need to implementation this
c.Request.Body = io.NopCloser(bytes.NewBuffer(requestBody))
err = c.ShouldBind(&v)
}
if err != nil {
return err
}
// Reset request body
c.Request.Body = io.NopCloser(bytes.NewBuffer(requestBody))
return nil
}

View File

@@ -12,7 +12,7 @@ import (
)
type ModelRequest struct {
Model string `json:"model"`
Model string `json:"model" form:"model"`
}
func Distribute() func(c *gin.Context) {

View File

@@ -9,7 +9,6 @@ import (
"github.com/songquanpeng/one-api/relay/model"
"io"
"net/http"
"strings"
)
type Adaptor struct {
@@ -21,18 +20,12 @@ func (a *Adaptor) Init(meta *meta.Meta) {
}
func (a *Adaptor) GetRequestURL(meta *meta.Meta) (string, error) {
baseURL := meta.BaseURL
if strings.HasSuffix(meta.APIKey, "#vip") {
baseURL = "https://apivip.aiproxy.io"
}
return fmt.Sprintf("%s/api/library/ask", baseURL), nil
return fmt.Sprintf("%s/api/library/ask", meta.BaseURL), nil
}
func (a *Adaptor) SetupRequestHeader(c *gin.Context, req *http.Request, meta *meta.Meta) error {
adaptor.SetupCommonRequestHeader(c, req, meta)
apiKey := meta.APIKey
apiKey = strings.TrimSuffix(apiKey, "#vip")
req.Header.Set("Authorization", "Bearer "+apiKey)
req.Header.Set("Authorization", "Bearer "+meta.APIKey)
return nil
}

View File

@@ -6,7 +6,6 @@ import (
"errors"
"fmt"
"github.com/gin-gonic/gin"
"github.com/songquanpeng/one-api/common/ctxkey"
"github.com/songquanpeng/one-api/common/helper"
"github.com/songquanpeng/one-api/common/logger"
"github.com/songquanpeng/one-api/relay/adaptor/openai"
@@ -20,11 +19,7 @@ import (
func ImageHandler(c *gin.Context, resp *http.Response) (*model.ErrorWithStatusCode, *model.Usage) {
apiKey := c.Request.Header.Get("Authorization")
apiKey = strings.TrimPrefix(apiKey, "Bearer ")
var responseFormat string
if req, exists := c.Get(ctxkey.ConvertedRequest); exists {
responseFormat = req.(*ImageRequest).ResponseFormat
}
responseFormat := c.GetString("response_format")
var aliTaskResponse TaskResponse
responseBody, err := io.ReadAll(resp.Body)

View File

@@ -72,7 +72,7 @@ func ConvertEmbeddingRequest(request model.GeneralOpenAIRequest) *EmbeddingReque
func ConvertImageRequest(request model.ImageRequest) *ImageRequest {
var imageRequest ImageRequest
imageRequest.Input.Prompt = request.Prompt
imageRequest.Model = strings.TrimPrefix(request.Model, "ali-")
imageRequest.Model = request.Model
imageRequest.Parameters.Size = strings.Replace(request.Size, "x", "*", -1)
imageRequest.Parameters.N = request.N
imageRequest.ResponseFormat = request.ResponseFormat

View File

@@ -50,11 +50,6 @@ func (a *Adaptor) GetRequestURL(meta *meta.Meta) (string, error) {
return minimax.GetRequestURL(meta)
case channeltype.Doubao:
return doubao.GetRequestURL(meta)
case channeltype.AIProxy:
if strings.HasSuffix(meta.APIKey, "#vip") {
return GetFullRequestURL("https://apivip.aiproxy.io", meta.RequestURLPath, meta.ChannelType), nil
}
fallthrough
case channeltype.Novita:
return novita.GetRequestURL(meta)
default:
@@ -68,11 +63,7 @@ func (a *Adaptor) SetupRequestHeader(c *gin.Context, req *http.Request, meta *me
req.Header.Set("api-key", meta.APIKey)
return nil
}
apiKey := meta.APIKey
if meta.ChannelType == channeltype.AIProxy {
apiKey = strings.TrimSuffix(apiKey, "#vip")
}
req.Header.Set("Authorization", "Bearer "+apiKey)
req.Header.Set("Authorization", "Bearer "+meta.APIKey)
if meta.ChannelType == channeltype.OpenRouter {
req.Header.Set("HTTP-Referer", "https://github.com/songquanpeng/one-api")
req.Header.Set("X-Title", "One API")

View File

@@ -61,4 +61,6 @@ var ImagePromptLengthLimitations = map[string]int{
}
var ImageOriginModelName = map[string]string{
"ali-stable-diffusion-xl": "stable-diffusion-xl",
"ali-stable-diffusion-v1.5": "stable-diffusion-v1.5",
}

View File

@@ -164,7 +164,6 @@ func RelayImageHelper(c *gin.Context, relayMode int) *relaymodel.ErrorWithStatus
if err != nil {
return openai.ErrorWrapper(err, "marshal_image_request_failed", http.StatusInternalServerError)
}
c.Set(ctxkey.ConvertedRequest, finalRequest)
requestBody = bytes.NewBuffer(jsonStr)
}

View File

@@ -4,13 +4,13 @@ import (
"bytes"
"encoding/json"
"fmt"
"github.com/songquanpeng/one-api/relay/adaptor"
"io"
"net/http"
"github.com/gin-gonic/gin"
"github.com/songquanpeng/one-api/common/logger"
"github.com/songquanpeng/one-api/relay"
"github.com/songquanpeng/one-api/relay/adaptor"
"github.com/songquanpeng/one-api/relay/adaptor/openai"
"github.com/songquanpeng/one-api/relay/apitype"
"github.com/songquanpeng/one-api/relay/billing"
@@ -54,6 +54,7 @@ func RelayTextHelper(c *gin.Context) *model.ErrorWithStatusCode {
}
adaptor.Init(meta)
// get request body
requestBody, err := getRequestBody(c, meta, textRequest, adaptor)
if err != nil {
return openai.ErrorWrapper(err, "convert_request_failed", http.StatusInternalServerError)