openrouter-video-generator
GitHub为AwesomeWebpageMetaSkill生成视频资产。通过OpenRouter异步API提交任务,轮询状态并下载MP4至指定目录。严格遵循配置读取与API调用规范,避免误用聊天接口导致报错或费用损失。
Trigger Scenarios
Install
npx skills add opensquilla/opensquilla --skill openrouter-video-generator -g -y
SKILL.md
Frontmatter
{
"name": "openrouter-video-generator",
"homepage": "",
"metadata": {
"opensquilla": {
"risk": "high",
"requires": {
"env": [],
"config": [
"awesome_webpage.openrouter.api_key",
"awesome_webpage.openrouter.api_key_env",
"awesome_webpage.openrouter.base_url",
"awesome_webpage.openrouter.models.video_generation",
"awesome_webpage.output_dir"
]
},
"capabilities": [
"network-write",
"filesystem-read",
"filesystem-write"
]
}
},
"entrypoint": {
"env": {
"{{ with.api_key_env | default('OPENROUTER_API_KEY') }}": "{{ with.api_key | default('') }}"
},
"args": [
"--model",
"{{ with.model | default('bytedance\/seedance-2.0-fast') }}",
"--base-url",
"{{ with.base_url | default('https:\/\/openrouter.ai\/api\/v1') }}",
"--api-key-env",
"{{ with.api_key_env | default('OPENROUTER_API_KEY') }}",
"--output-dir",
"{{ with.output_dir }}",
"--filename",
"{{ with.filename | default('intro.mp4') }}",
"--duration",
"{{ with.duration | default(10) }}",
"--aspect-ratio",
"{{ with.aspect_ratio | default('16:9') }}"
],
"parse": "text",
"stdin": "{{ with.prompt | default(inputs.user_message) }}",
"command": "python {baseDir}\/scripts\/openrouter_video.py",
"timeout": 420
},
"provenance": {
"origin": "opensquilla-original",
"license": "Apache-2.0",
"maintained_by": "OpenSquilla"
},
"description": "Generate or declare a configured OpenRouter video asset for AwesomeWebpageMetaSkill. Use only when the meta skill needs a local webpage video and the provider, model, API key, and output directory come from config.",
"user-invocable": false,
"disable-model-invocation": true
}
OpenRouter Video Generator
Create a short browser-playable video asset for AwesomeWebpageMetaSkill.
This is an adapter around the configured OpenRouter video model, not a place to
choose providers or invent model ids.
Meta-Skill Entrypoint
Meta-skills should run this skill as skill_exec. The entrypoint is a
deterministic Python adapter around OpenRouter's async video endpoint; it uses
an explicit with.api_key value by injecting it into the configured
with.api_key_env child process environment variable, writes the MP4 under the supplied
output directory, and prints either VIDEO_READY: or a single failure label.
Do not spawn an LLM sub-agent just to generate video.
Contract
- Read provider settings from
config.awesome_webpage.openrouter. - Resolve the API key from
awesome_webpage.openrouter.api_key; if empty, use the environment variable named byawesome_webpage.openrouter.api_key_env. - Use only
awesome_webpage.openrouter.models.video_generationas the model. - Use only
awesome_webpage.output_diras the output root. - Save generated files under
project/assets/video/. - Return a media manifest with local path, MIME type, duration if known, provenance, and replacement notes.
OpenRouter Video API Contract (hard rule)
OpenRouter video models are exposed through an async job endpoint, not
the chat-completions endpoint. Hitting /chat/completions with a video
model id returns HTTP 500 and burns the full per-attempt budget. Do not
attempt it.
- Submit:
POST {base_url}/videoswith JSON body{"model": "<video_generation>", "prompt": "<text>", "duration": <int>}. Optional fields:resolution,aspect_ratio,frame_images,input_references,provider,callback_url. Do NOT sendmessagesormodalities— those are chat-only and will be rejected. - Response (immediate):
{"id": "...", "polling_url": "...", "status": "pending"}. - Poll: GET the
polling_urlwith the sameAuthorization: Bearer ...header every 8-15 seconds untilstatusbecomes one ofcompleted | failed | cancelled | expired. Cap the loop at ~5 minutes per clip; treat anything beyond that asVIDEO_GENERATION_FAILED. - Download (only on
completed): take the first URL fromunsigned_urls, GET it with the same bearer token, and save the body to<output_dir>/project/assets/video/<slug>.mp4. Set MIME tovideo/mp4. - Terminal-failure statuses map to
VIDEO_GENERATION_FAILED; include the jobidand a replacement-slot path so the page can render a clean placeholder.
Typical successful job completes in 60-120 s for short clips; do not abort before that window.
Failure Labels
Return one of these labels instead of silently skipping video:
VIDEO_CONFIG_NEEDED: model, API key, base URL, or output directory is missing.VIDEO_MODEL_UNSUPPORTED: the configured model cannot return a local browser-playable asset in this environment.VIDEO_GENERATION_FAILED: the provider call failed after a concrete attempt.
When returning a failure label, also return a replacement slot such as
project/assets/video/replace-with-topic-intro.mp4 and enough prompt/context
for a later repair pass.
Output Requirements
- Prefer
.mp4withvideo/mp4;.webmis acceptable when browser playable. - Keep clips short, usually 8-20 seconds.
- Do not use remote embeds unless config explicitly allows them.
- Do not hardcode OpenRouter model names, API keys, or output directories.
On success: VIDEO_READY manifest line (required)
After every successful download, end your reply with one single-line JSON
record per file so AwesomeWebpageMetaSkill can collect and bind the asset:
VIDEO_READY: {"local_path": "project/assets/video/<slug>.mp4", "mime": "video/mp4", "duration_s": <int_or_null>, "resolution": "<WxH_or_null>", "prompt_preview": "<first 80 chars>"}
- One
VIDEO_READY:line per video file. No trailing prose on that line. local_pathMUST be the relative pathproject/assets/video/.... Do NOT emit an absolute path here.- On failure, emit one of
VIDEO_CONFIG_NEEDED,VIDEO_MODEL_UNSUPPORTED, orVIDEO_GENERATION_FAILEDas a single-line label with the replacement-slot path so the page can render a placeholder.
Version History
- 7f72a32 Current 2026-07-05 18:39


