Skip to content

fix(task): support xAI grok-imagine-video task polling - #5927

Closed
u-wlkjyy wants to merge 1 commit into
QuantumNous:mainfrom
u-wlkjyy:fix/xai-video-task-parsing
Closed

fix(task): support xAI grok-imagine-video task polling#5927
u-wlkjyy wants to merge 1 commit into
QuantumNous:mainfrom
u-wlkjyy:fix/xai-video-task-parsing

Conversation

@u-wlkjyy

@u-wlkjyy u-wlkjyy commented Jul 6, 2026

Copy link
Copy Markdown

⚠️ 提交说明 / PR Notice

Important

  • 请提供人工撰写的简洁摘要,避免直接粘贴未经整理的 AI 输出。

📝 变更描述 / Description

xAI grok-imagine-video(以及 grok-imagine-video-previewgrok-image-video 等同系列模型)通过 OpenAI 渠道调用时,任务永远返回 FAILURE,错误信息为 upstream returned unrecognized message,但实际上游 xAI 已经成功生成视频。

根因是 xAI 的任务响应格式与 OpenAI Sora 存在 3 处差异,sora adaptor 完全没有适配:

问题 1:完成状态值不同

  • OpenAI Sora 返回 status: "completed"
  • xAI 返回 status: "done"
  • sora adaptor 的 ParseTaskResult 只匹配 "completed",导致 "done" 落入 default 分支,状态为空。

问题 2:视频 URL 位置不同

  • OpenAI Sora 不在任务响应里返回视频地址,需要单独请求 /v1/videos/{id}/content
  • xAI 直接在任务响应里返回 video.url
  • sora adaptor 的 responseTask struct 没有 video 字段,URL 被丢弃 → result_url 为空。

问题 3:空 status 被误判为失败(最致命)

  • xAI 在任务刚提交、尚未开始执行时,返回的响应完全没有 status 字段
    {"request_id":"b53c8bb4-...","id":"task_xxx"}
  • 原代码在 taskResult.Status == "" 时尝试解析为 OpenAI 错误格式,解析失败后直接调用 FailTaskInfo("upstream returned unrecognized message") 判定任务失败。
  • 这导致任务在第一轮轮询就被误杀,根本等不到后续的 "done" 状态。

修复

  1. relay/channel/task/sora/adaptor.goParseTaskResult 的 switch 增加 "done" case 映射为 TaskStatusSuccessresponseTask 增加 Video 字段,成功时从 video.url 提取结果地址。
  2. service/task_polling.go:空 status 且无法识别为 OpenAI 错误时,return nil 保持当前状态等待下一轮轮询,不再判定为失败。

🚀 变更类型 / Type of change

  • 🐛 Bug 修复 (Bug fix) - 请关联对应 Issue,避免将设计取舍、理解偏差或预期不一致直接归类为 bug

🔗 关联任务 / Related Issue

✅ 提交前检查项 / Checklist

📸 运行证明 / Proof of Work

修复前(任务卡在第一轮就被判失败):

[ERR] Task task_xxx returned empty status with unrecognized error format, response: {"request_id":"...","id":"task_xxx"}
[INFO] Task task_xxx failed: upstream returned unrecognized message

修复后(正常完成并提取到视频 URL):

[1] status=NOT_START progress=0%
[2] status=QUEUED progress=1%
[3] status=QUEUED progress=94%
[4] status=SUCCESS progress=100%
result_url: https://vidgen.x.ai/xai-vidgen-bucket/xai-video-xxx.mp4

响应对比(修复后 polling 拿到的 xAI 上游响应被正确解析):

{
  "data": {
    "status": "SUCCESS",
    "result_url": "https://vidgen.x.ai/xai-vidgen-bucket/xai-video-xxx.mp4",
    "data": {
      "status": "done",
      "video": {"url": "https://vidgen.x.ai/.../xxx.mp4", "duration": 8}
    }
  }
}

Summary by CodeRabbit

  • New Features

    • Video task results can now include a direct video URL, with duration support when available.
    • Task completion now recognizes both “completed” and “done” as successful terminal states.
  • Bug Fixes

    • Improved handling of upstream responses that don’t follow the expected error format, reducing false task failures.
    • Preserves task state for retry when polling receives an unstructured intermediate response.

xAI grok-imagine-video returns a different response shape than OpenAI
Sora, causing tasks to fail with 'upstream returned unrecognized
message' even when the video was generated successfully.

Three issues are fixed:

1. Status mapping: xAI returns status 'done' on completion, but the
   sora adaptor only recognized 'completed'. 'done' is now mapped to
   TaskStatusSuccess.

2. Result URL extraction: xAI embeds the video URL directly in
   video.url instead of exposing a separate /content endpoint. The
   responseTask struct now includes a Video field, and on success the
   URL is propagated to taskResult.Url.

3. Empty status handling: xAI returns {id, request_id} without a
   status field in early polling phases. The previous code treated
   this as an unrecognized error and failed the task immediately. It
   now keeps the current status and waits for the next polling round.

Related issue: #5045
@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b7c3aef7-3c4e-428b-acce-5859e0bed165

📥 Commits

Reviewing files that changed from the base of the PR and between 17465b8 and 6fc0348.

📒 Files selected for processing (2)
  • relay/channel/task/sora/adaptor.go
  • service/task_polling.go

Walkthrough

This PR adds video URL support to the Sora/xAI task adaptor, expanding success status handling and populating result URLs from a new video field, and modifies task polling to treat unrecognized empty-status upstream responses as retryable instead of failing the task.

Changes

Video Task Result and Polling Updates

Layer / File(s) Summary
Sora video result parsing
relay/channel/task/sora/adaptor.go
Adds a Video field (url, duration) to responseTask; ParseTaskResult now treats completed and done as success and sets taskResult.Url from resTask.Video.URL when present.
Polling retry on empty status
service/task_polling.go
updateVideoSingleTask now logs and returns without failing the task when the upstream response has an unrecognized empty status, preserving state for the next retry instead of calling FailTaskInfo.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

  • QuantumNous/new-api#3042: Also modifies updateVideoSingleTask in service/task_polling.go, changing how upstream status/URL responses are handled.

Poem

A rabbit hops through video streams,
Chasing URLs and polling dreams,
No more failing on an empty clue,
Just retry again, we'll see it through! 🐰🎬

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is clear and accurately reflects the main change: adding support for xAI grok-imagine-video task polling.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with 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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant