feat: sync remaining channel and relay updates
This commit is contained in:
@@ -2,13 +2,16 @@ package controller
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"math"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/textproto"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -42,6 +45,56 @@ type testResult struct {
|
||||
newAPIError *types.NewAPIError
|
||||
}
|
||||
|
||||
const imageEditTestPngBase64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAusB9Wn7Zc8AAAAASUVORK5CYII="
|
||||
|
||||
func buildImageEditTestMultipartRequest(requestPath, model string) (*http.Request, error) {
|
||||
var requestBody bytes.Buffer
|
||||
writer := multipart.NewWriter(&requestBody)
|
||||
|
||||
if err := writer.WriteField("model", model); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := writer.WriteField("prompt", "edit this image"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := writer.WriteField("size", "1024x1024"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := writer.WriteField("n", "1"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
imageBytes, err := base64.StdEncoding.DecodeString(imageEditTestPngBase64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
header := make(textproto.MIMEHeader)
|
||||
header.Set("Content-Disposition", `form-data; name="image"; filename="channel-test.png"`)
|
||||
header.Set("Content-Type", "image/png")
|
||||
part, err := writer.CreatePart(header)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, err = part.Write(imageBytes); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = writer.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req := &http.Request{
|
||||
Method: "POST",
|
||||
URL: &url.URL{Path: requestPath},
|
||||
Body: io.NopCloser(bytes.NewReader(requestBody.Bytes())),
|
||||
Header: make(http.Header),
|
||||
}
|
||||
req.Header.Set("Content-Type", writer.FormDataContentType())
|
||||
req.ContentLength = int64(requestBody.Len())
|
||||
return req, nil
|
||||
}
|
||||
|
||||
func normalizeChannelTestEndpoint(channel *model.Channel, modelName, endpointType string) string {
|
||||
normalized := strings.TrimSpace(endpointType)
|
||||
if normalized != "" {
|
||||
@@ -153,6 +206,16 @@ func testChannel(channel *model.Channel, testModel string, endpointType string,
|
||||
|
||||
//c.Request.Header.Set("Authorization", "Bearer "+channel.Key)
|
||||
c.Request.Header.Set("Content-Type", "application/json")
|
||||
if requestPath == "/v1/images/edits" {
|
||||
c.Request, err = buildImageEditTestMultipartRequest(requestPath, testModel)
|
||||
if err != nil {
|
||||
return testResult{
|
||||
context: c,
|
||||
localErr: err,
|
||||
newAPIError: types.NewError(err, types.ErrorCodeReadRequestBodyFailed),
|
||||
}
|
||||
}
|
||||
}
|
||||
c.Set("channel", channel.Type)
|
||||
c.Set("base_url", channel.GetBaseURL())
|
||||
group, _ := model.GetUserGroup(1, false)
|
||||
@@ -184,7 +247,7 @@ func testChannel(channel *model.Channel, testModel string, endpointType string,
|
||||
relayFormat = types.RelayFormatGemini
|
||||
case constant.EndpointTypeJinaRerank:
|
||||
relayFormat = types.RelayFormatRerank
|
||||
case constant.EndpointTypeImageGeneration:
|
||||
case constant.EndpointTypeImageGeneration, constant.EndpointTypeImageEdit:
|
||||
relayFormat = types.RelayFormatOpenAIImage
|
||||
case constant.EndpointTypeEmbeddings:
|
||||
relayFormat = types.RelayFormatEmbedding
|
||||
@@ -200,6 +263,9 @@ func testChannel(channel *model.Channel, testModel string, endpointType string,
|
||||
if c.Request.URL.Path == "/v1/images/generations" {
|
||||
relayFormat = types.RelayFormatOpenAIImage
|
||||
}
|
||||
if c.Request.URL.Path == "/v1/images/edits" {
|
||||
relayFormat = types.RelayFormatOpenAIImage
|
||||
}
|
||||
if c.Request.URL.Path == "/v1/messages" {
|
||||
relayFormat = types.RelayFormatClaude
|
||||
}
|
||||
@@ -294,7 +360,7 @@ func testChannel(channel *model.Channel, testModel string, endpointType string,
|
||||
newAPIError: types.NewError(errors.New("invalid embedding request type"), types.ErrorCodeConvertRequestFailed),
|
||||
}
|
||||
}
|
||||
case relayconstant.RelayModeImagesGenerations:
|
||||
case relayconstant.RelayModeImagesGenerations, relayconstant.RelayModeImagesEdits:
|
||||
// 图像生成请求 - request 已经是正确的类型
|
||||
if imageReq, ok := request.(*dto.ImageRequest); ok {
|
||||
convertedRequest, err = adaptor.ConvertImageRequest(c, info, *imageReq)
|
||||
@@ -366,44 +432,53 @@ func testChannel(channel *model.Channel, testModel string, endpointType string,
|
||||
newAPIError: types.NewError(err, types.ErrorCodeConvertRequestFailed),
|
||||
}
|
||||
}
|
||||
jsonData, err := common.Marshal(convertedRequest)
|
||||
if err != nil {
|
||||
return testResult{
|
||||
context: c,
|
||||
localErr: err,
|
||||
newAPIError: types.NewError(err, types.ErrorCodeJsonMarshalFailed),
|
||||
}
|
||||
}
|
||||
|
||||
//jsonData, err = relaycommon.RemoveDisabledFields(jsonData, info.ChannelOtherSettings)
|
||||
//if err != nil {
|
||||
// return testResult{
|
||||
// context: c,
|
||||
// localErr: err,
|
||||
// newAPIError: types.NewError(err, types.ErrorCodeConvertRequestFailed),
|
||||
// }
|
||||
//}
|
||||
|
||||
if len(info.ParamOverride) > 0 {
|
||||
jsonData, err = relaycommon.ApplyParamOverrideWithRelayInfo(jsonData, info)
|
||||
if err != nil {
|
||||
if fixedErr, ok := relaycommon.AsParamOverrideReturnError(err); ok {
|
||||
return testResult{
|
||||
context: c,
|
||||
localErr: fixedErr,
|
||||
newAPIError: relaycommon.NewAPIErrorFromParamOverride(fixedErr),
|
||||
}
|
||||
}
|
||||
var requestBody *bytes.Buffer
|
||||
switch req := convertedRequest.(type) {
|
||||
case *bytes.Buffer:
|
||||
requestBody = bytes.NewBuffer(req.Bytes())
|
||||
case bytes.Buffer:
|
||||
requestBody = bytes.NewBuffer(req.Bytes())
|
||||
default:
|
||||
jsonData, marshalErr := common.Marshal(convertedRequest)
|
||||
if marshalErr != nil {
|
||||
return testResult{
|
||||
context: c,
|
||||
localErr: err,
|
||||
newAPIError: types.NewError(err, types.ErrorCodeChannelParamOverrideInvalid),
|
||||
localErr: marshalErr,
|
||||
newAPIError: types.NewError(marshalErr, types.ErrorCodeJsonMarshalFailed),
|
||||
}
|
||||
}
|
||||
|
||||
//jsonData, err = relaycommon.RemoveDisabledFields(jsonData, info.ChannelOtherSettings)
|
||||
//if err != nil {
|
||||
// return testResult{
|
||||
// context: c,
|
||||
// localErr: err,
|
||||
// newAPIError: types.NewError(err, types.ErrorCodeConvertRequestFailed),
|
||||
// }
|
||||
//}
|
||||
|
||||
if len(info.ParamOverride) > 0 {
|
||||
jsonData, marshalErr = relaycommon.ApplyParamOverrideWithRelayInfo(jsonData, info)
|
||||
if marshalErr != nil {
|
||||
if fixedErr, ok := relaycommon.AsParamOverrideReturnError(marshalErr); ok {
|
||||
return testResult{
|
||||
context: c,
|
||||
localErr: fixedErr,
|
||||
newAPIError: relaycommon.NewAPIErrorFromParamOverride(fixedErr),
|
||||
}
|
||||
}
|
||||
return testResult{
|
||||
context: c,
|
||||
localErr: marshalErr,
|
||||
newAPIError: types.NewError(marshalErr, types.ErrorCodeChannelParamOverrideInvalid),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
requestBody = bytes.NewBuffer(jsonData)
|
||||
c.Request.Body = io.NopCloser(bytes.NewBuffer(jsonData))
|
||||
}
|
||||
|
||||
requestBody := bytes.NewBuffer(jsonData)
|
||||
c.Request.Body = io.NopCloser(bytes.NewBuffer(jsonData))
|
||||
resp, err := adaptor.DoRequest(c, info, requestBody)
|
||||
if err != nil {
|
||||
return testResult{
|
||||
@@ -618,6 +693,14 @@ func buildTestRequest(model string, endpointType string, channel *model.Channel,
|
||||
N: lo.ToPtr(uint(1)),
|
||||
Size: "1024x1024",
|
||||
}
|
||||
case constant.EndpointTypeImageEdit:
|
||||
// 返回 ImageRequest
|
||||
return &dto.ImageRequest{
|
||||
Model: model,
|
||||
Prompt: "edit this image",
|
||||
N: lo.ToPtr(uint(1)),
|
||||
Size: "1024x1024",
|
||||
}
|
||||
case constant.EndpointTypeJinaRerank:
|
||||
// 返回 RerankRequest
|
||||
return &dto.RerankRequest{
|
||||
|
||||
Reference in New Issue
Block a user