Spaces:
Running
Running
| # WAN 2.2 generation provider | |
| ## Status | |
| MediaRouter integrates the audited WAN 2.2 Hugging Face worker as the `wan` | |
| generation provider. The registered public model ID is **`wan2.2`**. The | |
| underlying worker model reported by `/v1/info` is | |
| `Wan-AI/Wan2.2-I2V-A14B-Diffusers`; it is metadata, not the MediaRouter model | |
| identifier. | |
| FLUX is a separately configured optional image provider; it does not share | |
| WAN credentials, request fields, worker IDs, or publishing behavior. | |
| ## Worker contract verified | |
| The configured worker is expected to expose: | |
| | Method | Endpoint | Authentication | Use | | |
| | --- | --- | --- | --- | | |
| | `GET` | `/health` | public | Liveness only | | |
| | `GET` | `/ready` | public | Loaded model and whether it accepts jobs | | |
| | `GET` | `/v1/info` | public | Model identity/capability discovery | | |
| | `POST` | `/v1/generate` | Bearer | Authenticated multipart image-to-video submission | | |
| | `GET` | `/v1/jobs/{id}` | Bearer | Job reconciliation | | |
| | `POST` | `/v1/jobs/{id}/cancel` | Bearer | Queued-job cancellation only | | |
| | `GET` | `/v1/jobs/{id}/output` | Bearer | Completed MP4 stream | | |
| The worker reports: | |
| ```json | |
| { | |
| "id": "wan2.2", | |
| "name": "WAN 2.2 FP8 AOTI Faster", | |
| "type": "video", | |
| "task": "image-to-video", | |
| "model_id": "Wan-AI/Wan2.2-I2V-A14B-Diffusers", | |
| "fps": 16 | |
| } | |
| ``` | |
| Model availability is deliberately stricter than a successful HTTP health | |
| check. MediaRouter advertises `wan2.2` as available only after all of these | |
| are true: WAN is completely configured, `/health` is healthy, `/ready` says | |
| `ready` with `model_loaded: true` and `accepting_jobs: true`, `/ready` names | |
| `wan2.2`, and `/v1/info` reports the exact `wan2.2` image-to-video model, | |
| the audited `Wan-AI/Wan2.2-I2V-A14B-Diffusers` underlying model, and 16 FPS. | |
| ## Server configuration | |
| Set these only in backend deployment secrets: | |
| ```dotenv | |
| WAN_SPACE_URL=https://your-wan-worker.hf.space | |
| WAN_SPACE_TOKEN=replace-with-the-worker-secret | |
| AI_WORKER_CONNECT_TIMEOUT_SECONDS=10 | |
| AI_WORKER_REQUEST_TIMEOUT_SECONDS=60 | |
| AI_WORKER_READ_TIMEOUT_SECONDS=300 | |
| AI_WORKER_MAX_RETRIES=3 | |
| AI_WORKER_RETRY_BACKOFF_SECONDS=0.5 | |
| GENERATION_WORKER_ENABLED=true | |
| GENERATION_WORKER_INTERVAL_SECONDS=5 | |
| GENERATION_WORKER_POLL_BACKOFF_SECONDS=2 | |
| GENERATION_JOB_STALE_AFTER_SECONDS=900 | |
| ``` | |
| `WAN_SPACE_URL` and `WAN_SPACE_TOKEN` must be configured together. The token | |
| must meet the worker's 32β4096-character requirement. They are never exposed | |
| through REST, browser data, MCP, n8n, SDK results, audit records, or logs. | |
| WAN is optional: omitted or invalid WAN settings leave only WAN unavailable; | |
| they do not stop MediaRouter, social publishing, or unrelated workers. | |
| ## Request contract | |
| WAN is image-to-video. The caller references an existing **canonical, | |
| workspace-owned image asset**; no local path, worker URL, worker header, or | |
| output URL may be sent by a client. | |
| ```json | |
| { | |
| "provider": "wan", | |
| "model_id": "wan2.2", | |
| "modality": "video", | |
| "input_asset_id": "canonical-image-asset-uuid", | |
| "prompt": "Slow cinematic cloud movement over a mountain valley", | |
| "wan": { | |
| "negative_prompt": "blur, artifacts", | |
| "duration_seconds": 0.5, | |
| "steps": 4, | |
| "guidance_scale": 1.0, | |
| "guidance_scale_2": 1.0, | |
| "seed": 42, | |
| "randomize_seed": false | |
| } | |
| } | |
| ``` | |
| `wan` is a strict typed Pydantic object. Its worker-verified fields are: | |
| | Field | Required | Range/default | | |
| | --- | --- | --- | | |
| | `input_asset_id` | yes | Readable owned image; max 20 MiB at WAN submission | | |
| | `prompt` | yes | Nonblank, 1β4000 characters | | |
| | `negative_prompt` | no | Max 4000 characters; omitted uses WAN's default | | |
| | `duration_seconds` | no | 0.5β5.0; WAN default 5.0 | | |
| | `steps` | no | 1β30; WAN default 4 | | |
| | `guidance_scale` | no | 0β10; WAN default 1 | | |
| | `guidance_scale_2` | no | 0β10; WAN default 1 | | |
| | `seed` | no | 0β2147483647; WAN default 42 | | |
| | `randomize_seed` | no | Boolean; WAN default false | | |
| `width`, `height`, and `num_frames` are rejected. WAN derives supported | |
| dimensions from the source image and frames from duration at 16 FPS. The | |
| worker additionally rejects unreadable images, source sides above 16384, | |
| source images above 40,000,000 pixels, and derived dimensions outside | |
| 480β832 or not divisible by 16. Unknown top-level and WAN options are | |
| rejected; MediaRouter does not forward arbitrary provider fields. Output is a | |
| streamed `video/mp4` file. | |
| ## Job lifecycle and idempotency | |
| ```text | |
| POST /v1/generation/requests | |
| β 202 (MediaRouter job ID only) | |
| durable generation request + job | |
| β | |
| GenerationWorker claims with database row lock | |
| β | |
| WAN multipart submission | |
| β | |
| persist opaque WAN worker job ID | |
| β | |
| bounded status polling | |
| β | |
| stream /output β staging β validation β canonical asset | |
| β | |
| MediaRouter job succeeds | |
| ``` | |
| The reconciliation queue uses a durable, bounded lease in the existing job's | |
| `next_attempt_at` field. This prevents separate worker processes from polling | |
| or ingesting the same WAN output at the same time; a crashed worker's lease | |
| expires and another worker can reconcile the already-bound remote job without | |
| submitting it again. | |
| The public API never returns the WAN job ID as the MediaRouter job identity. | |
| The database protects `(provider, external_job_id)` uniqueness and every | |
| lookup/cancellation starts with the caller's workspace-owned MediaRouter job. | |
| The API idempotency key creates one logical MediaRouter request/job for an | |
| identical request and reports conflict for a changed request. WAN itself has | |
| **no submission idempotency protocol**. MediaRouter therefore never | |
| automatically resubmits after a connection failure, timeout, 502, or 504 that | |
| could have created a remote job while losing its response. Such a submission | |
| is recorded as `GENERATION_SUBMISSION_AMBIGUOUS` and is not retried. This is a | |
| safe at-most-once submission strategy, not an exactly-once guarantee. | |
| Received `429` and `503` rejection responses may be retried within the durable | |
| generation attempt limit. Polling uses the shared bounded retry policy for | |
| connection failures, timeouts, `429`, `502`, `503`, and `504`; `400`, `401`, | |
| `403`, invalid worker job IDs, validation failures, generic `500`s, and | |
| programming failures are not retried automatically. | |
| ## Cancellation and status | |
| WAN supports cancellation only while the remote job is queued. A confirmed | |
| worker `cancelled` response moves the MediaRouter job to `cancelled`. A WAN | |
| `409 WAN_JOB_NOT_CANCELLABLE` for a running job is a cancellation failure: | |
| MediaRouter preserves the active job and never claims GPU inference stopped. | |
| WAN state is normalized into the existing generation state machine: | |
| | WAN state | MediaRouter state | | |
| | --- | --- | | |
| | `queued` | `queued` after worker identity is bound | | |
| | `running` | `running` | | |
| | `completed` | output finalization, then `succeeded` | | |
| | `failed` | `failed` unless a separately safe pre-acceptance retry applies | | |
| | `cancelled` | `cancelled` | | |
| ## Output and security | |
| On completion, WAN returns only a video type and filename. The adapter creates | |
| a validated internal descriptor for the fixed relative endpoint | |
| `/v1/jobs/{worker-job-id}/output`, `video/mp4`, and the opaque worker job ID. | |
| It never trusts a worker filesystem path or arbitrary output URL. | |
| The shared worker client rejects non-server-configured worker origins, | |
| redirects, private literal IPs, unsafe endpoint paths, URL traversal, signed | |
| URLs, and client-supplied output locations. MP4 bytes are streamed without | |
| loading the output into memory, staged in a controlled directory, size and | |
| checksum verified where available, FFprobe/MediaValidator checked, then | |
| registered as a workspace-owned canonical asset. The canonical asset ID, MIME | |
| type, size, checksum, and safe media metadata are attached to the generation | |
| job. | |
| ## Verification status | |
| Mocked protocol tests cover model discovery, readiness, multipart translation, | |
| non-idempotent submission behavior, output normalization, cancellation, typed | |
| parameter rejection, optional configuration, and the shared worker runtime | |
| retry/SSRF/redaction behavior. A live WAN smoke test requires both | |
| `WAN_SPACE_URL` and `WAN_SPACE_TOKEN`; it is intentionally not run in normal | |
| CI and must be reported as not verified when those secrets are absent. | |