This commit refactors the logging mechanism across the application by replacing direct logger calls with a centralized logging approach using the `common` package. Key changes include: - Replaced instances of `logger.SysLog` and `logger.FatalLog` with `common.SysLog` and `common.FatalLog` for consistent logging practices. - Updated resource initialization error handling to utilize the new logging structure, enhancing maintainability and readability. - Minor adjustments to improve code clarity and organization throughout various modules. This change aims to streamline logging and improve the overall architecture of the codebase.
173 lines
4.4 KiB
Go
173 lines
4.4 KiB
Go
package ali
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"one-api/common"
|
|
"one-api/dto"
|
|
"one-api/logger"
|
|
relaycommon "one-api/relay/common"
|
|
"one-api/service"
|
|
"one-api/types"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
func oaiImage2Ali(request dto.ImageRequest) *AliImageRequest {
|
|
var imageRequest AliImageRequest
|
|
imageRequest.Input.Prompt = request.Prompt
|
|
imageRequest.Model = request.Model
|
|
imageRequest.Parameters.Size = strings.Replace(request.Size, "x", "*", -1)
|
|
imageRequest.Parameters.N = int(request.N)
|
|
imageRequest.ResponseFormat = request.ResponseFormat
|
|
|
|
return &imageRequest
|
|
}
|
|
|
|
func updateTask(info *relaycommon.RelayInfo, taskID string) (*AliResponse, error, []byte) {
|
|
url := fmt.Sprintf("%s/api/v1/tasks/%s", info.ChannelBaseUrl, taskID)
|
|
|
|
var aliResponse AliResponse
|
|
|
|
req, err := http.NewRequest("GET", url, nil)
|
|
if err != nil {
|
|
return &aliResponse, err, nil
|
|
}
|
|
|
|
req.Header.Set("Authorization", "Bearer "+info.ApiKey)
|
|
|
|
client := &http.Client{}
|
|
resp, err := client.Do(req)
|
|
if err != nil {
|
|
common.SysLog("updateTask client.Do err: " + err.Error())
|
|
return &aliResponse, err, nil
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
responseBody, err := io.ReadAll(resp.Body)
|
|
|
|
var response AliResponse
|
|
err = json.Unmarshal(responseBody, &response)
|
|
if err != nil {
|
|
common.SysLog("updateTask NewDecoder err: " + err.Error())
|
|
return &aliResponse, err, nil
|
|
}
|
|
|
|
return &response, nil, responseBody
|
|
}
|
|
|
|
func asyncTaskWait(info *relaycommon.RelayInfo, taskID string) (*AliResponse, []byte, error) {
|
|
waitSeconds := 3
|
|
step := 0
|
|
maxStep := 20
|
|
|
|
var taskResponse AliResponse
|
|
var responseBody []byte
|
|
|
|
for {
|
|
step++
|
|
rsp, err, body := updateTask(info, taskID)
|
|
responseBody = body
|
|
if err != nil {
|
|
return &taskResponse, responseBody, err
|
|
}
|
|
|
|
if rsp.Output.TaskStatus == "" {
|
|
return &taskResponse, responseBody, nil
|
|
}
|
|
|
|
switch rsp.Output.TaskStatus {
|
|
case "FAILED":
|
|
fallthrough
|
|
case "CANCELED":
|
|
fallthrough
|
|
case "SUCCEEDED":
|
|
fallthrough
|
|
case "UNKNOWN":
|
|
return rsp, responseBody, nil
|
|
}
|
|
if step >= maxStep {
|
|
break
|
|
}
|
|
time.Sleep(time.Duration(waitSeconds) * time.Second)
|
|
}
|
|
|
|
return nil, nil, fmt.Errorf("aliAsyncTaskWait timeout")
|
|
}
|
|
|
|
func responseAli2OpenAIImage(c *gin.Context, response *AliResponse, info *relaycommon.RelayInfo, responseFormat string) *dto.ImageResponse {
|
|
imageResponse := dto.ImageResponse{
|
|
Created: info.StartTime.Unix(),
|
|
}
|
|
|
|
for _, data := range response.Output.Results {
|
|
var b64Json string
|
|
if responseFormat == "b64_json" {
|
|
_, b64, err := service.GetImageFromUrl(data.Url)
|
|
if err != nil {
|
|
logger.LogError(c, "get_image_data_failed: "+err.Error())
|
|
continue
|
|
}
|
|
b64Json = b64
|
|
} else {
|
|
b64Json = data.B64Image
|
|
}
|
|
|
|
imageResponse.Data = append(imageResponse.Data, dto.ImageData{
|
|
Url: data.Url,
|
|
B64Json: b64Json,
|
|
RevisedPrompt: "",
|
|
})
|
|
}
|
|
return &imageResponse
|
|
}
|
|
|
|
func aliImageHandler(c *gin.Context, resp *http.Response, info *relaycommon.RelayInfo) (*types.NewAPIError, *dto.Usage) {
|
|
responseFormat := c.GetString("response_format")
|
|
|
|
var aliTaskResponse AliResponse
|
|
responseBody, err := io.ReadAll(resp.Body)
|
|
if err != nil {
|
|
return types.NewOpenAIError(err, types.ErrorCodeReadResponseBodyFailed, http.StatusInternalServerError), nil
|
|
}
|
|
service.CloseResponseBodyGracefully(resp)
|
|
err = json.Unmarshal(responseBody, &aliTaskResponse)
|
|
if err != nil {
|
|
return types.NewOpenAIError(err, types.ErrorCodeBadResponseBody, http.StatusInternalServerError), nil
|
|
}
|
|
|
|
if aliTaskResponse.Message != "" {
|
|
logger.LogError(c, "ali_async_task_failed: "+aliTaskResponse.Message)
|
|
return types.NewError(errors.New(aliTaskResponse.Message), types.ErrorCodeBadResponse), nil
|
|
}
|
|
|
|
aliResponse, _, err := asyncTaskWait(info, aliTaskResponse.Output.TaskId)
|
|
if err != nil {
|
|
return types.NewError(err, types.ErrorCodeBadResponse), nil
|
|
}
|
|
|
|
if aliResponse.Output.TaskStatus != "SUCCEEDED" {
|
|
return types.WithOpenAIError(types.OpenAIError{
|
|
Message: aliResponse.Output.Message,
|
|
Type: "ali_error",
|
|
Param: "",
|
|
Code: aliResponse.Output.Code,
|
|
}, resp.StatusCode), nil
|
|
}
|
|
|
|
fullTextResponse := responseAli2OpenAIImage(c, aliResponse, info, responseFormat)
|
|
jsonResponse, err := json.Marshal(fullTextResponse)
|
|
if err != nil {
|
|
return types.NewError(err, types.ErrorCodeBadResponseBody), nil
|
|
}
|
|
c.Writer.Header().Set("Content-Type", "application/json")
|
|
c.Writer.WriteHeader(resp.StatusCode)
|
|
c.Writer.Write(jsonResponse)
|
|
return nil, &dto.Usage{}
|
|
}
|