You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

163 lines
4.5 KiB

  1. package controller
  2. import (
  3. "fmt"
  4. "net/http"
  5. "strings"
  6. "github.com/QuantumNous/new-api/common"
  7. "github.com/QuantumNous/new-api/constant"
  8. "github.com/QuantumNous/new-api/dto"
  9. "github.com/QuantumNous/new-api/model"
  10. relaycommon "github.com/QuantumNous/new-api/relay/common"
  11. "github.com/QuantumNous/new-api/service"
  12. "github.com/QuantumNous/new-api/types"
  13. "github.com/gin-gonic/gin"
  14. )
  15. func convertAipingNativeVideoRequest(body []byte) (relaycommon.TaskSubmitReq, error) {
  16. var raw map[string]any
  17. if err := common.Unmarshal(body, &raw); err != nil {
  18. return relaycommon.TaskSubmitReq{}, err
  19. }
  20. modelName, _ := raw["model"].(string)
  21. if strings.TrimSpace(modelName) == "" {
  22. return relaycommon.TaskSubmitReq{}, fmt.Errorf("model field is required")
  23. }
  24. metadata := map[string]any{}
  25. for key, value := range raw {
  26. if key == "model" || key == "content" {
  27. continue
  28. }
  29. metadata[key] = value
  30. }
  31. var passthroughContent []any
  32. if rawContent, ok := raw["content"].([]any); ok {
  33. for _, item := range rawContent {
  34. itemMap, ok := item.(map[string]any)
  35. if !ok {
  36. passthroughContent = append(passthroughContent, item)
  37. continue
  38. }
  39. passthroughContent = append(passthroughContent, itemMap)
  40. }
  41. }
  42. if len(passthroughContent) > 0 {
  43. metadata["content"] = passthroughContent
  44. }
  45. return relaycommon.TaskSubmitReq{
  46. Model: strings.TrimSpace(modelName),
  47. Metadata: metadata,
  48. }, nil
  49. }
  50. func prepareAipingNativeVideoSubmit(c *gin.Context, info *relaycommon.RelayInfo) error {
  51. bodyStorage, err := common.GetBodyStorage(c)
  52. if err != nil {
  53. return err
  54. }
  55. body, err := bodyStorage.Bytes()
  56. if err != nil {
  57. return err
  58. }
  59. req, err := convertAipingNativeVideoRequest(body)
  60. if err != nil {
  61. return err
  62. }
  63. info.OriginModelName = req.Model
  64. info.Action = constant.TaskActionGenerate
  65. relaycommon.StoreTaskRequest(c, info, constant.TaskActionGenerate, req)
  66. return nil
  67. }
  68. func AipingNativeVideoSubmit(c *gin.Context) {
  69. relayInfo, err := relaycommon.GenRelayInfo(c, types.RelayFormatTask, nil, nil)
  70. if err != nil {
  71. c.JSON(http.StatusInternalServerError, &dto.TaskError{
  72. Code: "gen_relay_info_failed",
  73. Message: err.Error(),
  74. StatusCode: http.StatusInternalServerError,
  75. })
  76. return
  77. }
  78. if relayInfo.ChannelMeta == nil {
  79. relayInfo.ChannelMeta = &relaycommon.ChannelMeta{}
  80. }
  81. if err := prepareAipingNativeVideoSubmit(c, relayInfo); err != nil {
  82. c.JSON(http.StatusBadRequest, &dto.TaskError{
  83. Code: "invalid_request",
  84. Message: err.Error(),
  85. StatusCode: http.StatusBadRequest,
  86. })
  87. return
  88. }
  89. channelType := service.DoubaoAssetChannelTypeForModel(relayInfo.OriginModelName)
  90. c.Set("channel_type", channelType)
  91. relayInfo.ChannelType = channelType
  92. relayTaskWithInfo(c, relayInfo)
  93. }
  94. func buildAipingNativeFetchResponse(task *model.Task) ([]byte, error) {
  95. payload := map[string]any{}
  96. if len(task.Data) > 0 {
  97. if err := common.Unmarshal(task.Data, &payload); err != nil {
  98. return nil, err
  99. }
  100. }
  101. delete(payload, "aiping_id")
  102. if _, ok := payload["error"]; !ok {
  103. payload["error"] = nil
  104. }
  105. payload["id"] = task.TaskID
  106. if _, ok := payload["model"]; !ok {
  107. payload["model"] = task.Properties.OriginModelName
  108. }
  109. if _, ok := payload["status"]; !ok {
  110. payload["status"] = mapAipingNativeStatus(task.Status)
  111. }
  112. if _, ok := payload["created_at"]; !ok {
  113. payload["created_at"] = task.CreatedAt
  114. }
  115. if _, ok := payload["updated_at"]; !ok {
  116. payload["updated_at"] = task.UpdatedAt
  117. }
  118. return common.Marshal(payload)
  119. }
  120. func mapAipingNativeStatus(status model.TaskStatus) string {
  121. switch status {
  122. case model.TaskStatusQueued, model.TaskStatusSubmitted:
  123. return "queued"
  124. case model.TaskStatusInProgress:
  125. return "running"
  126. case model.TaskStatusSuccess:
  127. return "succeeded"
  128. case model.TaskStatusFailure:
  129. return "failed"
  130. default:
  131. return "running"
  132. }
  133. }
  134. func AipingNativeVideoFetch(c *gin.Context) {
  135. taskID := c.Param("task_id")
  136. task, exist, err := model.GetByTaskId(c.GetInt("id"), taskID)
  137. if err != nil {
  138. c.JSON(http.StatusInternalServerError, &dto.TaskError{Code: "get_task_failed", Message: err.Error(), StatusCode: http.StatusInternalServerError})
  139. return
  140. }
  141. if !exist {
  142. c.JSON(http.StatusNotFound, gin.H{"error": gin.H{"code": "not_found", "message": "task not found"}})
  143. return
  144. }
  145. data, err := buildAipingNativeFetchResponse(task)
  146. if err != nil {
  147. c.JSON(http.StatusInternalServerError, &dto.TaskError{Code: "build_response_failed", Message: err.Error(), StatusCode: http.StatusInternalServerError})
  148. return
  149. }
  150. c.Data(http.StatusOK, "application/json", data)
  151. }