feat(videos): Zhipu (CogVideoX) and Ark (Seedance) adapters on /v1/videos#814
Conversation
…1/videos Extend the unified video-generation surface (api7/AISIX-Cloud#1118 Phase 1, second PR) from DashScope-only to three provider mappings, dispatched by the Model's open `provider` string: - `zhipuai` — BigModel CogVideoX: submit POST {root}/api/paas/v4/videos/generations with a flat {model, prompt, duration, size} body (the vendor documents the unified WIDTHxHEIGHT size spelling, forwarded verbatim); poll GET {root}/api/paas/v4/async-result/{id}; statuses PROCESSING/SUCCESS/ FAIL normalise to in_progress/completed/failed (the vendor has no distinct queued state); the video URL is video_result[0].url. - `volcengine` — Ark Seedance: submit POST {root}/api/v3/contents/generations/tasks with {model, content: [{type:"text", text}], duration} (field set per the official Ark SDK); the create response carries only the task id (queued); poll GET {root}/api/v3/contents/generations/tasks/{id}; statuses queued/ running/succeeded/failed/cancelled normalise onto the unified enum; the video URL is content.video_url. `size` is not forwarded — the vendor expresses dimensions as resolution/ratio quality tiers, and inventing a lossy WIDTHxHEIGHT→tier mapping is worse than the provider default. The provider-specific pieces (URL derivation with per-vendor api_base suffix stripping, submit body, submit/poll response parsing, the DashScope-only async header) fold into one VideoProvider enum matched in three places, so a fourth adapter is a new match arm rather than another copy of the handler logic. Every existing invariant is unchanged: 3-segment video id codec, submit-only model rate limiting, guardrail-before-quota, uniform 404 on the GET routes, bounded metric labels, zero-token UsageEvent on submit, http(s)-only 302 content redirect, charset-guarded task ids. Unit: per-provider status tables, submit wire assertions, root/URL composition, nested-error-envelope passthrough, Ark failure detail. E2E: one submit→poll→content-302 journey per new provider against provider-shaped mock upstreams; DashScope journeys unchanged.
|
Warning Review limit reached
Next review available in: 42 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughThe ChangesMulti-provider video adapters
Estimated code review effort: 4 (Complex) | ~60 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 6✅ Passed checks (6 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
…ias, FAIL-path test - per-field as_u64 so a present-but-null output_video_duration still falls back to usage.duration - accept the common 'zhipu' spelling alongside the catalog-canonical 'zhipuai' on the videos dispatch - pin the Zhipu FAIL poll journey (generic video_generation_failed error object; the vendor task payload carries no failure detail)
|
@coderabbitai review |
✅ Action performedReview finished.
|
Summary
Second PR of
api7/AISIX-Cloud#1118Phase 1: extends the unified/v1/videossubmit → poll → content surface (shipped DashScope-only in the previous PR) with two more provider mappings, dispatched by the Model's openproviderstring (case-insensitive). Any unmapped provider keeps the existing behavior: typed 501not_implementedon submit, folded to a uniform 404 on the GET routes.All surface invariants are unchanged and re-verified by the existing test suite: 3-segment
video_idcodec (b64url(entry_id : b64url(alias) : task_id)), submit =enforce(Some(&model_rl))/ GETs =enforce(None)(poll exemption by design), guardrail-before-quota on the submit prompt, uniform 404 disclosure fold on GETs, bounded metric labels, one zero-token UsageEvent per submit, http(s)-only 302 content redirect, charset-guarded task ids.Provider mappings (doc citations)
zhipuai— BigModel CogVideoXContract source: https://docs.bigmodel.cn/api-reference/%E6%A8%A1%E5%9E%8B-api/%E8%A7%86%E9%A2%91%E7%94%9F%E6%88%90%E5%BC%82%E6%AD%A5
POST {root}/api/paas/v4/videos/generations,Authorization: Bearer, flat body{model, prompt, …}; response{model, id, request_id, task_status}GET {root}/api/paas/v4/async-result/{id}secondsduration(int)sizesizeverbatim — the vendor documents the sameWIDTHxHEIGHTspelling ("1920x1080","1280x720", …)PROCESSING→in_progress,SUCCESS→completed,FAIL/other→failed; the vendor has no distinct queued state, so an accepted submit reportsin_progressvideo_result[0].url{error: {code, message}}envelope, passed through the standard 4xx renderingRoot derivation: the control-plane catalog pre-fills
api_basehttps://open.bigmodel.cn/api/paas/v4; the adapter strips one trailing/api/paas/v4so the native task paths are never doubled (mirrors the DashScopecompatible-modestripper, with tests).volcengine— Ark SeedanceContract source: the official Ark SDK (
volcengine-python-sdk,volcenginesdkarkruntime/resources/content_generation/tasks.pyandtypes/content_generation/content_generation_task.py) — the vendor's doc pages (docs.volcengine.com/docs/82379/2298881and the ModelArk mirror) render client-side only and return no static content, so per the repo research rules the SDK source is the citable contract.POST {root}/api/v3/contents/generations/tasks, bearer auth, body{model, content: [{type: "text", text: prompt}], duration?}— the exact field set of the SDK'stasks.create(model=…, content=…, duration=…, resolution=…, ratio=…); response{id}(ContentGenerationTaskID)GET {root}/api/v3/contents/generations/tasks/{id}(ContentGenerationTask)secondsduration(int, top-level)sizeresolution("720p"/"1080p") +ratio("16:9", …) quality tiers, which cannot represent an arbitraryWIDTHxHEIGHTwithout a lossy invented mapping; the value is still shape-validated so malformed input fails identically across providers, a debug log records the drop, and the provider default applies. A tier-mapping design (shared with the wan2.7 follow-up) is tracked in the internal issue.queued→queued,running→in_progress,succeeded→completed,failed/cancelled/expired/other→failed; the create response carries no status, so a fresh submit reportsqueuedcontent.video_urlerror {code, message}surfaces through the unifiederrorobjectProvider-string note: the public model catalog carries no canonical id for this vendor, so the open provider string
volcenginematches the vendor's own name; the control-plane catalog quirk entry is separate tracked follow-up work.Structure
The provider-specific pieces fold into one internal
VideoProviderenum (root/submit_url/poll_url/submit_body/parse_submit/parse_poll/ DashScope-only async header), reducing every provider response to two normalised views (SubmitView,PollView) the handlers consume. A plain match at three providers — deliberately no trait objects or registry. Adding a fourth adapter is a new match arm plus tests, not another copy of handler logic.Deferred (tracked in the internal issue)
volcenginevendor (provider quirk/prefill) — separate CP work.size→ tier mapping for tier-based vendors (Ark resolution/ratio, wan2.7) — needs a deliberate, documented mapping decision.Test evidence
videos.rs, now 35 cases): per-provider status-mapping tables; Zhipu/Ark submit-body shape (includingsizeverbatim for Zhipu,sizedropped under every name for Ark, malformed-sizefast-fail); per-provider root stripping + full URL composition; Zhipu nested error envelope on 4xx; Ark failureerror {code,message}mapping; full-journey wiremock tests per provider (submit wire assertions + poll + content 302, and no DashScope header bleeding across vendors); every pre-existing invariant test (codec, ACL fold, metric-label boundedness, rpm cap with poll exemption, scheme validation, allowed_cidrs) unchanged and green.tests/e2e/src/cases/videos-providers-e2e.test.ts, source-blind, real binary + etcd + provider-shaped mock upstreams): one submit→poll→content-302 journey per new provider with upstream wire assertions; the DashScope journeys invideos-e2e.test.tsstay green.cargo fmtclean;cargo clippy --workspace --tests0 warnings;cargo test -p aisix-proxy --lib703 passed;cargo build --bin aisixok; e2e videos (3/3) + videos-providers (2/2) + passthrough family (7/7) all passed against the rebuilt binary.Summary by CodeRabbit
New Features
Bug Fixes
Tests