Skip to content

feat: support Wan2.7 i2v media mapping#4984

Open
wxwwt wants to merge 1 commit into
QuantumNous:mainfrom
wxwwt:feature/wan27-i2v-media
Open

feat: support Wan2.7 i2v media mapping#4984
wxwwt wants to merge 1 commit into
QuantumNous:mainfrom
wxwwt:feature/wan27-i2v-media

Conversation

@wxwwt
Copy link
Copy Markdown

@wxwwt wxwwt commented May 20, 2026

⚠️ 提交说明 / PR Notice

Important

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

📝 变更描述 / Description

本次为 Ali 视频生成渠道补充 Wan2.7 图生视频协议适配。

Wan2.7 I2V 使用的是新的 input.media 入参格式,而当前 Ali adaptor 仍主要按旧版 img_url / first_frame_url / last_frame_url 字段组织请求。这个改动在 wan2.7-i2v 场景下将通用视频请求里的 imageimagesinput_reference 映射为 DashScope 所需的 input.media

  • 单图会映射为 type: first_frame
  • 双图会映射为 first_frame + last_frame
  • 显式传入的 metadata.input.media 会被保留
  • 旧版 Wan I2V 模型仍继续使用原有 img_url 逻辑

同时补充了 wan2.7-i2vwan2.7-t2v 到 Ali task model list,并让 direct video request 路径兼容单图 image 字段,避免图生视频请求没有被识别为带图任务。

🚀 变更类型 / Type of change

  • 🐛 Bug 修复 (Bug fix) - 请关联对应 Issue,避免将设计取舍、理解偏差或预期不一致直接归类为 bug
  • ✨ 新功能 (New feature) - 重大特性建议先通过 Issue 沟通
  • ⚡ 性能优化 / 重构 (Refactor)
  • 📝 文档更新 (Documentation)

🔗 关联任务 / Related Issue

  • N/A

✅ 提交前检查项 / Checklist

  • 人工确认: 我已亲自整理并撰写此描述,没有直接粘贴未经处理的 AI 输出。
  • 非重复提交: 我已搜索现有的 IssuesPRs,确认不是重复提交。
  • Bug fix 说明: 若此 PR 标记为 Bug fix,我已提交或关联对应 Issue,且不会将设计取舍、预期不一致或理解偏差直接归类为 bug。
  • 变更理解: 我已理解这些更改的工作原理及可能影响。
  • 范围聚焦: 本 PR 未包含任何与当前任务无关的代码改动。
  • 本地验证: 已在本地运行并通过测试或手动验证,维护者可以据此复核结果。
  • 安全合规: 代码中无敏感凭据,且符合项目代码规范。

📸 运行证明 / Proof of Work

go test ./relay/channel/task/ali ./relay/common

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

* **New Features**
  * Added support for the "wan2.7-i2v" image-to-video model with a new media-based input protocol.
  * Single-image uploads are normalized so they work across model versions.

* **Bug Fixes**
  * Validation now enforces presence of derived media for wan2.7-i2v and returns clearer errors when missing.
  * Legacy single-field inputs are isolated to prevent mixing old and new media semantics.

* **Tests**
  * Unit tests covering wan2.7-i2v, legacy behavior, and image-field normalization.

<!-- review_stack_entry_start -->

