Skip to content

Add higgsfield-video-studio: describe a clip, get a video file - #12

Closed
oxedom wants to merge 3 commits into
mainfrom
feat/higgsfield-video-studio
Closed

Add higgsfield-video-studio: describe a clip, get a video file#12
oxedom wants to merge 3 commits into
mainfrom
feat/higgsfield-video-studio

Conversation

@oxedom

@oxedom oxedom commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

A new template. Purely additive — one new cabinet directory, plus one line each in the two cover scripts so the slug is known to them.

What it does

Open the Studio page, type "steam rising from a cup on a windowsill, morning light, camera still", press Send. A one-shot Video Maker run generates the clip on the user's own Higgsfield account and it appears on the page as a playable tile.

A sibling to higgsfield-studio, but request-driven rather than brief-driven: the page carries the text box, so there is no brief.md.

How clips are stored

Higgsfield returns a link, not a file. So the agent downloads it to videos/<slug>-<YYYY-MM-DD>T<HH-MM-SS>.mp4 and writes a .txt beside it holding the prompt, model, duration, credits and the original URL.

The folder listing is the whole data model — no manifest, nothing overwritten, newest sorts first by the timestamp in the name. The .txt is what lets a clip be re-run with one thing changed. If the download fails the .txt is still written: the credits are spent and the link is the only way back to the clip.

Spending rules

Video is roughly a hundred times the cost of a still image, and a free trial starts at 10 credits. An agent left to iterate on a prompt could empty a plan in an afternoon. So the persona's spending rules sit above everything else in the file and the job prompt defers to them rather than restating them:

  • One clip per request, about five seconds
  • Cheapest video model that does the job
  • 2 credits per run, hard ceiling
  • One retry on an outright failure — never a second take because the first could be better
  • Not connected / out of credits / over the ceiling → write nothing at all, report the numbers, leave the EXAMPLE seeds untouched

The weekly routine ships enabled: false for the same reason. The page reads the job file and shows "Routine paused" until it is switched on.

The one behavioural change from chassis 2

/api/agents/headless caps at 120s and clips regularly run longer. The image page reports an abort as an error; here that would tell someone their clip failed while their credits were already committed. So an abort is its own outcome: the page says "Still generating", keeps the prompt text, and re-lists the folder every 15s for ten minutes.

Verified

Rendered in a real browser against a static harness with /api/tree stubbed:

  • Title, textarea, Send, and the standing cost line under the box
  • ROUTINE PAUSED read live off weekly-clip.yaml
  • The EXAMPLE banner, and both seed clips playing as 0:05 <video> tiles

The extracted <script> passes node --check; .cabinet, the job YAML and both frontmatter blocks parse.

Not done

  • No cover.jpg. Entries are added to compose-logo-covers.mjs and generate_image.js, but both hardcode paths that only resolve on the maintainer's machine, so the cover needs generating there.
  • The video tool name is not hardcoded. Higgsfield was not connected while building this, so the persona tells the agent to ask the connector what models it offers and take the cheapest — the same approach higgsfield-studio's persona uses — rather than shipping a guessed tool name. Worth one real run against a connected account before this is published.

oxedom added 2 commits August 18, 2026 12:21
A sibling to higgsfield-studio, but request-driven rather than brief-driven:
the Studio page carries the text box, and pressing Send dispatches a one-shot
Video Maker run against the user's own Higgsfield account.

Higgsfield returns a link rather than a file, so the agent downloads the clip
into videos/<slug>-<stamp>.mp4 and writes a .txt beside it holding the prompt,
model, duration, credits and the original URL. The folder listing stays the
whole data model — nothing is overwritten, and the .txt is what lets a clip be
re-run with one thing changed. If the download fails the .txt is still written:
the credits are spent and the link is the only way back to the clip.

Video is roughly a hundred times the cost of a still image and a free trial
starts at 10 credits, so the persona's spending rules come before everything
else in the file: one clip per request, about five seconds, cheapest video
model that does the job, 2 credits per run, one retry on an outright failure
and never a second take because the first could be better. Not connected, out
of credits, or over the ceiling all write nothing at all and report the numbers.
The weekly routine ships switched off for the same reason.

The page is a fork of gemini-image-studio's chassis-2 with one behavioural
change: /api/agents/headless caps at 120s and clips regularly run longer, so an
abort is no longer reported as a failure. It would tell someone their clip died
while their credits were already committed. Instead the page says "Still
generating", keeps the prompt text, and re-lists the folder until it appears.

