Skip to content

新增支持 Sora-2-Pro 1080P,支持 豆包视频 官方原生路由 - #4175

Closed
aabao325 wants to merge 11 commits into
QuantumNous:mainfrom
aabao325:main
Closed

新增支持 Sora-2-Pro 1080P,支持 豆包视频 官方原生路由#4175
aabao325 wants to merge 11 commits into
QuantumNous:mainfrom
aabao325:main

Conversation

@aabao325

@aabao325 aabao325 commented Apr 10, 2026

Copy link
Copy Markdown

⚠️ 提交说明 / PR Notice

Important

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

📝 变更描述 / Description

(简述:做了什么?为什么这样改能生效?请基于你对代码逻辑的理解来写,避免粘贴未经整理的内容)

🚀 变更类型 / Type of change

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

🔗 关联任务 / Related Issue

  • Closes # (如有)

✅ 提交前检查项 / Checklist

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

📸 运行证明 / Proof of Work

(请在此粘贴截图、关键日志或测试报告,以证明变更生效)

Summary by CodeRabbit

  • New Features

    • Added Doubao-native video generation endpoints for creating tasks and fetching task status.
    • Accepts Doubao-native request format and normalizes duration inputs for more consistent handling.
  • Bug Fixes / Improvements

    • Clearer image-size validation messages and expanded 1080p support for sora-2-pro.
    • Improved billing/size estimation for video requests based on model and resolution.

@coderabbitai

coderabbitai Bot commented Apr 10, 2026

Copy link
Copy Markdown
Contributor

Walkthrough

Adds Doubao-native request/response conversion: new Gin middleware translating Doubao video requests to internal /v1/video/generations format, router endpoints for Doubao-native API, Doubao-native response conversion path, and Sora size validation and billing ratio updates.

Changes

Cohort / File(s) Summary
Doubao Request Conversion Middleware
middleware/doubao_adapter.go
New Gin middleware DoubaoRequestConvert() that rewrites GET/POST Doubao-native requests into internal /v1/video/generations format, extracts text/images, repacks metadata, normalizes/extracts durations, replaces request body, and sets context flags.
Doubao Routes
router/video-router.go
Registers new route group /api/v3/contents/generations with middleware chain (RouteTag("relay"), DoubaoRequestConvert(), TokenAuth(), Distribute()) exposing POST /tasks and GET /tasks/:task_id.
Doubao Native Response Conversion
relay/channel/adapter.go, relay/channel/task/doubao/adaptor.go, relay/relay_task.go
Added DoubaoNativeResponseConverter interface and TaskAdaptor.ConvertToDoubaoNativeResponse; videoFetchByIDRespBodyBuilder now uses adapter conversion when doubao_native_route is set, with fallback to OpenAI converter and error handling for conversion failures.
Sora size validation & billing
relay/common/relay_utils.go, relay/channel/task/sora/adaptor.go
Tightened size validation messages (explicit 720p for sora-2, 720/1024/1080p for sora-2-pro) and updated EstimateBilling to compute model-specific size ratios (e.g., sora-2-pro uses 7/3 for 1080p, 5/3 for 1024p).

Sequence Diagram

sequenceDiagram
    participant Client as Doubao Client
    participant Router as Video Router
    participant Middleware as DoubaoRequestConvert
    participant Service as Internal Service (/v1/video/generations)
    participant Adaptor as Channel Adaptor (Sora / Doubao)

    Client->>Router: POST/GET /api/v3/contents/generations/...
    Router->>Middleware: pass request
    Middleware->>Middleware: parse body/path, extract prompt/images, normalize duration, build metadata
    Middleware->>Service: rewrite path/body -> /v1/video/generations
    Service->>Adaptor: create/relay task
    Adaptor->>Adaptor: estimate billing (size ratio) / process
    Adaptor-->>Service: task created / status
    Service-->>Client: response (middleware flag controls Doubao-native conversion on fetch)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • creamlike1024
  • Calcium-Ion

Poem

