Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.
 
 
 

191 wiersze
5.7 KiB

  1. package doubao
  2. import (
  3. "testing"
  4. "github.com/QuantumNous/new-api/dto"
  5. "github.com/QuantumNous/new-api/model"
  6. relaycommon "github.com/QuantumNous/new-api/relay/common"
  7. "github.com/stretchr/testify/require"
  8. )
  9. func TestParseTaskResult_SuccessWithUsage(t *testing.T) {
  10. adaptor := &TaskAdaptor{}
  11. taskInfo, err := adaptor.ParseTaskResult([]byte(`{
  12. "status":"succeeded",
  13. "content":{"video_url":"https://example.test/video.mp4"},
  14. "usage":{"completion_tokens":12,"total_tokens":3456}
  15. }`))
  16. require.NoError(t, err)
  17. require.Equal(t, string(model.TaskStatusSuccess), taskInfo.Status)
  18. require.Equal(t, "https://example.test/video.mp4", taskInfo.Url)
  19. require.Equal(t, 12, taskInfo.CompletionTokens)
  20. require.Equal(t, 3456, taskInfo.TotalTokens)
  21. }
  22. func TestParseTaskResult_SuccessWithoutUsage(t *testing.T) {
  23. adaptor := &TaskAdaptor{}
  24. taskInfo, err := adaptor.ParseTaskResult([]byte(`{
  25. "status":"succeeded",
  26. "content":{"video_url":"https://example.test/video.mp4"}
  27. }`))
  28. require.NoError(t, err)
  29. require.Equal(t, string(model.TaskStatusSuccess), taskInfo.Status)
  30. require.Zero(t, taskInfo.TotalTokens)
  31. }
  32. func TestParseTaskResult_NonSuccessStatusesDoNotRequireUsage(t *testing.T) {
  33. adaptor := &TaskAdaptor{}
  34. cases := map[string]model.TaskStatus{
  35. "queued": model.TaskStatusQueued,
  36. "processing": model.TaskStatusInProgress,
  37. "failed": model.TaskStatusFailure,
  38. }
  39. for status, want := range cases {
  40. taskInfo, err := adaptor.ParseTaskResult([]byte(`{"status":"` + status + `"}`))
  41. require.NoError(t, err)
  42. require.Equal(t, string(want), taskInfo.Status)
  43. require.Zero(t, taskInfo.TotalTokens)
  44. }
  45. }
  46. func TestConvertToRequestPayload_MetadataSupportsVideoAudioAndTools(t *testing.T) {
  47. adaptor := &TaskAdaptor{}
  48. req := &relaycommon.TaskSubmitReq{
  49. Model: "doubao-seedance-2-0-260128",
  50. Prompt: "make a reference video",
  51. Metadata: map[string]interface{}{
  52. "content": []interface{}{
  53. map[string]interface{}{
  54. "type": "video_url",
  55. "video_url": map[string]interface{}{
  56. "url": "https://example.test/input.mp4",
  57. },
  58. "role": "reference_video",
  59. },
  60. map[string]interface{}{
  61. "type": "audio_url",
  62. "audio_url": map[string]interface{}{
  63. "url": "https://example.test/input.wav",
  64. },
  65. "role": "reference_audio",
  66. },
  67. },
  68. "tools": []interface{}{
  69. map[string]interface{}{"type": "web_search"},
  70. },
  71. },
  72. }
  73. payload, err := adaptor.convertToRequestPayload(req)
  74. require.NoError(t, err)
  75. require.Len(t, payload.Content, 3)
  76. require.Equal(t, "video_url", payload.Content[0].Type)
  77. require.Equal(t, "https://example.test/input.mp4", payload.Content[0].VideoURL.URL)
  78. require.Equal(t, "reference_video", payload.Content[0].Role)
  79. require.Equal(t, "audio_url", payload.Content[1].Type)
  80. require.Equal(t, "https://example.test/input.wav", payload.Content[1].AudioURL.URL)
  81. require.Equal(t, "reference_audio", payload.Content[1].Role)
  82. require.Len(t, payload.Tools, 1)
  83. require.Equal(t, "web_search", payload.Tools[0].Type)
  84. }
  85. func TestConvertToRequestPayload_SecondsOverridesDuration(t *testing.T) {
  86. adaptor := &TaskAdaptor{}
  87. req := &relaycommon.TaskSubmitReq{
  88. Model: "doubao-seedance-1-5-pro-251215",
  89. Prompt: "cat yawning",
  90. Seconds: "8",
  91. Metadata: map[string]interface{}{
  92. "duration": 5,
  93. },
  94. }
  95. payload, err := adaptor.convertToRequestPayload(req)
  96. require.NoError(t, err)
  97. require.NotNil(t, payload.Duration)
  98. require.Equal(t, dto.IntValue(8), *payload.Duration)
  99. }
  100. func TestConvertToRequestPayload_PromptAppendedAfterMetadataAndReplacesMetadataText(t *testing.T) {
  101. adaptor := &TaskAdaptor{}
  102. req := &relaycommon.TaskSubmitReq{
  103. Model: "doubao-seedance-1-5-pro-251215",
  104. Prompt: "current prompt",
  105. Images: []string{"https://example.test/first.png"},
  106. Metadata: map[string]interface{}{
  107. "content": []interface{}{
  108. map[string]interface{}{
  109. "type": "text",
  110. "text": "metadata prompt",
  111. },
  112. map[string]interface{}{
  113. "type": "image_url",
  114. "image_url": map[string]interface{}{
  115. "url": "https://example.test/second.png",
  116. },
  117. "role": "last_frame",
  118. },
  119. },
  120. },
  121. }
  122. payload, err := adaptor.convertToRequestPayload(req)
  123. require.NoError(t, err)
  124. require.Len(t, payload.Content, 2)
  125. require.Equal(t, "image_url", payload.Content[0].Type)
  126. require.Equal(t, "https://example.test/second.png", payload.Content[0].ImageURL.URL)
  127. require.Equal(t, "last_frame", payload.Content[0].Role)
  128. require.Equal(t, "text", payload.Content[1].Type)
  129. require.Equal(t, "current prompt", payload.Content[1].Text)
  130. }
  131. func TestParseTaskResult_FailedUsesUpstreamErrorMessage(t *testing.T) {
  132. adaptor := &TaskAdaptor{}
  133. taskInfo, err := adaptor.ParseTaskResult([]byte(`{
  134. "status":"failed",
  135. "error":{"code":"InvalidParameter","message":"duration is invalid"}
  136. }`))
  137. require.NoError(t, err)
  138. require.Equal(t, string(model.TaskStatusFailure), taskInfo.Status)
  139. require.Equal(t, "duration is invalid", taskInfo.Reason)
  140. }
  141. func TestConvertToOpenAIVideo_FailedUsesUpstreamError(t *testing.T) {
  142. adaptor := &TaskAdaptor{}
  143. task := &model.Task{
  144. TaskID: "task_public",
  145. Status: model.TaskStatusFailure,
  146. Progress: "100%",
  147. CreatedAt: 100,
  148. UpdatedAt: 200,
  149. Properties: model.Properties{
  150. OriginModelName: "doubao-seedance-1-5-pro-251215",
  151. },
  152. Data: []byte(`{
  153. "status":"failed",
  154. "error":{"code":"InvalidParameter","message":"duration is invalid"}
  155. }`),
  156. }
  157. data, err := adaptor.ConvertToOpenAIVideo(task)
  158. require.NoError(t, err)
  159. require.Contains(t, string(data), `"message":"duration is invalid"`)
  160. require.Contains(t, string(data), `"code":"InvalidParameter"`)
  161. }
  162. func TestGetModelList_IncludesSeedance20Models(t *testing.T) {
  163. adaptor := &TaskAdaptor{}
  164. models := adaptor.GetModelList()
  165. require.Contains(t, models, "doubao-seedance-2-0-260128")
  166. require.Contains(t, models, "doubao-seedance-2-0-fast-260128")
  167. }