[![Review Change Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/QuantumNous/new-api/pull/4984?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)

<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 20, 2026

Walkthrough

Adds Wan2.7-i2v image-to-video support to the Ali adaptor: new media schema, normalization that maps task images to media items (first/last frame, driving audio), validation requiring image sources, conversion integration, model registration, and tests plus upstream single-image compatibility.

Changes

Wan2.7-i2v Image-to-Video Support

Layer / File(s) Summary
Data structures for media protocol
relay/channel/task/ali/adaptor.go
Introduces AliVideoMedia and adds Media []AliVideoMedia to AliVideoInput and AliMetadata.
Input normalization for Wan2.7-i2v
relay/channel/task/ali/adaptor.go
Implements normalization that synthesizes first_frame, last_frame, and driving_audio from task images when input.media is empty, errors if no image source, and clears legacy single-field inputs.
Request conversion and normalization integration
relay/channel/task/ali/adaptor.go
Populates AliVideoInput.ImgURL from the task’s first image and invokes the Wan2.7-i2v normalization before returning the request.
Model registration
relay/channel/task/ali/constants.go
Adds "wan2.7-i2v" to the Ali ModelList.
Comprehensive adaptor tests
relay/channel/task/ali/adaptor_test.go
Adds tests for convertToAliRequest covering wan2.7-i2v single/multi-image media mapping, explicit metadata media, validation error on missing images, and backward compatibility with wan2.5-i2v-preview.
Upstream request validation for single image field
relay/common/relay_utils.go
Normalizes a single image field into images when InputReference and Images are absent.
Request validation tests
relay/common/relay_utils_test.go
Adds test verifying ValidateMultipartDirect normalizes image into images and sets the task action.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • QuantumNous/new-api#2141: Prior introduction and earlier changes to the Ali adaptor and model list that this PR extends for Wan2.7-i2v media handling.
  • QuantumNous/new-api#1788: Related work around TaskSubmitReq.Images and image-field normalization used by ValidateMultipartDirect.

Suggested reviewers

  • creamlike1024
  • Calcium-Ion

Poem

🐰 I stitched the frames from first to last with care,
A hop, a glance, a driving audio there.
Wan2.7 hums as images align,
Media lists march forward, neat and fine.
Hooray — the rabbit cheers for video flair!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'feat: support Wan2.7 i2v media mapping' directly summarizes the main change: adding support for Wan2.7 image-to-video media mapping. It is concise, clear, and clearly conveys the primary feature being introduced.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@relay/channel/task/ali/adaptor.go`:
- Around line 276-287: The helper firstTaskImage currently returns
InputReference before the newer direct-image fields; change its selection order
to prefer req.Image, then the first element of req.Images, and only fall back to
req.InputReference, so direct-image fields win; apply the same ordering change
to the other analogous helper used later (the one with the same logic around the
other task-image extraction) so both places derive img_url/first_frame from
Image/Images first.

In `@relay/common/relay_utils.go`:
- Around line 142-144: The code checks strings.TrimSpace(req.Image) but stores
the raw req.Image, allowing surrounding spaces to propagate; update the branch
that handles single-image compatibility so you store the trimmed value (e.g.,
use the trimmed string of req.Image when assigning to req.Images) — locate the
conditional around req.Images and req.Image in relay_utils.go and replace the
assignment to req.Images with the normalized/trimmed image string.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 32d16b1f-b3a9-456a-96a5-c57880d83d72

📥 Commits

Reviewing files that changed from the base of the PR and between 20d3e73 and e1153ab.

📒 Files selected for processing (5)
  • relay/channel/task/ali/adaptor.go
  • relay/channel/task/ali/adaptor_test.go
  • relay/channel/task/ali/constants.go
  • relay/common/relay_utils.go
  • relay/common/relay_utils_test.go

Comment thread relay/channel/task/ali/adaptor.go
Comment on lines +142 to +144
} else if len(req.Images) == 0 && strings.TrimSpace(req.Image) != "" {
// 兼容单图上传
req.Images = []string{req.Image}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Trim the normalized image value before storing it.

Line 142 checks strings.TrimSpace(req.Image), but Line 144 stores the raw value. If the input has surrounding spaces, an invalid URL string is propagated.

Suggested patch
 	} else if len(req.Images) == 0 && strings.TrimSpace(req.Image) != "" {
 		// 兼容单图上传
-		req.Images = []string{req.Image}
+		req.Images = []string{strings.TrimSpace(req.Image)}
 	}
📝 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.

Suggested change
} else if len(req.Images) == 0 && strings.TrimSpace(req.Image) != "" {
// 兼容单图上传
req.Images = []string{req.Image}
} else if len(req.Images) == 0 && strings.TrimSpace(req.Image) != "" {
// 兼容单图上传
req.Images = []string{strings.TrimSpace(req.Image)}
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@relay/common/relay_utils.go` around lines 142 - 144, The code checks
strings.TrimSpace(req.Image) but stores the raw req.Image, allowing surrounding
spaces to propagate; update the branch that handles single-image compatibility
so you store the trimmed value (e.g., use the trimmed string of req.Image when
assigning to req.Images) — locate the conditional around req.Images and
req.Image in relay_utils.go and replace the assignment to req.Images with the
normalized/trimmed image string.

@wxwwt wxwwt force-pushed the feature/wan27-i2v-media branch from e1153ab to e4cbbde Compare May 20, 2026 05:52
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
relay/channel/task/ali/adaptor_test.go (1)

18-121: ⚡ Quick win

Add one regression test for mixed-source precedence (image/images + input_reference).

Current cases are solid, but they don’t lock behavior when both legacy and direct image fields are sent together—the exact edge where source selection can drift.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@relay/channel/task/ali/adaptor_test.go` around lines 18 - 121, Add a
regression test named TestConvertToAliRequestMixedSourcePrecedence in
adaptor_test.go that constructs a TaskAdaptor and a relaycommon.TaskSubmitReq
for model "wan2.7-i2v" with both Image/Images set and Metadata containing an
explicit input.media (or input_reference) entry; call
adaptor.convertToAliRequest(testRelayInfo(), req) and assert no error, then
assert that aliReq.Input.Media equals the metadata-provided media (not the
Image/Images), aliReq.Input.ImgURL is empty, and the marshaled body contains
"media" and does not contain "img_url" to lock precedence of explicit metadata
over image/images.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@relay/channel/task/ali/adaptor_test.go`:
- Around line 18-121: Add a regression test named
TestConvertToAliRequestMixedSourcePrecedence in adaptor_test.go that constructs
a TaskAdaptor and a relaycommon.TaskSubmitReq for model "wan2.7-i2v" with both
Image/Images set and Metadata containing an explicit input.media (or
input_reference) entry; call adaptor.convertToAliRequest(testRelayInfo(), req)
and assert no error, then assert that aliReq.Input.Media equals the
metadata-provided media (not the Image/Images), aliReq.Input.ImgURL is empty,
and the marshaled body contains "media" and does not contain "img_url" to lock
precedence of explicit metadata over image/images.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 22828849-f2f5-4463-80b4-ed50c1ac891b

📥 Commits

Reviewing files that changed from the base of the PR and between e1153ab and e4cbbde.

📒 Files selected for processing (5)
  • relay/channel/task/ali/adaptor.go
  • relay/channel/task/ali/adaptor_test.go
  • relay/channel/task/ali/constants.go
  • relay/common/relay_utils.go
  • relay/common/relay_utils_test.go

@wxwwt wxwwt force-pushed the feature/wan27-i2v-media branch from e4cbbde to c19ecd8 Compare May 20, 2026 05:57
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (2)
relay/common/relay_utils.go (1)

142-144: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Trim the normalized single-image value before storing it.

Line 142 trims for validation, but Line 144 stores the raw string. This can propagate leading/trailing spaces into req.Images.

Suggested patch
-	} else if len(req.Images) == 0 && strings.TrimSpace(req.Image) != "" {
+	} else if len(req.Images) == 0 && strings.TrimSpace(req.Image) != "" {
 		// 兼容单图上传
-		req.Images = []string{req.Image}
+		req.Images = []string{strings.TrimSpace(req.Image)}
 	}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@relay/common/relay_utils.go` around lines 142 - 144, The code validates with
strings.TrimSpace(req.Image) but then stores the untrimmed value into
req.Images, so update the branch that handles single-image compatibility to
assign the trimmed value: compute trimmed := strings.TrimSpace(req.Image) (or
reuse the trimmed value used for validation) and set req.Images =
[]string{trimmed} instead of using req.Image; ensure req.Image remains unchanged
only if needed elsewhere or optionally overwrite req.Image with the trimmed
value for consistency.
relay/channel/task/ali/adaptor.go (1)

276-287: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Prefer image/images over input_reference in firstTaskImage.

This still picks input_reference first, so when a request carries both the new direct-image fields and the legacy reference, Wan2.7 media derivation can send the wrong first frame. Because Line 348 reuses this helper, the legacy img_url path inherits the same bug. Reorder the fallback to imageimages[0]input_reference, and trim whitespace so blank values do not block later candidates.

Suggested fix
 func firstTaskImage(req relaycommon.TaskSubmitReq) string {
-	if req.InputReference != "" {
-		return req.InputReference
-	}
-	if req.Image != "" {
+	if strings.TrimSpace(req.Image) != "" {
 		return req.Image
 	}
-	if len(req.Images) > 0 {
+	if len(req.Images) > 0 && strings.TrimSpace(req.Images[0]) != "" {
 		return req.Images[0]
 	}
+	if strings.TrimSpace(req.InputReference) != "" {
+		return req.InputReference
+	}
 	return ""
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@relay/channel/task/ali/adaptor.go` around lines 276 - 287, The helper
firstTaskImage currently prefers input_reference first and doesn't trim blanks;
change its fallback order to prefer req.Image, then req.Images[0], then
req.InputReference, and ensure you trim whitespace from each candidate so empty
or whitespace-only values don't block later options; update the logic in
function firstTaskImage (used elsewhere, e.g., the legacy img_url path) to check
strings.TrimSpace(req.Image), iterate images checking strings.TrimSpace on each
entry, and finally use strings.TrimSpace(req.InputReference) as the last resort.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Duplicate comments:
In `@relay/channel/task/ali/adaptor.go`:
- Around line 276-287: The helper firstTaskImage currently prefers
input_reference first and doesn't trim blanks; change its fallback order to
prefer req.Image, then req.Images[0], then req.InputReference, and ensure you
trim whitespace from each candidate so empty or whitespace-only values don't
block later options; update the logic in function firstTaskImage (used
elsewhere, e.g., the legacy img_url path) to check strings.TrimSpace(req.Image),
iterate images checking strings.TrimSpace on each entry, and finally use
strings.TrimSpace(req.InputReference) as the last resort.

In `@relay/common/relay_utils.go`:
- Around line 142-144: The code validates with strings.TrimSpace(req.Image) but
then stores the untrimmed value into req.Images, so update the branch that
handles single-image compatibility to assign the trimmed value: compute trimmed
:= strings.TrimSpace(req.Image) (or reuse the trimmed value used for validation)
and set req.Images = []string{trimmed} instead of using req.Image; ensure
req.Image remains unchanged only if needed elsewhere or optionally overwrite
req.Image with the trimmed value for consistency.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 807d1228-441b-4f1f-a65a-7b8b46fda618

📥 Commits

Reviewing files that changed from the base of the PR and between e4cbbde and c19ecd8.

📒 Files selected for processing (5)
  • relay/channel/task/ali/adaptor.go
  • relay/channel/task/ali/adaptor_test.go
  • relay/channel/task/ali/constants.go
  • relay/common/relay_utils.go
  • relay/common/relay_utils_test.go
✅ Files skipped from review due to trivial changes (1)
  • relay/channel/task/ali/constants.go

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