Skip to content

fix video task successful upstream result parsing - #5805

Open
CarminBack wants to merge 24 commits into
QuantumNous:mainfrom
CarminBack:video-task-result-fix
Open

fix video task successful upstream result parsing#5805
CarminBack wants to merge 24 commits into
QuantumNous:mainfrom
CarminBack:video-task-result-fix

Conversation

@CarminBack

@CarminBack CarminBack commented Jun 29, 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 “按秒计费” (Pay per second) support across pricing settings, UI filters/tags, and unit display.
  • Documentation
    • Added documentation for Seedance NewAPI video integration.
    • Added documentation for Grok NewAPI-compatible video generation.
  • Bug Fixes
    • Improved video task polling to correctly recognize successful nested results, mark completion properly, and extract the result URL.
    • Prevented real upstream failures from being misclassified as successes.
    • Fixed quota recalculation for per-call model tasks.
  • Tests
    • Added unit coverage for nested success normalization/URL extraction and per-call quota computation.

@coderabbitai

coderabbitai Bot commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds nested video success normalization in task polling, per-call-aware relay quota recalculation, per-second billing support across pricing logic and UI, and new Seedance and Grok video documentation.

Changes

Nested Video Success Normalization

Layer / File(s) Summary
Internal normalization helpers
service/task_polling.go
Adds helpers that detect success-like upstream statuses, extract nested video URLs from several JSON shapes, and rewrite failure-shaped task results to success when the reason matches an unrecognized-message pattern.
Polling path normalization
service/task_polling.go
Invokes the normalization helper after new-API parsing and falls back to inspecting the raw response body when task status is empty, setting success, URL, and complete progress when a nested success is found.
Normalization tests
service/task_billing_test.go
Adds tests for successful nested-video normalization, preservation of real failures, and nested video URL extraction from raw JSON, plus the import needed for progress assertions.

Per-call Relay Quota Recalculation

Layer / File(s) Summary
Per-call quota handling
relay/relay_task.go
Introduces a per-call model helper, uses it to gate initial ratio scaling, and passes the per-call flag into quota recomputation so per-call models keep the stored quota.
Quota recalculation tests
relay/relay_task_test.go
Adds unit tests that verify per-call mode preserves the base quota and non-per-call mode applies adjusted ratios.

Per-second Billing Labels

Layer / File(s) Summary
Per-second billing classification
model/pricing.go
Marks models with the per-second tag as quota type 2 during pricing updates.
Per-second price calculation
web/src/helpers/utils.jsx
Extends model price calculation and fixed-price display formatting to carry a per-second unit alongside the existing per-request path.
Per-second billing UI labels
web/src/components/table/model-pricing/filter/PricingQuotaTypes.jsx, web/src/components/table/model-pricing/modal/components/ModelPricingTable.jsx, web/src/components/table/model-pricing/view/card/PricingCardView.jsx, web/src/components/table/model-pricing/view/table/PricingTableColumns.jsx, web/src/i18n/locales/en.json, web/src/i18n/locales/zh-CN.json
Adds quota type 2 options, tags, table rendering, card rendering, and localized labels for the per-second billing type.

Video Integration Docs

Layer / File(s) Summary
Seedance integration guide
docs/seedance-video-integration.md
Adds Seedance video integration guidance for public endpoints, public model aliases, billing rules, marketplace metadata, channel notes, and verification commands.
Grok video API guide
docs/grok-video-api.md
Adds Grok video API usage, request and response formats, model-specific constraints, polling flow, and completed response examples.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Suggested reviewers

  • Calcium-Ion
  • creamlike1024

Poem

🐇 I hopped through JSON, bright and neat,
Found secret success in nested heat.
Per-second tags now ring a bell,
Quotas and docs all flow quite well.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 11.11% 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 title clearly matches the main fix: parsing successful upstream video task results correctly.
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.

@CarminBack

Copy link
Copy Markdown
Author

修复问题 上游返回成功本地可能显示失败

@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.

🧹 Nitpick comments (1)
service/task_polling.go (1)

551-564: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

output extraction only handles arrays of plain strings.

Several upstream video providers return output as an array of objects (e.g. [{"url": "..."}]) rather than bare strings. The current stringValue(item) skips those, so a nested success could be missed. Consider handling map[string]any items as well if such shapes are expected from your providers.

🤖 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 `@service/task_polling.go` around lines 551 - 564, The nested video URL
extraction in extractNestedVideoURL only reads output items as plain strings, so
object-shaped entries are missed. Update the output loop to also recognize
map[string]any items and extract a URL from common fields like url, video_url,
or result_url, while preserving the existing string handling and return
behavior.
🤖 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 `@service/task_polling.go`:
- Around line 551-564: The nested video URL extraction in extractNestedVideoURL
only reads output items as plain strings, so object-shaped entries are missed.
Update the output loop to also recognize map[string]any items and extract a URL
from common fields like url, video_url, or result_url, while preserving the
existing string handling and return behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 001d1143-3c53-4c70-a5b5-000b06c5f61a

