feat: add vidu video channel - #1425
Conversation
WalkthroughA new channel type "Vidu" (type 52) was introduced across backend and frontend codebases. This includes constant and base URL definitions, a dedicated task adaptor for Vidu video generation, conditional handling in channel testing, integration in the adaptor selection logic, and a new frontend channel option. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant Frontend
participant Backend
participant ViduAPI
User->>Frontend: Selects "Vidu" channel
Frontend->>Backend: Submits video generation request (channelType=52)
Backend->>TaskAdaptor (Vidu): Validates and builds request
TaskAdaptor (Vidu)->>ViduAPI: Sends HTTP request (text/image to video)
ViduAPI-->>TaskAdaptor (Vidu): Returns task creation response
TaskAdaptor (Vidu)-->>Backend: Parses and returns task info
Backend-->>Frontend: Responds with task result/status
Frontend-->>User: Displays result or status
Estimated code review effort🎯 4 (Complex) | ⏱️ ~35 minutes Poem
Note ⚡️ Unit Test Generation is now available in beta!Learn more here, or try it out under "Finishing Touches" below. ✨ Finishing Touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
relay/channel/task/vidu/adaptor.go (1)
230-237: Fix typo in variable name.There's a typo in the variable name.
- medaBytes, err := json.Marshal(metadata) + metaBytes, err := json.Marshal(metadata) if err != nil { return nil, errors.Wrap(err, "metadata marshal metadata failed") } - err = json.Unmarshal(medaBytes, &r) + err = json.Unmarshal(metaBytes, &r)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
constant/channel.go(2 hunks)controller/channel-test.go(1 hunks)controller/task_video.go(1 hunks)relay/channel/task/vidu/adaptor.go(1 hunks)relay/relay_adaptor.go(2 hunks)web/src/constants/channel.constants.js(1 hunks)
🔇 Additional comments (13)
constant/channel.go (2)
52-52: LGTM! Channel type constant follows established pattern.The new
ChannelTypeViduconstant with value 52 is properly positioned and follows the sequential numbering convention used throughout the codebase.
110-110: LGTM! Base URL correctly positioned and formatted.The Vidu API base URL is properly placed at index 52 in the
ChannelBaseURLsslice, matching the channel type constant value, and follows the established URL formatting pattern.web/src/constants/channel.constants.js (1)
157-161: LGTM! Frontend channel option properly configured.The new Vidu channel option correctly matches the backend constant value (52) and follows the established pattern with appropriate color and label settings.
relay/relay_adaptor.go (2)
30-30: LGTM! Import statement properly added.The import for the taskVidu package is correctly placed and follows the established naming convention for task adaptors.
126-127: LGTM! Task adaptor registration follows established pattern.The new case for
ChannelTypeViducorrectly returns ataskVidu.TaskAdaptorinstance, maintaining consistency with other task adaptor registrations in the factory method.controller/channel-test.go (1)
72-77: LGTM! Channel test exclusion follows established pattern.The conditional branch for
ChannelTypeViducorrectly follows the same pattern used for other unsupported channel types, returning an appropriate error message indicating that testing is not supported for this channel type.controller/task_video.go (1)
86-86: LGTM! Enhanced response validation improves robustness.The addition of
&& responseItems.IsSuccess()condition ensures that the new API response format is only processed when the response indicates success, preventing incorrect data extraction from failed responses while maintaining backward compatibility through the fallback mechanism.relay/channel/task/vidu/adaptor.go (6)
3-20: Well-organized imports!The imports are properly grouped following Go conventions: standard library, third-party, and internal packages.
26-76: Well-structured data models!All structs are properly defined with appropriate JSON tags and follow Go naming conventions.
92-110: Solid request validation!The method properly validates required fields and determines the action type based on the presence of an image.
135-144: Clear URL routing logic!The method properly routes to different endpoints based on the action type.
255-285: Comprehensive state mapping!The method properly maps all Vidu API states to internal task statuses and correctly extracts results and error information.
183-200: Proper task fetching implementation!The method correctly constructs the request with appropriate headers and handles type assertion safely.
| func (a *TaskAdaptor) BuildRequestBody(c *gin.Context, _ *relaycommon.TaskRelayInfo) (io.Reader, error) { | ||
| v, exists := c.Get("task_request") | ||
| if !exists { | ||
| return nil, fmt.Errorf("request not found in context") | ||
| } | ||
| req := v.(SubmitReq) | ||
|
|
||
| body, err := a.convertToRequestPayload(&req) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
|
|
||
| if len(body.Images) == 0 { | ||
| c.Set("action", constant.TaskActionTextGenerate) | ||
| } | ||
|
|
||
| data, err := json.Marshal(body) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
| return bytes.NewReader(data), nil | ||
| } |
There was a problem hiding this comment.
Add safety check for type assertion.
The type assertion at line 117 could panic if the value is not of the expected type.
Apply this fix to handle the type assertion safely:
- req := v.(SubmitReq)
+ req, ok := v.(SubmitReq)
+ if !ok {
+ return nil, fmt.Errorf("invalid request type in context")
+ }📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| func (a *TaskAdaptor) BuildRequestBody(c *gin.Context, _ *relaycommon.TaskRelayInfo) (io.Reader, error) { | |
| v, exists := c.Get("task_request") | |
| if !exists { | |
| return nil, fmt.Errorf("request not found in context") | |
| } | |
| req := v.(SubmitReq) | |
| body, err := a.convertToRequestPayload(&req) | |
| if err != nil { | |
| return nil, err | |
| } | |
| if len(body.Images) == 0 { | |
| c.Set("action", constant.TaskActionTextGenerate) | |
| } | |
| data, err := json.Marshal(body) | |
| if err != nil { | |
| return nil, err | |
| } | |
| return bytes.NewReader(data), nil | |
| } | |
| func (a *TaskAdaptor) BuildRequestBody(c *gin.Context, _ *relaycommon.TaskRelayInfo) (io.Reader, error) { | |
| v, exists := c.Get("task_request") | |
| if !exists { | |
| return nil, fmt.Errorf("request not found in context") | |
| } | |
| req, ok := v.(SubmitReq) | |
| if !ok { | |
| return nil, fmt.Errorf("invalid request type in context") | |
| } | |
| body, err := a.convertToRequestPayload(&req) | |
| if err != nil { | |
| return nil, err | |
| } | |
| if len(body.Images) == 0 { | |
| c.Set("action", constant.TaskActionTextGenerate) | |
| } | |
| data, err := json.Marshal(body) | |
| if err != nil { | |
| return nil, err | |
| } | |
| return bytes.NewReader(data), nil | |
| } |
🤖 Prompt for AI Agents
In relay/channel/task/vidu/adaptor.go around lines 112 to 133, the type
assertion on line 117 directly converts the interface{} to SubmitReq, which can
cause a panic if the type is incorrect. Modify the code to use the two-value
form of type assertion to check if the assertion succeeded. If it fails, return
an error indicating the type mismatch instead of panicking.
| if err != nil { | ||
| taskErr = service.TaskErrorWrapper(errors.Wrap(err, fmt.Sprintf("%s", responseBody)), "unmarshal_response_failed", http.StatusInternalServerError) | ||
| return |
There was a problem hiding this comment.
Avoid including raw response in error messages.
Including the entire response body in error messages could leak sensitive information in logs.
Apply this fix:
- taskErr = service.TaskErrorWrapper(errors.Wrap(err, fmt.Sprintf("%s", responseBody)), "unmarshal_response_failed", http.StatusInternalServerError)
+ taskErr = service.TaskErrorWrapper(err, "unmarshal_response_failed", http.StatusInternalServerError)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if err != nil { | |
| taskErr = service.TaskErrorWrapper(errors.Wrap(err, fmt.Sprintf("%s", responseBody)), "unmarshal_response_failed", http.StatusInternalServerError) | |
| return | |
| if err != nil { | |
| taskErr = service.TaskErrorWrapper(err, "unmarshal_response_failed", http.StatusInternalServerError) | |
| return |
🤖 Prompt for AI Agents
In relay/channel/task/vidu/adaptor.go around lines 169 to 171, avoid including
the raw responseBody in the error message to prevent leaking sensitive
information. Modify the error wrapping to exclude responseBody and instead use a
generic error message or relevant error context without exposing the full
response content.
…o-channel feat: add vidu video channel
增加vidu视频渠道


可选模型
viduq1、vidu2.0、vidu1.5请求参数示例:
{
"model": "viduq1",
"prompt": "一个穿着宇航服的宇航员在月球上行走, 高品质, 电影级",
"size": "1920x1080",
"image": "https://prod-ss-images.s3.cn-northwest-1.amazonaws.com.cn/vidu-maas/template/image2video.png",
"duration": 5,
"metadata": {
"resolution": "1080p"
}
}
Summary by CodeRabbit
New Features
Bug Fixes
Other