🐰
I hopped through bytes and request streams bright,
I packed prompts and images snug and tight.
Durations tamed, metadata in a row,
Routes aligned, Sora sizes now show.
Hooray — relay hops, and the videos go! 🎬

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the two main changes: adding Sora-2-Pro 1080P support and implementing Doubao video native routing, which directly align with the changeset.
Docstring Coverage ✅ Passed Docstring coverage is 80.00% which is sufficient. The required threshold is 80.00%.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ 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.

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@middleware/doubao_adapter.go`:
- Around line 82-90: The loop over nativeReq.Content currently overwrites prompt
for each "text" item (var prompt), losing earlier chunks; change the logic in
the switch case for item.Type == "text" to append each item.Text to prompt
(e.g., use strings.Builder or join with a separator) instead of assigning,
ensuring empty texts are skipped and preserving ordering; update any related
uses of prompt after the loop (the variables prompt and
nativeReq.Content/item.Text are the key identifiers to modify).
🪄 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: d9bcaeb3-dd18-418e-96d1-7490a2c4a7c9

📥 Commits

Reviewing files that changed from the base of the PR and between 0664bb3 and f84ac18.

📒 Files selected for processing (4)
  • middleware/doubao_adapter.go
  • relay/channel/task/sora/adaptor.go
  • relay/common/relay_utils.go
  • router/video-router.go

Comment thread middleware/doubao_adapter.go Outdated

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 1

🧹 Nitpick comments (2)
relay/channel/task/doubao/adaptor.go (1)

428-442: TaskStatusUnknown maps to "pending" via default case.

The internalStatusToDoubaoStatus helper defaults unknown statuses (including model.TaskStatusUnknown) to "pending". This is reasonable for most cases, but you may want to explicitly handle TaskStatusUnknown for clarity.

📝 Optional: Explicit handling of TaskStatusUnknown
 func internalStatusToDoubaoStatus(status model.TaskStatus) string {
 	switch status {
 	case model.TaskStatusQueued, model.TaskStatusSubmitted, model.TaskStatusNotStart:
 		return "pending"
 	case model.TaskStatusInProgress:
 		return "processing"
 	case model.TaskStatusSuccess:
 		return "succeeded"
 	case model.TaskStatusFailure:
 		return "failed"
+	case model.TaskStatusUnknown:
+		return "pending" // Treat unknown as pending
 	default:
 		return "pending"
 	}
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@relay/channel/task/doubao/adaptor.go` around lines 428 - 442, Add an explicit
case for model.TaskStatusUnknown in the internalStatusToDoubaoStatus function so
it maps to "pending" (instead of relying on the default case); update the switch
in internalStatusToDoubaoStatus to include case model.TaskStatusUnknown: return
"pending" for clarity and future-proofing.
middleware/doubao_adapter.go (1)

216-245: Consider handling negative duration values.

Both normalizeDuration and extractDurationSeconds accept any numeric input without validation. If a negative value is passed (e.g., {"value": -5}), it will be silently converted and used.

🛡️ Optional: Add non-negative validation
 func extractDurationSeconds(v interface{}) int {
 	switch d := v.(type) {
 	case float64:
+		if d < 0 {
+			return 0
+		}
 		return int(d)
 	case int:
+		if d < 0 {
+			return 0
+		}
 		return d
 	case map[string]interface{}:
 		if val, ok := d["value"]; ok {
 			return extractDurationSeconds(val)
 		}
 	}
 	return 0
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@middleware/doubao_adapter.go` around lines 216 - 245, The functions
normalizeDuration and extractDurationSeconds currently convert numeric values
without validation; update both to guard against negative durations by detecting
negative numbers (including when nested via map[string]interface{} recursion)
and returning a non-negative value instead—e.g., clamp negative results to 0
(normalizeDuration should return 0 for negative inputs and
extractDurationSeconds should return 0) so downstream code never receives a
negative duration; preserve the existing recursion behavior when unwrapping
{"value": ...}.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@relay/relay_task.go`:
- Around line 387-412: The fallback step currently ignores errors from
OpenAIVideoConverter.ConvertToOpenAIVideo; update the block that obtains adaptor
via GetTaskAdaptor(originTask.Platform) so that if adaptor implements
channel.OpenAIVideoConverter and ConvertToOpenAIVideo returns a non-nil error
you either log the error and/or set taskResp =
service.TaskErrorWrapper(convertErr, "convert_to_openai_video_failed",
http.StatusInternalServerError) and return (similar to how
ConvertToDoubaoNativeResponse errors are handled), ensuring the function does
not silently fall through and that respBody/taskResp is set consistently when
conversion fails.

---

Nitpick comments:
In `@middleware/doubao_adapter.go`:
- Around line 216-245: The functions normalizeDuration and
extractDurationSeconds currently convert numeric values without validation;
update both to guard against negative durations by detecting negative numbers
(including when nested via map[string]interface{} recursion) and returning a
non-negative value instead—e.g., clamp negative results to 0 (normalizeDuration
should return 0 for negative inputs and extractDurationSeconds should return 0)
so downstream code never receives a negative duration; preserve the existing
recursion behavior when unwrapping {"value": ...}.

In `@relay/channel/task/doubao/adaptor.go`:
- Around line 428-442: Add an explicit case for model.TaskStatusUnknown in the
internalStatusToDoubaoStatus function so it maps to "pending" (instead of
relying on the default case); update the switch in internalStatusToDoubaoStatus
to include case model.TaskStatusUnknown: return "pending" for clarity and
future-proofing.
🪄 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: 867e15ae-71fa-47eb-8697-ecc3dc96d7ef

📥 Commits

Reviewing files that changed from the base of the PR and between f84ac18 and fa42bcc.

📒 Files selected for processing (4)
  • middleware/doubao_adapter.go
  • relay/channel/adapter.go
  • relay/channel/task/doubao/adaptor.go
  • relay/relay_task.go

Comment thread relay/relay_task.go
@aabao325

Copy link
Copy Markdown
Author

已测试通过

@aabao325 aabao325 closed this Apr 10, 2026
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