📥 Commits

Reviewing files that changed from the base of the PR and between 43591fb and 0bad71e.

📒 Files selected for processing (2)
  • service/task_billing_test.go
  • service/task_polling.go

@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 current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@model/pricing.go`:
- Around line 298-301: The pricing serialization in the quota type branch is
introducing a new value that the existing pricing sync consumer does not
understand. Update the logic around the pricing quota assignment so that the
code in model/pricing.go and the downstream parser in controller/ratio_sync.go
stay in sync: either keep per-second entries serialized as quota_type 1 for now,
or extend the ratio_sync parsing path to treat quota_type 2 as fixed-price and
read model_price instead of ratio fields. Ensure the existing /api/pricing
contract remains consistent with the behavior of the sync code.
🪄 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: e798d1c1-de1e-4654-b72b-b587c28846c1

📥 Commits

Reviewing files that changed from the base of the PR and between 6cff1be and 275c96a.

📒 Files selected for processing (8)
  • model/pricing.go
  • web/src/components/table/model-pricing/filter/PricingQuotaTypes.jsx
  • web/src/components/table/model-pricing/modal/components/ModelPricingTable.jsx
  • web/src/components/table/model-pricing/view/card/PricingCardView.jsx
  • web/src/components/table/model-pricing/view/table/PricingTableColumns.jsx
  • web/src/helpers/utils.jsx
  • web/src/i18n/locales/en.json
  • web/src/i18n/locales/zh-CN.json
✅ Files skipped from review due to trivial changes (2)
  • web/src/i18n/locales/zh-CN.json
  • web/src/i18n/locales/en.json

Comment thread model/pricing.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 (1)
docs/seedance-video-integration.md (1)

140-144: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Restructure repeated "Keep" sentences to improve readability.

Lines 140-144 start three successive bullet points with "Keep". Vary the sentence structure or merge related points for better flow.

- - Keep the public aliases in `channels.models`.
- - Keep `channels.model_mapping` mapping each public alias to the raw upstream model.
- - Keep raw upstream Seedance model names out of `abilities`.
- - Keep raw upstream Seedance model metadata disabled with `models.status = 0`.
+ - Store public aliases in `channels.models`.
+ - Map each public alias to its raw upstream model via `channels.model_mapping`.
+ - Exclude raw upstream Seedance model names from `abilities`.
+ - Disable raw upstream Seedance model metadata with `models.status = 0`.
🤖 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 `@docs/seedance-video-integration.md` around lines 140 - 144, The repeated
“Keep” bullets in the Seedance integration notes should be rewritten for
readability. Update the affected bullet list in the documentation so the related
constraints are grouped more naturally and the sentence openings vary, while
still preserving the guidance about channels.models, channels.model_mapping,
abilities, models.status, and channel 17 auto-sync behavior.
🤖 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 `@docs/seedance-video-integration.md`:
- Line 152: The jq verification command is over-escaping the dot in the
model_name regex, so the pattern passed to jq does not match seedance-2.0 as
intended. Update the select(...test(...)) expression in the verification command
to use the correct escaping inside the single-quoted shell string so jq receives
an escaped dot pattern, and confirm the regex still matches only the Seedance
2.0 model names.

---

Nitpick comments:
In `@docs/seedance-video-integration.md`:
- Around line 140-144: The repeated “Keep” bullets in the Seedance integration
notes should be rewritten for readability. Update the affected bullet list in
the documentation so the related constraints are grouped more naturally and the
sentence openings vary, while still preserving the guidance about
channels.models, channels.model_mapping, abilities, models.status, and channel
17 auto-sync behavior.
🪄 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: 3a866e84-7a1e-4cd2-90b5-07840b380864

📥 Commits

Reviewing files that changed from the base of the PR and between 275c96a and bf45c77.

📒 Files selected for processing (1)
  • docs/seedance-video-integration.md


```bash
curl -sS 'https://token.mewinyou.shop/api/pricing' \
| jq -r '.data[]? | select(.model_name|test("^[0-9]+:seedance-2\\\\.0")) | .model_name'

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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Fix jq regex escaping in verification command.

The pattern seedance-2\\\\.0 in a single-quoted shell string produces seedance-2\\\.0 passed to jq, where jq likely sees \\. (literal backslash-dot) rather than \. (escaped dot). Use seedance-2\\\.0 or seedance-2\\.0 inside single quotes so jq receives seedance-2\.0.

