Feat:豆包视频端点支持、视频模型计费支持、异步任务页面优化 - #713
Open
NyaDoo wants to merge 2 commits into
Open
Conversation
Expose Volcengine Ark's content generation task surface at /v3/contents/generations/tasks as a third video contract alongside openai:video and gemini:video. The three share the video_tasks table, the polling worker and the billing pipeline, but keep separate client contracts, route classification and plan kinds. Request modeling keeps a minimal whitelist (model, content text, ratio, resolution, duration, callback_url) and passes everything else through verbatim, so Ark parameters such as generate_audio and multi-modal content entries keep working without a gateway change. Notable decisions: - callback_url is rejected with 400. The gateway owns task state, so an upstream callback would bypass it and leak the upstream task id. Silently stripping it would leave clients waiting forever. - The task list is served from gateway state rather than proxied, which would return every task owned by the shared provider key across all tenants. - Downloads are proxied instead of handing out content.video_url, whose signed URL expires within a day. - The upstream base URL is appended to verbatim; no API-root segment is inferred, so a misconfigured base stays visible in the resulting URL instead of being silently repaired. - usage.completion_tokens is recorded as output_tokens, since Ark bills video generation by tokens unlike the per-second video surfaces. Also reports upstream failures with their status code instead of a generic "no execution path" miss. That applies to every AI surface, not just Doubao, and only fires when all candidates actually reached an upstream and were refused there. A one-way openai:video to doubao:video request conversion is included so Sora clients can target Doubao providers. The reverse is deliberately not implemented: Ark requests carry reference video/audio, multiple images and generate_audio, none of which Sora can express, so it would fail on most real requests. Cross-format candidate selection is not wired up yet, so the conversion is not reachable end to end. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Video tasks recorded their tokens but always settled at zero cost: the admin UI wrote billing.video.price_per_second_by_resolution, yet no Rust code ever read it. Nothing in the pipeline could turn a finished render into a charge. Video pricing lives in the model config rather than in tiered_pricing, because it is keyed by rendered resolution instead of token counts. Two billing modes are supported, and both vary by resolution and by whether the request supplied a reference video: - per_second charges a resolution price times the rendered duration. - per_token charges resolution-keyed token rates. It does not fall back to the model-wide token tier catalog, whose only key is context size. The modes are mutually exclusive at rule level, not by UI convention, so editing the config through the API cannot produce double charging: per_second zeroes the token rates and drops the tier tables, per_token overrides the tier-resolved rates with dimension-sourced ones. Each mode also takes a default price for resolutions the table omits, mirroring image output pricing. Resolution and the reference-video flag reach settlement as usage-event dimensions, the same path image_size already used, so no data-layer change was needed. Notable decisions: - Sections resolve whole: the with_video_input row, then that section's default, then the base row, then the base default. A with_video_input block carrying only a default therefore covers every resolution rather than silently leaking back to base prices. - An unlisted resolution with no configured default resolves to nothing instead of inventing a price, so a partial config underbills visibly rather than overbilling silently. - Resolution keys are normalized to match the admin UI: providers report either a tier (720p) or pixels (1280x720), and a pixel pair is ordered smallest-first so portrait and landscape share one entry. - The token short-circuit in calculate_with_resolution now lets video through. An empty tier catalog is the expected shape for a video model, and Doubao always reports tokens, so the guard would otherwise kill the charge before the video price was ever read. Display had to learn the mode too. Switching modes deliberately keeps the other mode's tables so operators can compare, which meant a model moved to per_token kept showing its stale per-second price. The read logic is now shared in utils/form.ts and gates on mode, and the model lists and detail drawer render per-token video prices, which are absent from default_tiered_pricing and previously left the price column empty. The admin dialogs merge the base and with_video_input tables into one grid, with the override as an optional column and the default as a pinned row, and switch modes from a Repeat2 button matching the tiered editor. Doubao video create/remix reports now defer settlement: an async job answers 200 before its tokens are known, and settling then froze the record at zero. Keeping it pending lets the terminal poll write tokens first. Existing configurations keep working: an absent mode means per_second. Already-settled tasks are not backfilled. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
1、增加对豆包视频端点的原生支持。
2、修复视频模型计费BUG,优化视频模型计费维度。
3、异步任务页面优化。