image.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. package zhipu_4v
  2. import (
  3. "io"
  4. "net/http"
  5. "github.com/QuantumNous/new-api/common"
  6. "github.com/QuantumNous/new-api/dto"
  7. "github.com/QuantumNous/new-api/logger"
  8. relaycommon "github.com/QuantumNous/new-api/relay/common"
  9. "github.com/QuantumNous/new-api/service"
  10. "github.com/QuantumNous/new-api/types"
  11. "github.com/gin-gonic/gin"
  12. )
  13. type zhipuImageRequest struct {
  14. Model string `json:"model"`
  15. Prompt string `json:"prompt"`
  16. Quality string `json:"quality,omitempty"`
  17. Size string `json:"size,omitempty"`
  18. WatermarkEnabled *bool `json:"watermark_enabled,omitempty"`
  19. UserID string `json:"user_id,omitempty"`
  20. }
  21. type zhipuImageResponse struct {
  22. Created *int64 `json:"created,omitempty"`
  23. Data []zhipuImageData `json:"data,omitempty"`
  24. ContentFilter any `json:"content_filter,omitempty"`
  25. Usage *dto.Usage `json:"usage,omitempty"`
  26. Error *zhipuImageError `json:"error,omitempty"`
  27. RequestID string `json:"request_id,omitempty"`
  28. ExtendParam map[string]string `json:"extendParam,omitempty"`
  29. }
  30. type zhipuImageError struct {
  31. Code string `json:"code"`
  32. Message string `json:"message"`
  33. }
  34. type zhipuImageData struct {
  35. Url string `json:"url,omitempty"`
  36. ImageUrl string `json:"image_url,omitempty"`
  37. B64Json string `json:"b64_json,omitempty"`
  38. B64Image string `json:"b64_image,omitempty"`
  39. }
  40. type openAIImagePayload struct {
  41. Created int64 `json:"created"`
  42. Data []openAIImageData `json:"data"`
  43. }
  44. type openAIImageData struct {
  45. B64Json string `json:"b64_json"`
  46. }
  47. func zhipu4vImageHandler(c *gin.Context, resp *http.Response, info *relaycommon.RelayInfo) (*dto.Usage, *types.NewAPIError) {
  48. responseBody, err := io.ReadAll(resp.Body)
  49. if err != nil {
  50. return nil, types.NewOpenAIError(err, types.ErrorCodeReadResponseBodyFailed, http.StatusInternalServerError)
  51. }
  52. service.CloseResponseBodyGracefully(resp)
  53. var zhipuResp zhipuImageResponse
  54. if err := common.Unmarshal(responseBody, &zhipuResp); err != nil {
  55. return nil, types.NewOpenAIError(err, types.ErrorCodeBadResponseBody, http.StatusInternalServerError)
  56. }
  57. if zhipuResp.Error != nil && zhipuResp.Error.Message != "" {
  58. return nil, types.WithOpenAIError(types.OpenAIError{
  59. Message: zhipuResp.Error.Message,
  60. Type: "zhipu_image_error",
  61. Code: zhipuResp.Error.Code,
  62. }, resp.StatusCode)
  63. }
  64. payload := openAIImagePayload{}
  65. if zhipuResp.Created != nil && *zhipuResp.Created != 0 {
  66. payload.Created = *zhipuResp.Created
  67. } else {
  68. payload.Created = info.StartTime.Unix()
  69. }
  70. for _, data := range zhipuResp.Data {
  71. url := data.Url
  72. if url == "" {
  73. url = data.ImageUrl
  74. }
  75. if url == "" {
  76. logger.LogWarn(c, "zhipu_image_missing_url")
  77. continue
  78. }
  79. var b64 string
  80. switch {
  81. case data.B64Json != "":
  82. b64 = data.B64Json
  83. case data.B64Image != "":
  84. b64 = data.B64Image
  85. default:
  86. _, downloaded, err := service.GetImageFromUrl(url)
  87. if err != nil {
  88. logger.LogError(c, "zhipu_image_get_b64_failed: "+err.Error())
  89. continue
  90. }
  91. b64 = downloaded
  92. }
  93. if b64 == "" {
  94. logger.LogWarn(c, "zhipu_image_empty_b64")
  95. continue
  96. }
  97. imageData := openAIImageData{
  98. B64Json: b64,
  99. }
  100. payload.Data = append(payload.Data, imageData)
  101. }
  102. jsonResp, err := common.Marshal(payload)
  103. if err != nil {
  104. return nil, types.NewError(err, types.ErrorCodeBadResponseBody)
  105. }
  106. service.IOCopyBytesGracefully(c, resp, jsonResp)
  107. return &dto.Usage{}, nil
  108. }