-  | jq -r '.data[]? | select(.model_name|test("^[0-9]+:seedance-2\\\\.0")) | .model_name'
+  | jq -r '.data[]? | select(.model_name|test("^[0-9]+:seedance-2\\.0")) | .model_name'
📝 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
| jq -r '.data[]? | select(.model_name|test("^[0-9]+:seedance-2\\\\.0")) | .model_name'
| jq -r '.data[]? | select(.model_name|test("^[0-9]+:seedance-2\\.0")) | .model_name'
🤖 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 `@docs/seedance-video-integration.md` at line 152, The jq verification command
is over-escaping the dot in the model_name regex, so the pattern passed to jq
does not match seedance-2.0 as intended. Update the select(...test(...))
expression in the verification command to use the correct escaping inside the
single-quoted shell string so jq receives an escaped dot pattern, and confirm
the regex still matches only the Seedance 2.0 model names.

@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.

🧹 Nitpick comments (4)
docs/grok-video-api.md (4)

169-181: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Rename "Success Response" to "Initial Response" or "Creation Response".

The example shows status: "queued", which is the initial creation response, not a successful completion. The title is misleading.

🤖 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 `@docs/grok-video-api.md` around lines 169 - 181, The response heading in the
Grok video API docs is misleading because the example payload from the queued
task creation flow is not a completed success state. Update the section title
around the JSON example to “Initial Response” or “Creation Response” so it
matches the queued status shown by the video task response.

5-6: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Clarify or remove the misspelled domain note.

Documenting tokne.mewinyou.shop as a possible valid endpoint risks confusing users. If it is a typo, remove it; if it is an actual alternate domain, explain why both spellings exist (e.g., legacy alias, regional deployment).

🤖 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 `@docs/grok-video-api.md` around lines 5 - 6, Clarify the endpoint note in the
grok-video-api documentation by either removing the misspelled
tokne.mewinyou.shop reference or explicitly explaining why it is a valid
alternate domain. Update the relevant note text so the URL guidance is
unambiguous, and keep the production base URL description in sync with the
actual expected endpoint.

33-33: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Clarify seconds type flexibility.

integer or string is ambiguous. If the API coerces string numerics (e.g., "4"), document that; otherwise restrict to integer.

🤖 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 `@docs/grok-video-api.md` at line 33, Clarify the `seconds` field type in the
video API documentation by updating the schema description to match the actual
behavior of the request parser. In the `seconds` row, either explicitly state
that numeric strings are accepted and coerced (for example, `"4"`), or change
the type to integer only if string values are not supported. Make the wording in
`grok-video-api` unambiguous so users know exactly what `seconds` accepts.

209-212: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Remove or clarify the vague normalization note.

"The exact field may depend on upstream response normalization" undermines API contract confidence. Since this PR specifically fixes normalization, document the guaranteed field (result_url) or describe the concrete normalization behavior.

🤖 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 `@docs/grok-video-api.md` around lines 209 - 212, The “Completed Response”
section is too vague because the note about upstream response normalization
weakens the API contract; update the documentation in the grok video API spec to
either explicitly guarantee the normalized result field as result_url or clearly
describe the exact normalization behavior implemented by the response handling
path. Refer to the Completed Response wording in the docs and align it with the
concrete contract exposed by the NewAPI response so readers know precisely which
field to expect.
🤖 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 `@docs/grok-video-api.md`:
- Around line 169-181: The response heading in the Grok video API docs is
misleading because the example payload from the queued task creation flow is not
a completed success state. Update the section title around the JSON example to
“Initial Response” or “Creation Response” so it matches the queued status shown
by the video task response.
- Around line 5-6: Clarify the endpoint note in the grok-video-api documentation
by either removing the misspelled tokne.mewinyou.shop reference or explicitly
explaining why it is a valid alternate domain. Update the relevant note text so
the URL guidance is unambiguous, and keep the production base URL description in
sync with the actual expected endpoint.
- Line 33: Clarify the `seconds` field type in the video API documentation by
updating the schema description to match the actual behavior of the request
parser. In the `seconds` row, either explicitly state that numeric strings are
accepted and coerced (for example, `"4"`), or change the type to integer only if
string values are not supported. Make the wording in `grok-video-api`
unambiguous so users know exactly what `seconds` accepts.
- Around line 209-212: The “Completed Response” section is too vague because the
note about upstream response normalization weakens the API contract; update the
documentation in the grok video API spec to either explicitly guarantee the
normalized result field as result_url or clearly describe the exact
normalization behavior implemented by the response handling path. Refer to the
Completed Response wording in the docs and align it with the concrete contract
exposed by the NewAPI response so readers know precisely which field to expect.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2b51b465-03c0-47ed-9cfa-1edaedfdc263

📥 Commits

Reviewing files that changed from the base of the PR and between bf45c77 and 37a6e53.

📒 Files selected for processing (1)
  • docs/grok-video-api.md

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