Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions relay/channel/task/sora/adaptor.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@ type responseTask struct {
Message string `json:"message"`
Code string `json:"code"`
} `json:"error,omitempty"`
// xAI grok-imagine-video returns the video URL directly in video.url,
// without a separate /content endpoint like OpenAI Sora.
Video *struct {
URL string `json:"url"`
Duration int `json:"duration,omitempty"`
} `json:"video,omitempty"`
}

// ============================
Expand Down Expand Up @@ -302,10 +308,14 @@ func (a *TaskAdaptor) ParseTaskResult(respBody []byte) (*relaycommon.TaskInfo, e
taskResult.Status = model.TaskStatusQueued
case "processing", "in_progress":
taskResult.Status = model.TaskStatusInProgress
case "completed":
case "completed", "done":
// "done" is the terminal success status returned by xAI grok-imagine-video.
taskResult.Status = model.TaskStatusSuccess
// Url intentionally left empty — the caller constructs the proxy URL using the public task ID
case "failed", "cancelled":
// xAI returns the video URL directly in video.url (no separate content endpoint).
if resTask.Video != nil && resTask.Video.URL != "" {
taskResult.Url = resTask.Video.URL
}
case "failed", "cancelled", "error":
taskResult.Status = model.TaskStatusFailure
if resTask.Error != nil {
taskResult.Reason = resTask.Error.Message
Expand Down
9 changes: 6 additions & 3 deletions service/task_polling.go
Original file line number Diff line number Diff line change
Expand Up @@ -502,9 +502,12 @@ func updateVideoSingleTask(ctx context.Context, adaptor TaskPollingAdaptor, ch *
// 其他错误认为是任务失败,记录错误信息并更新任务状态
taskResult = relaycommon.FailTaskInfo("upstream returned error")
} else {
// unknown error format, log original response
logger.LogError(ctx, fmt.Sprintf("Task %s returned empty status with unrecognized error format, response: %s", taskId, string(responseBody)))
taskResult = relaycommon.FailTaskInfo("upstream returned unrecognized message")
// Upstream may return a body without a status field in early/intermediate
// polling phases (e.g. xAI grok-imagine-video returns {"request_id":"...","id":"..."}
// before the task starts). Such a response is not an error — keep the current
// task status and wait for the next polling round instead of failing the task.
logger.LogInfo(ctx, fmt.Sprintf("Task %s returned empty status, will retry next poll. response: %s", taskId, string(responseBody)))
return nil
}
}
}
Expand Down
Loading