即梦和vidu支持 OpenAI sdk生成和查询视频 - #2018
Conversation
WalkthroughIntroduces a unified OpenAIVideo model and status constants, adds TaskStatus-to-video-status mapping, and updates jimeng, kling, and vidu task adaptors to convert upstream task data into OpenAIVideo responses via new ConvertToOpenAIVideo methods and adjusted DoResponse flows. Removes prior OpenAIVideo types from relay_info and moves them to relay_video. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant Client
participant API as Relay API
participant Adaptor as Channel Adaptor (jimeng/kling/vidu)
participant Upstream as Upstream Task Service
Client->>API: Create/Query task
API->>Upstream: Forward request
Upstream-->>API: Task response (provider-specific)
API->>Adaptor: DoResponse(info, resp)
Adaptor->>Adaptor: ConvertToOpenAIVideo(originTask)
Note over Adaptor: Map TaskStatus -> VideoStatus<br/>Set progress, metadata (e.g., url)<br/>Set timestamps and error if present
Adaptor-->>API: OpenAIVideo
API-->>Client: JSON(OpenAIVideo)
sequenceDiagram
autonumber
participant Task as model.Task
participant Mapper as TaskStatus.ToVideoStatus
participant Video as OpenAIVideo
Task->>Mapper: status
Mapper-->>Video: status string (queued/in_progress/...)
Note over Video: Used in all adaptors during conversion
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 7
🧹 Nitpick comments (1)
relay/common/relay_video.go (1)
43-47: Consider initializing Status to a default value.The constructor only sets the
Objectfield. Optionally, you could initializeStatustoVideoStatusUnknownto ensure it always has a valid value rather than an empty string.func NewOpenAIVideo() *OpenAIVideo { return &OpenAIVideo{ Object: "video", + Status: VideoStatusUnknown, } }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
model/main.go(1 hunks)model/task.go(1 hunks)relay/channel/task/jimeng/adaptor.go(2 hunks)relay/channel/task/kling/adaptor.go(2 hunks)relay/channel/task/vidu/adaptor.go(4 hunks)relay/common/relay_info.go(0 hunks)relay/common/relay_video.go(1 hunks)
💤 Files with no reviewable changes (1)
- relay/common/relay_info.go
🧰 Additional context used
🧬 Code graph analysis (4)
model/task.go (1)
relay/common/relay_video.go (5)
VideoStatusQueued(10-10)VideoStatusInProgress(11-11)VideoStatusCompleted(12-12)VideoStatusFailed(13-13)VideoStatusUnknown(9-9)
relay/channel/task/jimeng/adaptor.go (2)
relay/common/relay_video.go (3)
NewOpenAIVideo(43-47)OpenAIVideo(16-31)OpenAIVideoError(49-52)model/task.go (3)
Task(40-59)Task(248-252)Task(254-258)
relay/channel/task/kling/adaptor.go (2)
relay/common/relay_video.go (1)
NewOpenAIVideo(43-47)relay/channel/ali/dto.go (1)
TaskResult(70-75)
relay/channel/task/vidu/adaptor.go (4)
relay/channel/adapter.go (1)
TaskAdaptor(33-52)relay/common/relay_info.go (1)
RelayInfo(74-121)relay/common/relay_video.go (3)
NewOpenAIVideo(43-47)OpenAIVideo(16-31)OpenAIVideoError(49-52)model/task.go (3)
Task(40-59)Task(248-252)Task(254-258)
🔇 Additional comments (3)
relay/common/relay_video.go (3)
8-14: LGTM!The video status constants are well-defined and cover the typical video processing lifecycle states.
37-42: LGTM!The lazy initialization of the metadata map is a good practice and the implementation is straightforward.
49-52: LGTM!The error structure is simple and appropriate for representing video processing errors.
| func (t TaskStatus) ToVideoStatus() string { | ||
| var status string | ||
| switch t { | ||
| case TaskStatusQueued, TaskStatusSubmitted: | ||
| status = commonRelay.VideoStatusQueued | ||
| case TaskStatusInProgress: | ||
| status = commonRelay.VideoStatusInProgress | ||
| case TaskStatusSuccess: | ||
| status = commonRelay.VideoStatusCompleted | ||
| case TaskStatusFailure: | ||
| status = commonRelay.VideoStatusFailed | ||
| default: | ||
| status = commonRelay.VideoStatusUnknown // Default fallback | ||
| } | ||
| return status | ||
| } |
There was a problem hiding this comment.
Map NOT_START to a valid video status
InitTask initializes tasks with TaskStatusNotStart, but ToVideoStatus() currently drops that into the default branch, returning "unknown". Downstream OpenAI-compatible clients expect queued/in-progress/etc.; returning unknown for every freshly created task is misleading and breaks status-based flows. Please map TaskStatusNotStart (and optionally any other pre-start aliases) to VideoStatusQueued.
- switch t {
- case TaskStatusQueued, TaskStatusSubmitted:
+ switch t {
+ case TaskStatusNotStart, TaskStatusQueued, TaskStatusSubmitted:📝 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 (t TaskStatus) ToVideoStatus() string { | |
| var status string | |
| switch t { | |
| case TaskStatusQueued, TaskStatusSubmitted: | |
| status = commonRelay.VideoStatusQueued | |
| case TaskStatusInProgress: | |
| status = commonRelay.VideoStatusInProgress | |
| case TaskStatusSuccess: | |
| status = commonRelay.VideoStatusCompleted | |
| case TaskStatusFailure: | |
| status = commonRelay.VideoStatusFailed | |
| default: | |
| status = commonRelay.VideoStatusUnknown // Default fallback | |
| } | |
| return status | |
| } | |
| func (t TaskStatus) ToVideoStatus() string { | |
| var status string | |
| switch t { | |
| case TaskStatusNotStart, TaskStatusQueued, TaskStatusSubmitted: | |
| status = commonRelay.VideoStatusQueued | |
| case TaskStatusInProgress: | |
| status = commonRelay.VideoStatusInProgress | |
| case TaskStatusSuccess: | |
| status = commonRelay.VideoStatusCompleted | |
| case TaskStatusFailure: | |
| status = commonRelay.VideoStatusFailed | |
| default: | |
| status = commonRelay.VideoStatusUnknown // Default fallback | |
| } | |
| return status | |
| } |
🤖 Prompt for AI Agents
In model/task.go around lines 13 to 28, ToVideoStatus currently maps
TaskStatusNotStart into the default "unknown"; update the switch to include a
case for TaskStatusNotStart (and any other pre-start aliases you have, e.g.,
TaskStatusInitialized) that assigns commonRelay.VideoStatusQueued so newly
created tasks report "queued" instead of "unknown". Keep existing cases intact
and return the status as before.
| ov := relaycommon.NewOpenAIVideo() | ||
| ov.ID = jResp.Data.TaskID | ||
| ov.TaskID = jResp.Data.TaskID | ||
| ov.CreatedAt = time.Now().Unix() | ||
| ov.Model = info.OriginModelName | ||
| c.JSON(http.StatusOK, ov) |
There was a problem hiding this comment.
Set creation response status to “queued”
OpenAIVideo.Status must be a valid enum value. Leaving it blank for Jimeng task submissions produces an invalid payload for SDK consumers. Initialize it to VideoStatusQueued when returning the creation acknowledgement.
ov := relaycommon.NewOpenAIVideo()
ov.ID = jResp.Data.TaskID
ov.TaskID = jResp.Data.TaskID
ov.CreatedAt = time.Now().Unix()
ov.Model = info.OriginModelName
+ ov.Status = relaycommon.VideoStatusQueued
c.JSON(http.StatusOK, ov)📝 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.
| ov := relaycommon.NewOpenAIVideo() | |
| ov.ID = jResp.Data.TaskID | |
| ov.TaskID = jResp.Data.TaskID | |
| ov.CreatedAt = time.Now().Unix() | |
| ov.Model = info.OriginModelName | |
| c.JSON(http.StatusOK, ov) | |
| ov := relaycommon.NewOpenAIVideo() | |
| ov.ID = jResp.Data.TaskID | |
| ov.TaskID = jResp.Data.TaskID | |
| ov.CreatedAt = time.Now().Unix() | |
| ov.Model = info.OriginModelName | |
| ov.Status = relaycommon.VideoStatusQueued | |
| c.JSON(http.StatusOK, ov) |
🤖 Prompt for AI Agents
In relay/channel/task/jimeng/adaptor.go around lines 160–165, the returned
OpenAIVideo is missing a valid Status enum; set ov.Status to the queued enum
value (relaycommon.VideoStatusQueued) before sending the JSON response so the
creation acknowledgement contains a valid status for SDK consumers.
| ov := relaycommon.NewOpenAIVideo() | ||
| ov.ID = kResp.Data.TaskId | ||
| ov.TaskID = kResp.Data.TaskId | ||
| ov.CreatedAt = time.Now().Unix() | ||
| ov.Model = info.OriginModelName | ||
| c.JSON(http.StatusOK, ov) | ||
| return kResp.Data.TaskId, responseBody, nil |
There was a problem hiding this comment.
Populate OpenAIVideo status on creation responses
OpenAIVideo.Status is left empty when we return the creation response, yet the OpenAI schema requires a concrete value (e.g. "queued"). Clients inspecting the enum will see an invalid blank status. Please initialize it—for a freshly submitted task, VideoStatusQueued (and optionally zero progress) is the expected value.
ov := relaycommon.NewOpenAIVideo()
ov.ID = kResp.Data.TaskId
ov.TaskID = kResp.Data.TaskId
ov.CreatedAt = time.Now().Unix()
ov.Model = info.OriginModelName
+ ov.Status = relaycommon.VideoStatusQueued
c.JSON(http.StatusOK, ov)🤖 Prompt for AI Agents
In relay/channel/task/kling/adaptor.go around lines 190 to 196,
OpenAIVideo.Status is left empty on creation responses which violates the OpenAI
schema; set ov.Status = relaycommon.VideoStatusQueued (and optionally
ov.Progress = 0 or 0.0 if the struct has a Progress field) before c.JSON so the
created task returns a concrete "queued" status and zero progress for new tasks.
| ov := relaycommon.NewOpenAIVideo() | ||
| ov.ID = vResp.TaskId | ||
| ov.TaskID = vResp.TaskId | ||
| ov.CreatedAt = time.Now().Unix() | ||
| ov.Model = info.OriginModelName | ||
| c.JSON(http.StatusOK, ov) | ||
| return vResp.TaskId, responseBody, nil |
There was a problem hiding this comment.
Return a valid status in the creation response
The OpenAI video schema expects status to be one of the defined enums, but the current response leaves it empty. For a just-created VIDU task, set it to VideoStatusQueued so downstream callers receive a valid value.
ov := relaycommon.NewOpenAIVideo()
ov.ID = vResp.TaskId
ov.TaskID = vResp.TaskId
ov.CreatedAt = time.Now().Unix()
ov.Model = info.OriginModelName
+ ov.Status = relaycommon.VideoStatusQueued
c.JSON(http.StatusOK, ov)📝 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.
| ov := relaycommon.NewOpenAIVideo() | |
| ov.ID = vResp.TaskId | |
| ov.TaskID = vResp.TaskId | |
| ov.CreatedAt = time.Now().Unix() | |
| ov.Model = info.OriginModelName | |
| c.JSON(http.StatusOK, ov) | |
| return vResp.TaskId, responseBody, nil | |
| ov := relaycommon.NewOpenAIVideo() | |
| ov.ID = vResp.TaskId | |
| ov.TaskID = vResp.TaskId | |
| ov.CreatedAt = time.Now().Unix() | |
| ov.Model = info.OriginModelName | |
| ov.Status = relaycommon.VideoStatusQueued | |
| c.JSON(http.StatusOK, ov) | |
| return vResp.TaskId, responseBody, nil |
🤖 Prompt for AI Agents
In relay/channel/task/vidu/adaptor.go around lines 158 to 164, the created
OpenAI video object is returned without a valid status; set its status to the
queued enum before sending/returning it (e.g., assign ov.Status =
relaycommon.VideoStatusQueued after creating ov) so the creation response
contains a valid VideoStatusQueued value for downstream callers.
|
|
||
| type OpenAIVideo struct { | ||
| ID string `json:"id"` | ||
| TaskID string `json:"task_id,omitempty"` //兼容旧接口 待废弃 |
There was a problem hiding this comment.
Clarify deprecation timeline for TaskID.
The deprecation comment lacks guidance on when TaskID will be removed or what users should migrate to. Consider adding a timeline or migration path in the comment.
Example:
TaskID string `json:"task_id,omitempty"` // Deprecated: use ID instead. Will be removed in v2.0.🤖 Prompt for AI Agents
In relay/common/relay_video.go around line 18, the inline comment on TaskID is
ambiguous about deprecation; update the comment to a proper Go-style deprecation
note that states the replacement field (e.g., ID), a removal version or
timeframe (e.g., "Will be removed in v2.0"), and brief migration guidance (e.g.,
"use ID instead"). Replace the current Chinese/ambiguous note with a clear
English deprecation tag such as: "Deprecated: use ID instead. Will be removed in
v2.0." and optionally add a one-line migration hint.
| func (m *OpenAIVideo) SetProgressStr(progress string) { | ||
| progress = strings.TrimSuffix(progress, "%") | ||
| m.Progress, _ = strconv.Atoi(progress) | ||
| } |
There was a problem hiding this comment.
Handle parsing errors in SetProgressStr.
The error from strconv.Atoi is silently ignored, which means invalid input like "abc" will result in Progress being set to 0 without any indication of failure. This could mask data quality issues and make debugging difficult.
Consider one of these approaches:
Option 1: Return the error
-func (m *OpenAIVideo) SetProgressStr(progress string) {
+func (m *OpenAIVideo) SetProgressStr(progress string) error {
progress = strings.TrimSuffix(progress, "%")
- m.Progress, _ = strconv.Atoi(progress)
+ var err error
+ m.Progress, err = strconv.Atoi(progress)
+ return err
}Option 2: Log the error and set a default
+import "log"
+
func (m *OpenAIVideo) SetProgressStr(progress string) {
progress = strings.TrimSuffix(progress, "%")
- m.Progress, _ = strconv.Atoi(progress)
+ var err error
+ m.Progress, err = strconv.Atoi(progress)
+ if err != nil {
+ log.Printf("Failed to parse progress '%s': %v", progress, err)
+ m.Progress = 0
+ }
}📝 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 (m *OpenAIVideo) SetProgressStr(progress string) { | |
| progress = strings.TrimSuffix(progress, "%") | |
| m.Progress, _ = strconv.Atoi(progress) | |
| } | |
| func (m *OpenAIVideo) SetProgressStr(progress string) error { | |
| progress = strings.TrimSuffix(progress, "%") | |
| var err error | |
| m.Progress, err = strconv.Atoi(progress) | |
| return err | |
| } |
🤖 Prompt for AI Agents
In relay/common/relay_video.go around lines 33 to 36, SetProgressStr silently
ignores strconv.Atoi errors which masks invalid input; either change
SetProgressStr to return an error (update callers) and propagate the
strconv.Atoi error, or keep the void signature but detect the error, log a
warning with the offending input and set m.Progress to a safe default (e.g., 0)
only on parse failure; implement one of these two approaches and ensure callers
or logs reflect the parse failure.
cd5f92c to
e08f799
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (3)
relay/channel/task/vidu/adaptor.go (1)
158-163: Set Status to VideoStatusQueued in creation response.The OpenAI video schema expects a valid status enum. For a newly submitted task, initialize
ov.Status = relaycommon.VideoStatusQueued.Apply this diff:
ov := relaycommon.NewOpenAIVideo() ov.ID = vResp.TaskId ov.TaskID = vResp.TaskId ov.CreatedAt = time.Now().Unix() ov.Model = info.OriginModelName + ov.Status = relaycommon.VideoStatusQueued c.JSON(http.StatusOK, ov)relay/channel/task/jimeng/adaptor.go (1)
161-166: Set Status to VideoStatusQueued in creation response.The returned OpenAIVideo lacks a valid status enum. Initialize
ov.Status = relaycommon.VideoStatusQueuedbefore sending the JSON response so SDK consumers receive a valid status.Apply this diff:
ov := relaycommon.NewOpenAIVideo() ov.ID = jResp.Data.TaskID ov.TaskID = jResp.Data.TaskID ov.CreatedAt = time.Now().Unix() ov.Model = info.OriginModelName + ov.Status = relaycommon.VideoStatusQueued c.JSON(http.StatusOK, ov)relay/channel/task/kling/adaptor.go (1)
191-196: Set Status to VideoStatusQueued in creation response.
OpenAIVideo.Statusmust be a valid enum value. Initializeov.Status = relaycommon.VideoStatusQueuedbefore returning the JSON response.Apply this diff:
ov := relaycommon.NewOpenAIVideo() ov.ID = kResp.Data.TaskId ov.TaskID = kResp.Data.TaskId ov.CreatedAt = time.Now().Unix() ov.Model = info.OriginModelName + ov.Status = relaycommon.VideoStatusQueued c.JSON(http.StatusOK, ov)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
model/task.go(1 hunks)relay/channel/task/jimeng/adaptor.go(2 hunks)relay/channel/task/kling/adaptor.go(2 hunks)relay/channel/task/vidu/adaptor.go(4 hunks)relay/common/relay_info.go(0 hunks)relay/common/relay_video.go(1 hunks)
💤 Files with no reviewable changes (1)
- relay/common/relay_info.go
🚧 Files skipped from review as they are similar to previous changes (1)
- model/task.go
🧰 Additional context used
🧬 Code graph analysis (3)
relay/channel/task/jimeng/adaptor.go (3)
relay/common/relay_video.go (3)
NewOpenAIVideo(43-47)OpenAIVideo(16-31)OpenAIVideoError(49-52)relay/channel/adapter.go (1)
TaskAdaptor(34-53)model/task.go (3)
Task(41-60)Task(249-253)Task(255-259)
relay/channel/task/kling/adaptor.go (2)
relay/common/relay_video.go (1)
NewOpenAIVideo(43-47)relay/channel/ali/dto.go (1)
TaskResult(70-75)
relay/channel/task/vidu/adaptor.go (4)
relay/channel/adapter.go (1)
TaskAdaptor(34-53)relay/common/relay_info.go (1)
RelayInfo(75-122)relay/common/relay_video.go (3)
NewOpenAIVideo(43-47)OpenAIVideo(16-31)OpenAIVideoError(49-52)model/task.go (3)
Task(41-60)Task(249-253)Task(255-259)
🔇 Additional comments (3)
relay/common/relay_video.go (1)
8-14: LGTM! Clean model definition and helper methods.The status constants, lazy-initialization pattern in
SetMetadata, and constructor follow Go best practices. The model provides a clear API for downstream adapters.Also applies to: 37-47, 49-52
relay/channel/task/vidu/adaptor.go (1)
266-291: LGTM! Robust OpenAIVideo conversion.The method correctly:
- Maps task status via
ToVideoStatus()- Uses
SetProgressStrfor safe progress handling- Conditionally sets metadata URL only when present
- Populates error details for failed tasks
relay/channel/task/kling/adaptor.go (1)
370-401: LGTM! Well-guarded OpenAIVideo conversion.The method properly:
- Maps status via
ToVideoStatus()- Checks video URL and duration presence before assigning
- Uses
SetMetadatafor conditional URL population- Sets error details only when code is non-zero
| openAIVideo.ID = originTask.TaskID | ||
| openAIVideo.Status = originTask.Status.ToVideoStatus() | ||
| openAIVideo.SetProgressStr(originTask.Progress) | ||
| openAIVideo.SetMetadata("url", jimengResp.Data.VideoUrl) |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major
Check VideoUrl before setting metadata.
Unlike the vidu and kling adapters (which verify URL presence), this unconditionally sets metadata even when VideoUrl is empty, polluting the metadata map with empty strings.
Apply this diff to align with the other adapters:
- openAIVideo.SetMetadata("url", jimengResp.Data.VideoUrl)
+ if jimengResp.Data.VideoUrl != "" {
+ openAIVideo.SetMetadata("url", jimengResp.Data.VideoUrl)
+ }📝 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.
| openAIVideo.SetMetadata("url", jimengResp.Data.VideoUrl) | |
| if jimengResp.Data.VideoUrl != "" { | |
| openAIVideo.SetMetadata("url", jimengResp.Data.VideoUrl) | |
| } |
🤖 Prompt for AI Agents
In relay/channel/task/jimeng/adaptor.go around line 418, the code
unconditionally sets openAIVideo metadata "url" to jimengResp.Data.VideoUrl
which can be empty; update it to check that jimengResp.Data.VideoUrl is
non-empty (e.g., len > 0 or != "") before calling openAIVideo.SetMetadata so the
metadata map is not populated with empty strings, following the same guard used
in the vidu and kling adapters.
…du-openai-sdk 即梦和vidu支持 OpenAI sdk生成和查询视频
import OpenAI from 'openai';
视频生成: await client.videos.create(requestParams);
视频查询: await client.videos.retrieve(taskId);
node create.js --prompt "美女跳舞" --model viduq1 --size=1080p --secends=5

Summary by CodeRabbit
New Features
Refactor