← HypernaturalCONTENT HISTORYWHAT CHANGED · RULE-BASED ANALYSIS
Update to Hypernatural
Snapshot Sep 30, 2026 · 22:48 UTC · version 1.0.2
Collection source: not recorded for this historical snapshot.
First saved snapshot
No earlier snapshot is available to establish a change.
Compare saved observations
Download comparison JSONFull technical diff · 0 changed fields
Full snapshot data
{
"name": "hypernatural",
"description": "Use when the user wants a video made or edited — \"make me a video\", a promo, ad, UGC clip, explainer, product or launch video, turning a script, blog post, or images into video — even when no tool is named, and whenever Hypernatural or its MCP server is mentioned.",
"included_files": [
{
"relative_path": "agents/openai.yaml",
"size_in_bytes": 405
},
{
"relative_path": "references/shot-writing.md",
"size_in_bytes": 4670
}
],
"skill_md_contents": "---\nname: hypernatural\ndescription: Use when the user wants a video made or edited — \"make me a video\", a promo, ad, UGC clip, explainer, product or launch video, turning a script, blog post, or images into video — even when no tool is named, and whenever Hypernatural or its MCP server is mentioned.\n---\n\n# Creating videos with Hypernatural\n\n## What Hypernatural is\n\nHypernatural (https://hypernatural.ai) is a **subagent** that builds a _composition_: a timeline of still images, animated clips, music, and TTS narration that together constitute a video. You direct it over MCP server `https://api.hypernatural.ai/mcp` (streamable HTTP; your client handles OAuth).\n\nThe division of labor: **you decide the creative structure; Hypernatural renders it.** It is a strong executor and a weak reasoner. It accepts open-ended prompts, but it works far better when you specify the exact shots you want — the shot-list format in [references/shot-writing.md](references/shot-writing.md) — and address everything precisely: library entities by exact `@Name`, shots by position (\"shot 2\"). You are better than it is at working out which shot or entity the user means, so resolve that yourself, then name it.\n\nEvery creative call is asynchronous — it queues background work and returns immediately, and you poll for the result. Only the `list_*` / `get_*` reads answer straight away.\n\n## Glossary\n\n**Composition** — the video itself: a timeline of shots plus independent audio tracks. Created once with `create_composition`, then changed by conversation. Has an id, a shareable `url`, a `title`, and a `render_size` (`landscape` / `portrait` / `square`) fixed at creation. The `url` opens the website editor; it is **not** a video file.\n\n**Shot** — one entry on the timeline: a still image generated from its description (using its `@`-mentioned references), an optional animation (a short video clip derived from that still), and optional animation instructions.\n\n**Animation instructions** — the motion for a single shot. They can also bake **dialogue (lip-synced) or sound effects** into that one shot's clip; quoted speech here is voiced _in the clip_, not as a separate voiceover.\n\n**Voiceover track** — TTS narration: independent audio that plays across the timeline alongside the shots. It is not part of any shot, and is added, moved, and replaced separately.\n\n**Music track** — a background score across the timeline, added / moved / resized by asking in chat.\n\n**Captions** — on-screen text auto-generated from the narration. Captions and voiceover are different concepts: \"hide the captions\" is a visibility change, never a voiceover removal. Captions are the only text _overlay_ over MCP — there are no separate title or end-card elements. Words can also be generated directly into a shot's still image (a title card, a sign, an end-card); the rules for that are in [references/shot-writing.md](references/shot-writing.md).\n\n**Reference** — a named, reusable, team-scoped library entity that you mention as `@Name` in shot text. Three kinds, routed by what the image _depicts_, not by how you want it used (all three end up in the video):\n\n| The image is | Create it with | Then |\n| ---------------------------------------------------------------- | --------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- |\n| A recurring on-screen person (spokesperson, presenter, founder) | `create_character` — one image, or a text `bio` with no image | `@Name` in shots |\n| One specific product or logo that must look identical every time | `create_reference_object` (`kind: product` / `logo`) — an image is required | `@Name` in shots |\n| A scene, location, background, mood, or style — the common case | `create_asset` | pass `{asset_id, name}` in `static_image_references` **and** use that `@Name` in the prompt |\n\n**Job** — one unit of background work, identified by a `job_id`. Poll `get_job` until `complete` or `failed`. Composition turns are the exception: they poll `get_composition` instead.\n\n**`next_action`** — the single computed instruction `get_composition` returns for the composition's current state. It is the state machine, not a suggestion: always obey `next_action.guidance`.\n\n**Credits** — the team's generation budget. A composition can pause mid-plan on `top_up_credits`.\n\n## The tools\n\n| Purpose | Tools |\n| ----------------------- | ------------------------------------------------------------- |\n| Get images in | `get_image_upload_urls`, `upload_file_from_remote_url` |\n| Build the library | `create_asset`, `create_reference_object`, `create_character` |\n| Read the library | `list_assets`, `list_characters`, `list_reference_objects` |\n| Create and read a video | `create_composition`, `get_composition`, `list_compositions` |\n| Change a video | `send_chat_message` |\n| Track background work | `get_job`, `list_jobs` |\n\nEach tool's own description defines its arguments; this skill defines the workflow and the UX.\n\n## Building a video\n\n### 1. Decide the references first, and ask the user about them\n\nBefore writing any shot text, decide which characters, products, logos, and scene images the video needs — and **ask the user**. The video should show _their_ spokesperson, product, and business; do not invent a stand-in for something the user owns.\n\nReferences are team-scoped and reusable across compositions, so check the library first (`list_characters`, `list_reference_objects`, `list_assets`) and reuse existing entities rather than creating duplicates.\n\nEvery new image needs an `upload_key` first. Pick the path by **where the bytes already are**:\n\n| Bytes are | Call |\n| -------------------------------- | -------------------------------------------------------------------------- |\n| On local disk, and you can `PUT` | `get_image_upload_urls([filenames])`, then PUT each file's bytes to its url |\n| A native attachment (`file`, ChatGPT only) | `upload_file_from_remote_url(file=…)` |\n| Already at a public HTTPS URL | `upload_file_from_remote_url(url=…)` — never download it locally first |\n\nUpload only the files you were given, never a whole directory. `upload_file_from_remote_url` takes exactly one source — whichever of `file` / `url` your client's schema offers — and returns its `upload_key` immediately, with no job to poll. If a PUT fails, switch to `upload_file_from_remote_url` instead of retrying it. Never invent a `url` for a local file — when neither path is available, say so and ask the user for a public URL or an attachment, rather than building the video without an image they asked for.\n\n### 2. Create a reference for each image, routed by what it depicts\n\nRoute each image with the table in the glossary, then **poll each returned `job_id` with `get_job` until `complete`**. The entity does not exist before that, so never use a new `@Name` in the same turn as its `create_*` call — a `create_composition` or `send_chat_message` that mentions an unresolved `@Name` fails. A `complete` job can still carry per-file failures: check `error_message` and `result.errors`; failed files are absent from `result.assets`.\n\nCreating a reference from material the user handed you with stated intent (\"this is our founder\", \"here is the logo\") is setup, not speculation — do it now; it is reusable library work either way. A reference that was _your_ idea, for a subject the user never raised, belongs to your draft and waits for approval in step 4.\n\n### 3. Write the shot list that uses those references\n\nEach `Shot 1: …` entry becomes exactly one shot; the planner preserves your count, order, and intent while filling in generation detail. Give every shot a **Visual** (subjects, placement, exact `@Name`s) and an **Animation** (motion, camera, any quoted on-screen speech first). Shots are generated with no memory of each other, so every appearance of an entity is its exact `@Name` — in every shot, every time.\n\nRead [references/shot-writing.md](references/shot-writing.md) before drafting: Visual vs Animation, standalone shots, `@Name` discipline, quoted speech, in-shot text, pacing, and a worked example.\n\n### 4. Get approval for anything you wrote\n\n- **The user supplied the shots:** preserve their wording, weave in the required `@Name`s, and create immediately. Those `@Name` edits are a binding requirement, not a rewrite — they are the only change you make without approval.\n- **You wrote or expanded any shot beyond those `@Name` edits** — from prose, a brief, a vague idea, or by filling in detail the user did not give: show the drafted shot list and get approval **before any `create_*` call**; an unapproved plan makes those entities wasted work. Label the draft `Shot 1:`, `Shot 2:` … so the approved text becomes the prompt verbatim. An explicit waiver (\"just make it, I trust you\") counts: show the list, then proceed without waiting.\n\n### 5. Call `create_composition` once\n\nOne composition per video: every later change is a `send_chat_message`, never a second `create_composition`. Pass the approved shot list as `prompt`, every scene image as a `static_image_references` entry whose name appears as `@Name` in that prompt, and the `render_size` the user wants.\n\n### 6. Follow `next_action` until `done`\n\nPoll `get_composition` (not `get_job`) and do exactly what `next_action` says. While work is in flight, say generation is _kicked off_, never _ready_, until polling confirms it — and close each turn in one brief sentence.\n\n| `state` | Do this |\n| -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `wait` | Wait `retry_after_seconds`, then poll again. Send no message and no unsolicited progress update; answer a direct status question if the user asks one. |\n| `answer_question` | Ask the user `question.question`, then send **only** their answer. A labeled recommendation of your own is fine; answering for them is not. Send nothing else — an unrelated message cancels the question. |\n| `pick_references` | Planning paused on a subject you did not `@`-tag. Show every question with its candidates, then send all choices in one message: `Use @Name for <subject>.` or `Use any <kind> for <subject>.` Create and poll a missing reference first. |\n| `top_up_credits` | Relay the shortfall and the composition `url`. |\n| `open_in_app` / `report_failure` | Relay the guidance with the `url`, then stop polling. |\n| `done` | Relay `assistant_reply`; add `actions` if the user wants the change details. |\n\n### 7. Edit by conversation, then hand off the `url`\n\nSend one intent per `send_chat_message`, in plain language, with exact `@Name`s. Refer to shots by position (\"shot 2\", \"shots 3–5\") and pick the shot yourself rather than describing it. Music, captions, voiceover placement, and volume are all chat edits: describe what you want.\n\n- Ask for pacing in words (\"quick cuts\", \"let it linger\") rather than per-shot seconds, unless the user needs exact timing.\n- Quote the durations `get_composition` reports, never the ones you requested — narration refits timing. Do not send a follow-up message to correct drift the user never raised.\n\nFinish by giving the user the composition's `url` — review, rendering, and export all happen in the Hypernatural app, not over MCP. Hand over the `url`, never a bare id.\n\n## Common errors\n\n| Mistake | Instead |\n| ----------------------------------------------------------- | --------------------------------------------------------------------------------------------- |\n| `create_composition` straight from a vague ask | Draft the shot list, show it, get approval |\n| Deciding the references yourself | Ask the user which spokesperson / product / logo images the video should use |\n| Using an `@Name` in the same turn as its `create_*` | Poll `get_job` to `complete` first — the entity does not exist yet |\n| Writing \"your logo\", \"the same barista\", or \"she\" in a shot | The exact `@Name`, in every shot, every appearance |\n| A `static_image_references` name that is not in `prompt` | Every name there must appear as `@Name` in the prompt, or the call is rejected |\n| Uploading a product photo as a plain asset | Products and logos are reference objects, people are characters, scenes and styles are assets |\n| Downloading a remote image locally to re-upload it | `upload_file_from_remote_url(url=…)` — the server fetches it for you |\n| Answering a `next_action` question yourself | Forward the user's own answer |\n| Messaging while `next_action` is `wait` | Wait `retry_after_seconds`, then poll again |\n| A second `create_composition` to change something | One composition per video; every later change is `send_chat_message` |\n| Vague in-shot text (\"a sign with the company name\") | Text in shots is fine used sparingly — quote the exact words and specify style and placement |\n| Treating a `complete` job as fully successful | Check `error_message` and `result.errors` |\n| Handing over a composition id | Hand over the `url` |\n\nWhen something does fail:\n\n- Follow the recovery instructions in the error text and any `guidance` field before improvising.\n- After an ambiguous `create_composition` failure (timeout, server error), call `list_compositions` **before** retrying. The composition may already exist, and a blind retry creates a duplicate.\n- Never loop on identical failures. On `report_failure`, relay the guidance with the composition `url` and stop — the user can continue in the app.\n"
}SHA-256: ed866bfe185e1e3ace27b30b7929fa486667bb4529bc72afd483d8d39f621769