Repository navigation
feat(skills): style templates on the HyperFrames plan - #6842
WaterrrForever wants to merge 34 commits into
Conversation
…t of retries An out-of-credits refusal named what the step needs, and an agent read that as the shortfall. It now says the number is the step's total. After its last try, an agent told the person what was spent and what another try would cost. The HeyGen reference now says not to.
An avatar's credits came from its old API price, about five times what the plan charges, so --max-credits refused calls that fit and a top-up asked for too much. They now use the Avatar IV photo row plus the general avatar video row, 950 credits a minute.
The general avatar row is only checked at admission and billed on seconds left after Avatar IV, so adding it to every second made a 15 s script plan at 238 instead of 200 and a 220 limit refuse a call that fits.
A Pro account asks for a video in a creator's format and the agent pulls that template on demand. The packs sit in the private bucket behind the plan-gated bundle route, so a Free account gets a 402 and the upgrade step. A pull costs no credits; making the film spends them as Reverse does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
SKILL.md holds the catalog, the Pro openings, the pull and the credit rules. references/remix.md is how to make the episode, from Desktop's creator-remix with only what the app alone has swapped for the CLI. The packs now hold only the template, so their hashes change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
SKILL.md holds the catalog, the Pro openings, the pull and the credit rules. references/remix.md is how to make the episode, from Desktop's creator-remix with only what the app alone has swapped for the CLI. The packs now hold only the template, so their hashes change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The person's own HeyGen avatar is recommended, not required: without one, 小Lin's presenter is made with HeyGen Video 1 from their photo. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Automations to automatically generate PRs for you. |
Edit accuracy: accurate 267 (base branch 267), smooth 104 of thoseThe gate passes. Quarantined, measured but not gated (8)
Unstable (1)
|
References in a composition's <template> were never rewritten, because the DOM query stops at the tag and template.content does not serialize, so the file stayed in the zip. A stem matched as a plain word and a same-named file elsewhere counted as a mention too. A 5-minute presented film went from 196 MB to 71 MB. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Video 1 takes audio as a reference and re-paces it, so a shot's lips follow its own track and drift up to a second from the voice. generate --type lipsync redoes the mouth to the exact voice. generate --type avatar takes --audio, and --avatar for the person's own look, so the lips land on the voice from one job. Also moves the plan rows to the 2026-10-30 price book, estimates a voice's credits so --max-credits can hold it, logs jobs from a folder with no project, and describes the resolve flags. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The person's own avatar, then Avatar IV from their photo, then Video 1 with lipsync. With no clone or recording, a stock voice named in the credits. Pins the five rebuilt packs. The archive test keeps its ../ under GNU tar with -P. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Keeps the 2026-10-30 price rows over main's older ones and regenerates the skills manifest. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
| try { | ||
| const archive = join(work, "template.tar.gz"); | ||
| const out = join(work, "template"); | ||
| writeFileSync(archive, data); |
A wav gives the avatar price test an exact length on every platform. The sfx tests now expect HeyGen first. Comment share is back under the base. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`font: calc(var(--size) * 1px)/1 "X"` cut at the first closing parenthesis, so a bad family name failed the render. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ictures A job done at once logs one row, transcribe logs to the project, and resolve no longer offers a component's file for a search. --reuse and --provider get help text. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… real slug Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…oryboard rule Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e stock-presenter ban Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ates to names that say the look Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…phics Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ackground on the plan Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…riety rule Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…eal films Animated Science gets a worlds-and-boards budget, 3D True Crime a main board and a brief corner note, 3D Brand caps by measured rate, Finance and Collage set pieces and more than one look. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…, not the heygen CLI ones Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts: # packages/cli/src/heygen/generate.ts # skills-manifest.json # skills/media-use/references/heygen.md
jrusso1020
left a comment
There was a problem hiding this comment.
Reviewed at 0e30f4c78caab000f78af85de3ae0155c4a160e0.
The template pull authenticates before downloading, checks pinned size and SHA-256 before extraction, and stages beside the destination before an atomic rename (packages/cli/src/commands/templates.ts:55–123). The generation retry key derives from source bytes rather than newly assigned asset IDs (packages/cli/src/heygen/generate.ts:624–626).
Important — cutout retries do not use the server's deduplication mechanism (packages/cli/src/heygen/generate.ts:243–246,627). The new /v3/background-removals body omits request_id. That endpoint uses body request_id, and explicitly does not honor the HTTP Idempotency-Key header: see EF movio/api_service/app/controller/background_removal_dto.py:39–48 and background_removal.py:69, plus service background_removal.py:381–389. I checked those files against current EF master. Two identical actual generate/runJob calls, each advanced through its 30-minute pending timeout with mocked upload/HTTP, retain the same header key but have no body request_id. A server-contract model therefore creates two jobs; supplying the same body request_id deduplicates. This is a mocked contract reproduction, not an observed production duplicate. Paid-up HF Pro/Max cutout is currently free, but API credentials can potentially incur another charge (the service has a separate billed path; no billing was executed), and either caller creates another job.
Fix: send the effective retry key as cutout's body request_id, including the failed-job suffix selected by runJob, rather than only as a header. Preserve the same value after a lost response/pending timeout and a fresh value after a confirmed terminal failure. Add a retry regression whose server stub ignores the header and deduplicates exclusively by request_id.
Important — WebM and MOV inputs are declared as audio (packages/cli/src/heygen/generate.ts:386). uploaded() declares .mp4 as video/mp4 and everything else as audio/mpeg. Both new video operations accept an input --video without restricting it to MP4; WebM/MOV reach upload finalization as audio/mpeg and are rejected by the server media-category helper under the checked contract. Actual generate calls captured that declaration. Real FFmpeg MP4/WebM/MOV fixtures, sniffed with file(1), were passed to the AST-extracted current EF _resolve_real_file_type: MP4 succeeds; WebM and MOV fail with “Stored file type … does not match … audio/mpeg.” Correct declared-MIME controls all succeed.
Fix: reuse getMimeType from @hyperframes/core/studio-api (already used by the CLI static server), or explicitly map/validate supported video and audio types before upload (WebM video/webm, MOV video/quicktime, and each accepted audio format). Add real-file MIME controls for cutout/lipsync and avatar audio.
Nit — public discovery: skills/style-remix/SKILL.md:5 still sets metadata.internal=true. The existing skills installer lists the eight public skills and omits style-remix; an explicitly named --skill style-remix does find it. If this is the public launch described in the body, remove the flag and update the catalog/count surfaces. Otherwise describe it as an internal opt-in for now.
Plan-gate / hands-on evidence: no HyperFrames account is configured here. The built CLI's signed-out templates pull 3d-true-crime prints the login step and creates no project directory. No live Free/Pro pull was possible. The CLI's mocked 402 path passes with upgrade guidance and no template files. I inspected current EF moment_routes/moment_access: the server checks the payer's paid-up plan before storage lookup/signing when purchase enforcement is enabled; all five M9001–M9005 packs are outside the free list. Extracted actual functions with mocked policy/plan/storage cover 25 cases: enabled+unpaid→402 with no storage/signing, unavailable+unpaid→503, paid→link. Pre-existing policy: explicitly disabled purchase enforcement allows Free callers; this is a conditional server gate, not an unconditional Pro-only rule. I did not verify production policy configuration or a real expired subscription.
Validation: 181 CLI tests, 21 media-use JS tests and 7 font tests pass; full build and lint pass. Independently reran both adversarial witnesses and MIME controls. Template tests also cover hash mismatch, unsafe parent paths, an existing destination and cleanup after refusal. Malicious symlink/hardlink archives, redirect handling and filesystem-failure injection were not exercised; private pack contents were not available for inspection. No paid generation, live upload, plan purchase/change, full episode or cloud render performed. The linked design/eval page was inaccessible to the web tool; its films were not evaluated.
Audited: template command/tests, shared media generation/pricing/upload/ledger boundaries, transcription and SFX changes, offload references and retention, asset adoption, font shorthand, skill/docs/catalog integration. Server gate and upload/background-removal contracts checked separately against EF source.
Trusting: unchanged auth/payment/provider internals and private pack content; generated manifest structure checked, author-reported production pulls and five end-to-end films not reproduced.
Need: yes · Size: broad but reviewable; media fixes are independently testable · Reuse: getMimeType and endpoint request_id contract · Simpler: adapt the shared paid-job wrapper to cutout's existing deduplication field · Structure: fine
Risk: medium — adds paid media routes and private pack delivery.
Verdict: REQUEST CHANGES
Reasoning: Template refusal and staging pass the exercised paths, but cutout retry identity and non-MP4 upload typing need fixes before approval.
— hf-review
miguel-heygen
left a comment
There was a problem hiding this comment.
Independent review at 0e30f4c78caab000f78af85de3ae0155c4a160e0; the PR is still a draft.
The template path verifies pinned bytes/SHA256 before unpacking and publishes from a temporary sibling with finally cleanup (packages/cli/src/commands/templates.ts:84–119). The credit-limit check refuses an unpriced operation before generation (packages/cli/src/heygen/pricing.ts:134–150).
Blockers: +1 to @jrusso1020's existing findings; no duplicate inline comments. I independently traced the cutout body at packages/cli/src/heygen/generate.ts:243–246 through runJob: the effective retry key reaches only the HTTP header, while the server DTO/controller use body request_id for deduplication and explicitly ignore that header. A resumed command can therefore start another cutout job. The upload helper at generate.ts:386 also labels every non-MP4 input audio/mpeg, including MOV/WebM and avatar WAV/M4A. These need contract-level tests, beyond the mocked successful upload response.
Additional CI qualification: current Fallow job 125441922255 exits 1. Its report identifies generate.ts:472, commands/media-use/generate.ts:149, and cloud/offload.ts:534,896; resolve or explicitly disposition that gate. The current hosted CLI shards pass 3,982 + 3,343 cases, with 23 + 89 skips; their checkout is synthetic merge 1179aec83fe751f9e1f175a32bfedaca0ce2bd84, merging this head into captured base 7d3c2252. Lint and skill lint/mirror pass. The 167 check records include historical failures and a pending WIP check, so this is not an all-green claim.
Audited: all 36 changed-file diffs; downloader, generation/retry/upload, pricing/refusal, skill instructions, and relevant consumer paths. Limits: no paid calls or new local test run; existing local server-source contracts are not serving-deployment proof. No valid own Free account was established, so live Free→402/no download and live Pro pulls remain unverified. The design/evaluation link requires sign-in; no private pack contents or film-quality claim. The existing internal-skill/public-discovery concern remains as Rames noted.
Verdict: REQUEST CHANGES
Reasoning: The two independently confirmed job-contract bugs remain at this exact head; passing mocked tests do not discharge them.
— Magi (cutroom-dev)
…al type; style-remix is public The background-removal route dedupes on the body's request_id and ignores the Idempotency-Key header, so a retry after a lost answer started a second job: runJob now also sends the key in the body for such a route. Uploads typed every non-MP4 file as audio, so WebM and MOV inputs were refused: they now take their type from the extension. Fails without the fix: the new cutout test in generate.test.ts sees audio/mpeg for WebM and MOV. style-remix drops metadata.internal and is listed with the other published skills. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Thanks. Fixed in 83d176e:
On the server gate: agreed it's conditional on purchase enforcement, which is on in production. |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@miguel-heygen (Magi): thanks. All three are fixed at the current head (a6e07a6), as answered to Rames above:
|
jrusso1020
left a comment
There was a problem hiding this comment.
Reviewed at a6e07a60f7b0a4296a46987dbbc09b5bff5f6d38, delta from 0e30f4c78caab000f78af85de3ae0155c4a160e0.
Both earlier Important findings are fixed:
- Cutout selects
bodyKey: "request_id";runJobinserts the effectiveliveKey, including its failed-job suffix, into the body as well as the header (packages/cli/src/heygen/generate.ts:251,642;v3.ts:231–235). The lost-response/body-only-dedup regression and real generation timeout witness preserve one job; a confirmed failed job gets a fresh key. uploaded()uses the sharedgetMimeTypemapping (generate.ts:382–389), covering MOV/WebM video and WAV/M4A audio. The real-file WebM/MOV regression executes successfully. This also fixes the shared upload boundary used by lipsync and avatar audio.
Public discovery is fixed: the existing skills installer now lists 9 skills, including style-remix, without an explicit name. The catalog, fresh-install list and manifest include it. The offload function extraction preserves the template-scene rewrite fallback and passes the offload suite.
Validation: bun run --cwd packages/cli test src/commands/templates.test.ts src/heygen src/commands/media-use src/cloud/offload.test.ts src/utils/skillsManifest.test.ts reports 183 passed. Removing both fixes makes the two targeted regressions fail; restoring them makes both pass. The prior actual-generate pending-timeout reproduction now yields one body-keyed job, and fresh adversarial controls cover lost response, timeout, successful replay, terminal failure and shared MIME consumers. Root bun run build and bun run lint pass. Hosted Fallow audit succeeds on this exact head (run 41498870011). No new Important finding in the delta or fresh adversarial pass.
Nit: README.md:85 and CLAUDE.md:7 retain “all 8” while the public catalog has nine; update those remaining counts.
Limits: this re-review exercises mocked service responses and local FFmpeg, not live paid generation, billing, a Free/Pro production pull or a full film. Concurrent independent cutout invocations were not exercised; the retry claim is limited to the tested sequential recovery paths. The original server-gate qualification remains: unpaid callers are refused before signing when purchase enforcement is enabled; the disabled-policy branch permits access. The author reports enforcement is enabled in production; I did not independently verify deployment configuration. Private pack contents/eval films remain outside this review.
Audited: all 16 delta files, retry/upload consumers, offload extraction and public catalog/manifest. Trusting: unchanged PR surfaces covered in my prior review and unchanged server/auth/payment internals.
Need: yes · Size: bounded delta · Reuse: shared MIME table and existing retry-key selection · Simpler: existing wrapper carries the endpoint-specific body key · Structure: fine
Risk: medium — private pack delivery and paid media contracts; fixes close the exercised retry and upload failures.
Verdict: APPROVE
Reasoning: Both prior Important job-contract findings and public discovery are resolved at this head; no new blocking defect found in the reviewed delta.
— hf-review
What
Style templates for HyperFrames Pro. A person asks their agent for a video in one of five styles (Collage Explainer, Finance Explainer, Animated Science Explainer, 3D Brand Explainer, 3D True Crime). The agent pulls that style's template pack on demand and makes the episode on the person's topic. A signed-out person gets the sign-in step; a Free account gets the upgrade step and nothing is downloaded.
Why
A template's value is its files, so a gate in the prompt alone protects nothing. The gate sits at delivery: packs live in private storage and the server hands a short-lived link only to a Pro plan. Making the film then spends plan credits through
media-use generate, priced and refused by the server.Related work
Refs #6833 (the plan sign-in and credit rules this follows).
How
skills/style-remix/: one public skill, listed with the other published skills.SKILL.mdlists the five templates when none is named and waits for a pick, checks the sign-in and plan, pulls, and holds the credit rules.references/remix.mdis the order of work; each template's own steps stay in its private pack.npx hyperframes templates pull <slug>: asksGET /v1/hyperframes/moments/<id>/bundlefor a five-minute link, downloads, checks the pinned sha256, and moves the template intotemplates/<slug>/whole. A pack already there is not downloaded again; 401, 402, 503 (one retry, never a public fallback) and 404 each end with a clear next step. Packs are pinned intemplates.ts, so a new pack ships with a CLI release.media-use generate:--type lipsync;--type cutout(a filmed shot out of its background, on the plan);--type avatarcan speak a finished voice (--audio) or use the person's own look (--avatar). Prices for these on the plan, and a voice is only picked when the avatar reads a script. A cutout sends its retry key as the body'srequest_id(the route dedupes there, not on the header), and uploads carry their real media type, so WebM and MOV inputs work.resolve --type sfx; a font shorthand whose size nests parentheses.cli.mdxgainstemplates pull; the media-use skill names the on-plan cutout and lipsync commands.Test plan
templates.test.ts(402, 401, 503 retry, hash mismatch, unsafe archive path),generate.test.ts(cutout of real WebM and MOV files: their upload type and a stablerequest_id),v3.test.ts(a server that dedupes on the body'srequest_idonly: a lost answer keeps it, a failed job moves it),offload.test.ts,adopt.test.mjs,registry.test.mjs, the font shorthand test.src/heygen,src/commands/media-use,templates.test.tsandoffload.test.ts: 125 passed. Fails without the fix: the cutout test seesaudio/mpegfor WebM and MOV.docs/packages/cli.mdx,skills/media-use, and the skill lists in README, AGENTS.md, CLAUDE.md anddocs/guides/skills.mdx.Size
About 1,100 added lines across 44 files: the
templatescommand and its tests (~280), the new skill (~110), themedia-use generatetypes and pricing (~250), and the small fixes with their tests.🤖 Generated with Claude Code