No cover.jpg yet — the entries are added to both cover scripts, but those
hardcode paths that only resolve on the maintainer's machine.
The Send button called /api/agents/headless, which hardcodes timeoutMs 120_000
and, when it expires, calls terminateChildProcess(proc). The agent is killed —
the run does NOT continue in the background as the page claimed.

An image usually beats that clock. A clip usually does not. So the shipped page
told anyone whose clip took longer than two minutes "Still generating. The clip
will appear here when it is ready" and then polled for ten minutes for a file
that was never coming, while Higgsfield had already charged them for the
generation. Paid, killed, and reassured — the exact failure the persona's
spending rules exist to prevent.

Send now does two writes and waits for neither:

  PUT /api/pages/<cabinet>/requests/<stamp>   the prompt, status: pending
  PUT /api/agents/video-maker/jobs/on-demand-clip   {action: "run"}

Job runs are fire-and-forget and carry their own timeout, so on-demand-clip.yaml
sets 900s and the agent lives long enough to finish. executeJob() does not check
`enabled`, so the job ships switched off — never fired by the daemon — while the
button still works. The weekly routine is untouched; it always had its own 900s
budget and was never affected.

requests/ has exactly one writer. The job prompt forbids the agent from editing
those files at all, so an edit made while a clip generates cannot be clobbered
by an agent that read the file three minutes earlier.

Also corrects two claims the persona could not back:

- Model choice. Higgsfield's docs say the model is picked from the prose of the
  prompt, not a validated parameter, so "take the cheapest model" was advice the
  tool does not enforce. The persona now requires naming the model explicitly in
  the prompt and recording it, since an unnamed model is priced at whatever the
  service picks.
- Result shape. The persona asserted Higgsfield returns a link to download. Their
  documentation only says clips "land in your Higgsfield workspace", and
  generation is asynchronous with polling tools. It now handles a URL, a job id
  to poll, or neither — and is forbidden from inventing a link.
@oxedom

oxedom commented Aug 18, 2026

Copy link
Copy Markdown
Contributor Author

Correction: the Send button was broken, and is now fixed

Reviewing this against the app code turned up a real bug in what I originally shipped here.

/api/agents/headless hardcodes timeoutMs: 120_000, and on expiry runOneShotProviderPrompt calls terminateChildProcess(proc). The agent is killed. The run does not continue in the background, which is what the page assumed.

An image usually beats that clock. A clip usually does not. So the original page told anyone whose clip ran past two minutes "Still generating. The clip will appear here when it is ready" and polled for ten minutes for a file that was never coming — while Higgsfield had already charged them for the generation. Paid, killed, and reassured.

The fix

Send now does two writes and waits for neither:

PUT /api/pages/<cabinet>/requests/<stamp>          the prompt, status: pending
PUT /api/agents/video-maker/jobs/on-demand-clip    {action: "run"}

Job runs are fire-and-forget and carry their own timeout, so on-demand-clip.yaml sets timeout: 900. executeJob() never checks enabled, so the job ships switched off — the daemon never fires it — while the button still works.

requests/ has exactly one writer. The job prompt forbids the agent from editing those files, so an edit made while a clip generates cannot be clobbered by an agent that read the file three minutes earlier.

The weekly routine is untouched — it always ran through the scheduler with its own 900s budget and was never affected.

Two persona claims corrected

  • Model choice. Higgsfield's docs say the model is picked from the prose of the prompt, not a validated parameter. "Take the cheapest model" was advice the tool does not enforce, so the persona now requires naming the model explicitly and recording it — an unnamed model is priced at whatever the service picks.
  • Result shape. The persona asserted Higgsfield returns a link to download. Their documentation only says clips "land in your Higgsfield workspace", and generation is async with polling tools. It now handles a URL, a job id to poll, or neither, and is forbidden from inventing a link.

Still unverified

Higgsfield is not connected on this machine, so the tool schemas remain unseen. The two corrections above make the persona honest about that uncertainty rather than resolving it. A zero-credit tool-surface pass once it is connected is still the right gate before merge.

A smoke test from 2026-08-12 settles what the docs left vague. The tools do
expose a credit preflight (z_image 0.15 vs nano_banana 1.00) and models are real
ids passed as parameters, not prose the service interprets. Generations return a
job id first and a CloudFront URL on completion.

That makes the 2-credit ceiling an actual check rather than an intention, so the
persona now requires pricing a generation before committing to it.
@oxedom

oxedom commented Aug 18, 2026

Copy link
Copy Markdown
Contributor Author

Superseded by #13, which now contains this branch merged in — every commit here is in that history. Closing so there is one review surface for both video cabinets rather than two carrying the same reasoning.

@oxedom oxedom closed this Aug 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant