@reactor-models/helios
v1.0.1
Published
Strongly-typed SDK for the Helios model on Reactor
Maintainers
Readme
@reactor-models/helios
Typed JavaScript + React SDK for the Helios model on Reactor. Version v1.0.1.
Get started
Scaffold a starter app for Helios with create-reactor-app:
npx create-reactor-app my-app --model=heliospnpm dlx create-reactor-app my-app --model=heliosInstall
npm install @reactor-models/heliospnpm add @reactor-models/heliosThe package exports a plain-JavaScript client and a set of React bindings. Import whichever you need from @reactor-models/helios:
import { HeliosModel } from "@reactor-models/helios";import { HeliosProvider, useHelios } from "@reactor-models/helios";React 18 or later is required when using the provider and hooks. The token-loading examples below use React 19's use(); on React 18, fetch the JWT in a useEffect and pass it to the provider once it resolves.
Authenticate
Reactor uses short-lived JWTs for session auth. You hold your API key on your server, mint a token on demand, and the client never sees the raw key. Tokens are valid for 6 hours — if one leaks, it expires on its own.
Mint a JWT with POST https://api.reactor.inc/tokens and the Reactor-API-Key header; the response JSON is { "jwt": "..." }.
JavaScript (Next.js route handler)
// app/api/reactor/token/route.ts
import { NextResponse } from "next/server";
export async function POST() {
const res = await fetch("https://api.reactor.inc/tokens", {
method: "POST",
headers: { "Reactor-API-Key": process.env.REACTOR_API_KEY! },
});
const { jwt } = await res.json();
return NextResponse.json({ jwt });
}React (provider)
Call the /api/reactor/token route above from a client component and pass the result to the provider:
"use client";
import { use } from "react";
import { HeliosProvider } from "@reactor-models/helios";
import { ReactorView } from "@reactor-team/js-sdk";
async function getToken() {
const r = await fetch("/api/reactor/token", { method: "POST" });
const { jwt } = await r.json();
return jwt;
}
const tokenPromise = getToken();
export default function App() {
const token = use(tokenPromise);
return (
<HeliosProvider jwtToken={token} connectOptions={{ autoConnect: true }}>
<ReactorView className="w-full aspect-video" />
</HeliosProvider>
);
}Connect
JavaScript
import { HeliosModel } from "@reactor-models/helios";
const helios = new HeliosModel();
await helios.connect(jwt);React
The provider takes the JWT as a prop; fetch it from the same /api/reactor/token route the Authenticate example mints:
"use client";
import { use } from "react";
import { HeliosProvider, useHelios } from "@reactor-models/helios";
async function getToken() {
const r = await fetch("/api/reactor/token", { method: "POST" });
const { jwt } = await r.json();
return jwt;
}
const tokenPromise = getToken();
function Controller() {
const { status } = useHelios();
return <span>Status: {status}</span>;
}
export default function App() {
const token = use(tokenPromise);
return (
<HeliosProvider jwtToken={token}>
<Controller />
</HeliosProvider>
);
}Events
Client-to-model commands. The typed surface is HeliosModel (one method per event) in plain JS, and useHelios() in React — every field name below matches the parameter name the method accepts. Every awaited call resolves once the model's handler has completed; a command whose handler returns a message resolves with that reply (see each event's "Returns" line).
pause
Pause generation after the current chunk finishes. Frames stop streaming on main_video until resume is called. Requires generation to be active. Emits generation_paused on success, or command_error if not generating or already paused.
Returns: generation_paused — { type: "generation_paused", chunk_index: 0 } (or undefined when the send fails).
No parameters.
JavaScript
import { HeliosModel } from "@reactor-models/helios";
const helios = new HeliosModel();
await helios.connect(jwt);
const reply = await helios.pause();
if (reply) {
console.log("generation_paused", reply.chunk_index);
}React
"use client";
import { useHelios } from "@reactor-models/helios";
function Example() {
const { pause } = useHelios();
return <button onClick={() => pause()}>pause</button>;
}reset
Clear all session conditions (prompt, reference image, chunk index) and return the session to the initial waiting state. After reset, a new prompt must be set before start can be called again.
Returns: nothing — the awaited call resolves undefined once the model's handler has run.
No parameters.
JavaScript
import { HeliosModel } from "@reactor-models/helios";
const helios = new HeliosModel();
await helios.connect(jwt);
await helios.reset();React
"use client";
import { useHelios } from "@reactor-models/helios";
function Example() {
const { reset } = useHelios();
return <button onClick={() => reset()}>reset</button>;
}start
Begin generating video on main_video. Requires that a prompt has been set via set_prompt or schedule_prompt. Emits generation_started on success, or command_error if no prompt is set. Has no effect while already generating.
Returns: nothing — the awaited call resolves undefined once the model's handler has run.
No parameters.
JavaScript
import { HeliosModel } from "@reactor-models/helios";
const helios = new HeliosModel();
await helios.connect(jwt);
await helios.start();React
"use client";
import { useHelios } from "@reactor-models/helios";
function Example() {
const { start } = useHelios();
return <button onClick={() => start()}>start</button>;
}resume
Resume generation from the exact state at which pause was issued. Emits generation_resumed on success, or command_error if not currently paused.
Returns: generation_resumed — { type: "generation_resumed", chunk_index: 0 } (or undefined when the send fails).
No parameters.
JavaScript
import { HeliosModel } from "@reactor-models/helios";
const helios = new HeliosModel();
await helios.connect(jwt);
const reply = await helios.resume();
if (reply) {
console.log("generation_resumed", reply.chunk_index);
}React
"use client";
import { useHelios } from "@reactor-models/helios";
function Example() {
const { resume } = useHelios();
return <button onClick={() => resume()}>resume</button>;
}rewind
Restore the model to a previously saved snapshot. The restore is queued: generation resumes from the snapshot's chunk at the next chunk boundary. Only the scene is restored, never the prompt — send [set_prompt](#setprompt) after this call to steer the restored scene somewhere new, or to re-apply the prompt the snapshot was saved under. The restored snapshot becomes current_snapshot_id, so the next [save_snapshot](#savesnapshot) branches off it. Emits a [state](#state) update followed by [rewind_complete](#rewind_complete) once queued, or [rewind_failed](#rewind_failed) when the buffer is empty, the index is out of range, or no session is active.
Returns: rewind_complete — { type: "rewind_complete", chunk: 0, snapshot_index: 0 } (or undefined when the send fails).
| Parameter | Type | Description |
|---|---|---|
| snapshot_index | number | Which snapshot to restore. Positive values are snapshot IDs (numbered from 1): pass the snapshot_index from a previous [snapshot_saved](#snapshot_saved) message to target that checkpoint. Negative values count back from the newest snapshot held: -1 (default) is the most recent, -2 the one before it, and so on. Either form emits [rewind_failed](#rewind_failed) if the target is not in the buffer. (default -1) |
JavaScript
import { HeliosModel } from "@reactor-models/helios";
const helios = new HeliosModel();
await helios.connect(jwt);
const reply = await helios.rewind({ snapshot_index: 0 });
if (reply) {
console.log("rewind_complete", reply.chunk, reply.snapshot_index);
}React
"use client";
import { useHelios } from "@reactor-models/helios";
function Example() {
const { rewind } = useHelios();
return <button onClick={() => rewind({ snapshot_index: 0 })}>rewind</button>;
}setSeed
Seed for the random generator used to sample the initial noise. Use -1 to draw a fresh random seed. Read once when generation begins; later changes take effect only after reset followed by a new start.
Returns: nothing — the awaited call resolves undefined once the model's handler has run.
| Parameter | Type | Description |
|---|---|---|
| seed | number | Seed for the random generator used to sample the initial noise. Use -1 to draw a fresh random seed. Read once when generation begins; later changes take effect only after reset followed by a new start. (default 0) |
JavaScript
import { HeliosModel } from "@reactor-models/helios";
const helios = new HeliosModel();
await helios.connect(jwt);
await helios.setSeed({ seed: 0 });React
"use client";
import { useHelios } from "@reactor-models/helios";
function Example() {
const { setSeed } = useHelios();
return <button onClick={() => setSeed({ seed: 0 })}>setSeed</button>;
}setImage
Provide a reference image that anchors generation (image-to-video). Can be set before start or replaced during generation; a new image applies from the next chunk onward. Exactly one of image (preferred) or image_b64 must be provided. Emits image_accepted and conditions_ready on success, or command_error if the file is missing or not an image. When both a prompt and an image are needed before start, prefer set_conditioning — it commits both atomically and avoids the ordering race between set_prompt and set_image.
Returns: image_accepted — { type: "image_accepted", width: 0, height: 0 } (or undefined when the send fails).
| Parameter | Type | Description |
|---|---|---|
| image | FileRef | Reference to a file uploaded via the Reactor upload protocol. (default null) |
| image_b64 | string | Deprecated. Base64-encoded reference image (PNG or JPEG), optionally prefixed with a data: URI. Provided for backward compatibility; use image instead. Ignored when image is also present. (default "") |
JavaScript
import { HeliosModel } from "@reactor-models/helios";
const helios = new HeliosModel();
await helios.connect(jwt);
const fileRef = await helios.uploadFile(blob);
const reply = await helios.setImage({ image: fileRef, image_b64: "" });
if (reply) {
console.log("image_accepted", reply.width, reply.height);
}React
"use client";
import { useHelios } from "@reactor-models/helios";
function Example() {
const { setImage, uploadFile } = useHelios();
async function handlePick(file: File) {
const ref = await uploadFile(file);
await setImage({ image: ref, image_b64: "" });
}
return <input type="file" onChange={(e) => handlePick(e.target.files![0])} />;
}setPrompt
Set the scene prompt. Valid at any time: call before start to arm generation, or hot-swap during generation to steer the next chunk. Emits prompt_accepted and conditions_ready on success. When you also need to set a reference image before the first start, use set_conditioning instead to commit both atomically.
Returns: prompt_accepted — { type: "prompt_accepted", prompt: "A sunset over the ocean" } (or undefined when the send fails).
| Parameter | Type | Description |
|---|---|---|
| prompt | string | Natural-language description of the scene to generate. Replaces any previously active prompt and takes effect on the next chunk. (default "") |
JavaScript
import { HeliosModel } from "@reactor-models/helios";
const helios = new HeliosModel();
await helios.connect(jwt);
const reply = await helios.setPrompt({ prompt: "A sunset over the ocean" });
if (reply) {
console.log("prompt_accepted", reply.prompt);
}React
"use client";
import { useHelios } from "@reactor-models/helios";
function Example() {
const { setPrompt } = useHelios();
return <button onClick={() => setPrompt({ prompt: "A sunset over the ocean" })}>setPrompt</button>;
}setSrScale
Super-resolution factor applied to each emitted frame. off disables upscaling, 2x and 4x upscale the output. May be changed at any time; the new scale applies to the next emitted chunk.
Returns: nothing — the awaited call resolves undefined once the model's handler has run.
| Parameter | Type | Description |
|---|---|---|
| sr_scale | "off" \| "2x" \| "4x" | Super-resolution factor applied to each emitted frame. off disables upscaling, 2x and 4x upscale the output. May be changed at any time; the new scale applies to the next emitted chunk. (default "2x") |
JavaScript
import { HeliosModel } from "@reactor-models/helios";
const helios = new HeliosModel();
await helios.connect(jwt);
await helios.setSrScale({ sr_scale: "off" });React
"use client";
import { useHelios } from "@reactor-models/helios";
function Example() {
const { setSrScale } = useHelios();
return <button onClick={() => setSrScale({ sr_scale: "off" })}>setSrScale</button>;
}saveSnapshot
Capture the current world state into the snapshot buffer so [rewind](#rewind) can return to it later. The buffer holds up to 50 snapshots and evicts the oldest when full. Emits [snapshot_saved](#snapshot_saved) with the snapshot ID, current chunk, and the snapshot it descends from, or [rewind_failed](#rewind_failed) if no chunk has completed yet. The new snapshot descends from whatever current_snapshot_id named, and becomes the new current_snapshot_id — so saving after a [rewind](#rewind) starts a branch off the restored snapshot, while saving without one extends the current branch. An optional label is stored with the snapshot and returned by [list_snapshots](#listsnapshots) for display.
Returns: snapshot_saved — { type: "snapshot_saved", chunk: 0, parent_id: null, snapshot_index: 0 } (or undefined when the send fails).
| Parameter | Type | Description |
|---|---|---|
| label | string | Optional human-readable label stored with the snapshot and returned by [list_snapshots](#listsnapshots) (e.g. 'before-cat-scene'). Purely decorative. (default "") |
JavaScript
import { HeliosModel } from "@reactor-models/helios";
const helios = new HeliosModel();
await helios.connect(jwt);
const reply = await helios.saveSnapshot({ label: "" });
if (reply) {
console.log(
"snapshot_saved",
reply.chunk,
reply.parent_id,
reply.snapshot_index,
);
}React
"use client";
import { useHelios } from "@reactor-models/helios";
function Example() {
const { saveSnapshot } = useHelios();
return <button onClick={() => saveSnapshot({ label: "" })}>saveSnapshot</button>;
}listSnapshots
Return the snapshots currently in the buffer, oldest first. Each entry carries snapshot_index (monotonic ID), chunk (chunk index at capture), label (the label passed to [save_snapshot](#savesnapshot)), parent_id (ID of the snapshot this one descends from, or null for a root), and prompt (the prompt driving generation at capture). The parents form a tree: a save after a [rewind](#rewind) branches off the restored snapshot, a save without one extends the current branch, and current_snapshot_id on the [state](#state) message says which branch is live. Saving evicts the oldest entry, so a parent_id may name a snapshot no longer listed — treat an unresolvable parent as a root. Emits [snapshot_list](#snapshot_list) immediately; always succeeds.
Returns: snapshot_list — { type: "snapshot_list", snapshots: null } (or undefined when the send fails).
No parameters.
JavaScript
import { HeliosModel } from "@reactor-models/helios";
const helios = new HeliosModel();
await helios.connect(jwt);
const reply = await helios.listSnapshots();
if (reply) {
console.log("snapshot_list", reply.snapshots);
}React
"use client";
import { useHelios } from "@reactor-models/helios";
function Example() {
const { listSnapshots } = useHelios();
return <button onClick={() => listSnapshots()}>listSnapshots</button>;
}schedulePrompt
Queue a prompt to take effect at a specific future chunk index. Multiple prompts can be queued; at each chunk boundary the latest scheduled prompt at or before the current chunk wins. Scheduling a prompt for a past chunk applies it on the next chunk. Emits prompt_accepted.
Returns: prompt_accepted — { type: "prompt_accepted", prompt: "A sunset over the ocean" } (or undefined when the send fails).
| Parameter | Type | Description |
|---|---|---|
| chunk | number | Zero-based chunk index at which the prompt takes effect. Chunk indices match those reported by chunk_complete. (min 0, default 0) |
| prompt | string | Natural-language description of the scene that should become active starting at the given chunk. (default "") |
JavaScript
import { HeliosModel } from "@reactor-models/helios";
const helios = new HeliosModel();
await helios.connect(jwt);
const reply = await helios.schedulePrompt({ chunk: 0, prompt: "A sunset over the ocean" });
if (reply) {
console.log("prompt_accepted", reply.prompt);
}React
"use client";
import { useHelios } from "@reactor-models/helios";
function Example() {
const { schedulePrompt } = useHelios();
return <button onClick={() => schedulePrompt({ chunk: 0, prompt: "A sunset over the ocean" })}>schedulePrompt</button>;
}setConditioning
Atomically commit a prompt and a reference image together, in a single command. Use this in place of separate set_prompt and set_image calls when both are required before start — the combined command can't be split across the wire, so it removes the race where start is processed before the image upload has been resolved. Both prompt and image are required. Emits prompt_accepted, image_accepted, and conditions_ready on success, or command_error if any input is missing or invalid (no state is mutated on error).
Returns: conditions_ready — { type: "conditions_ready", has_image: true, has_prompt: true } (or undefined when the send fails).
| Parameter | Type | Description |
|---|---|---|
| image | FileRef | Reference to a file uploaded via the Reactor upload protocol. (default null) |
| prompt | string | Natural-language description of the scene to generate. Replaces any previously active prompt and takes effect on the next chunk. (default "") |
JavaScript
import { HeliosModel } from "@reactor-models/helios";
const helios = new HeliosModel();
await helios.connect(jwt);
const fileRef = await helios.uploadFile(blob);
const reply = await helios.setConditioning({ image: fileRef, prompt: "A sunset over the ocean" });
if (reply) {
console.log("conditions_ready", reply.has_image, reply.has_prompt);
}React
"use client";
import { useHelios } from "@reactor-models/helios";
function Example() {
const { setConditioning, uploadFile } = useHelios();
async function handlePick(file: File) {
const ref = await uploadFile(file);
await setConditioning({ image: ref, prompt: "A sunset over the ocean" });
}
return <input type="file" onChange={(e) => handlePick(e.target.files![0])} />;
}setImageStrength
How strongly the reference image anchors the generated video. 1.0 locks the first frame to the reference; lower values let the scene drift further from it. Ignored when no reference image has been set. May be changed at any time; the new value is read at the start of the next chunk.
Returns: nothing — the awaited call resolves undefined once the model's handler has run.
| Parameter | Type | Description |
|---|---|---|
| image_strength | number | How strongly the reference image anchors the generated video. 1.0 locks the first frame to the reference; lower values let the scene drift further from it. Ignored when no reference image has been set. May be changed at any time; the new value is read at the start of the next chunk. (min 0, max 1, default 1) |
JavaScript
import { HeliosModel } from "@reactor-models/helios";
const helios = new HeliosModel();
await helios.connect(jwt);
await helios.setImageStrength({ image_strength: 1 });React
"use client";
import { useHelios } from "@reactor-models/helios";
function Example() {
const { setImageStrength } = useHelios();
return <button onClick={() => setImageStrength({ image_strength: 1 })}>setImageStrength</button>;
}Messages
Model-to-client messages. Register a typed listener with on… on HeliosModel, or a useHelios… hook in React, to receive only the messages you care about.
state
Snapshot of the session's observable state.
Emitted after every completed chunk and after any command that mutates
session state (set_prompt, schedule_prompt, set_image, start,
pause, resume, reset). Clients can treat this as the single
source of truth for driving UI, without having to track every
individual command and message themselves.
The snapshot buffer is deliberately not carried here: state is
emitted after every completed chunk, and re-sending the whole buffer
at that rate would repeat the same prompts every second. Call
list_snapshots for the buffer contents; read current_snapshot_id
here to know where in it the model currently sits.
Listener: onState · React hook: useHeliosState
| Field | Type | Description |
|---|---|---|
| paused | boolean | True while generation is paused via pause. |
| running | boolean | True while the chunk loop is actively producing frames — equivalent to started and not paused. False both before start and while paused; read started to disambiguate. |
| started | boolean | True once start has been accepted. Remains true while paused; reset to false by reset. Distinguishes a paused run (started=True, paused=True) from a session that has never started (started=False, paused=False) — the running flag collapses both of those to False. |
| image_set | boolean | True once a reference image has been set for the session. |
| current_chunk | number | Zero-based index of the chunk the model is currently working on. 0 for a fresh session or after reset. |
| current_frame | number | Running total of frames emitted on main_video since the last reset (or session connect). Resets to 0 on reset. |
| current_prompt | string \| null | The prompt currently driving generation, or null if no prompt has been applied yet (e.g. before start). |
| image_strength | number | Current value of the image_strength input field (0.0–1.0). Ignored when no reference image is set. |
| scheduled_prompts | Record<string, string> | Pending scheduled prompts, keyed by the chunk index (as a decimal string) at which they take effect. Entries are removed once applied. |
| current_snapshot_id | number \| null | ID of the snapshot the current generation descends from, or null before the first save_snapshot. Set by save_snapshot (to the new snapshot) and by rewind (to the restored one), and unchanged as chunks advance, so it names the branch being generated rather than a position on it. This is the only way to tell which branch is live: after a rewind, current_chunk alone is ambiguous because two snapshots can sit at the same chunk on different branches. Matches the parent_id the next save_snapshot will record. (default null) |
JavaScript
import { HeliosModel } from "@reactor-models/helios";
const helios = new HeliosModel();
helios.onState((msg) => {
console.log(
"state",
msg.paused,
msg.running,
msg.started,
msg.image_set,
msg.current_chunk,
msg.current_frame,
msg.current_prompt,
msg.image_strength,
msg.scheduled_prompts,
msg.current_snapshot_id,
);
});
await helios.connect(jwt);React
import { useHeliosState } from "@reactor-models/helios";
// Inside a React component wrapped by <HeliosProvider>:
useHeliosState((msg) => {
console.log(
"state",
msg.paused,
msg.running,
msg.started,
msg.image_set,
msg.current_chunk,
msg.current_frame,
msg.current_prompt,
msg.image_strength,
msg.scheduled_prompts,
msg.current_snapshot_id,
);
});command_error
Emitted when a command is rejected because preconditions are not met.
Listener: onCommandError · React hook: useHeliosCommandError
| Field | Type | Description |
|---|---|---|
| reason | string | Human-readable explanation of why the command was rejected. |
| command | string | Name of the command that was rejected. |
JavaScript
import { HeliosModel } from "@reactor-models/helios";
const helios = new HeliosModel();
helios.onCommandError((msg) => {
console.log("command_error", msg.reason, msg.command);
});
await helios.connect(jwt);React
import { useHeliosCommandError } from "@reactor-models/helios";
// Inside a React component wrapped by <HeliosProvider>:
useHeliosCommandError((msg) => {
console.log("command_error", msg.reason, msg.command);
});rewind_failed
Emitted when save_snapshot or rewind cannot be completed.
Listener: onRewindFailed · React hook: useHeliosRewindFailed
| Field | Type | Description |
|---|---|---|
| reason | string | Human-readable explanation of why the operation failed. |
JavaScript
import { HeliosModel } from "@reactor-models/helios";
const helios = new HeliosModel();
helios.onRewindFailed((msg) => {
console.log("rewind_failed", msg.reason);
});
await helios.connect(jwt);React
import { useHeliosRewindFailed } from "@reactor-models/helios";
// Inside a React component wrapped by <HeliosProvider>:
useHeliosRewindFailed((msg) => {
console.log("rewind_failed", msg.reason);
});snapshot_list
Emitted in response to list_snapshots.
Contains every snapshot in the buffer, oldest first. The buffer holds up
to 50 entries and drops the oldest as new snapshots are saved, so entries
fall out of this list over time; IDs are never reused until reset empties
the buffer and restarts numbering. The buffer belongs to the session: it
starts empty and is released when the session ends, so snapshots are never
visible to a later session.
Every entry records the snapshot it descends from in parent_id, so the
entries form a tree: saving after a rewind branches off the restored
snapshot, and saving without one extends the current branch. Because the
buffer evicts the oldest entry, a parent_id can name a snapshot no
longer listed — treat an unresolvable parent as a branch root rather than
an error.
Listener: onSnapshotList · React hook: useHeliosSnapshotList
| Field | Type | Description |
|---|---|---|
| snapshots | { "chunk": number; "label": string; "prompt": string; "parent_id": number \| null; "snapshot_index": number }[] | Snapshot descriptors, oldest first. Each entry carries snapshot_index (monotonic ID), chunk (chunk index at capture), label (the label passed to save_snapshot, or an empty string), parent_id (ID of the snapshot this one descends from, or null for a root), and prompt (the prompt driving generation when the snapshot was saved). |
JavaScript
import { HeliosModel } from "@reactor-models/helios";
const helios = new HeliosModel();
helios.onSnapshotList((msg) => {
console.log("snapshot_list", msg.snapshots);
});
await helios.connect(jwt);React
import { useHeliosSnapshotList } from "@reactor-models/helios";
// Inside a React component wrapped by <HeliosProvider>:
useHeliosSnapshotList((msg) => {
console.log("snapshot_list", msg.snapshots);
});chunk_complete
Emitted once per completed 33-frame chunk of main_video.
Listener: onChunkComplete · React hook: useHeliosChunkComplete
| Field | Type | Description |
|---|---|---|
| chunk_index | number | Zero-based index of the chunk that just completed. |
| active_prompt | string | The prompt used to generate this chunk. |
| frames_emitted | number | Running total of frames emitted on main_video up to and including this chunk. |
JavaScript
import { HeliosModel } from "@reactor-models/helios";
const helios = new HeliosModel();
helios.onChunkComplete((msg) => {
console.log(
"chunk_complete",
msg.chunk_index,
msg.active_prompt,
msg.frames_emitted,
);
});
await helios.connect(jwt);React
import { useHeliosChunkComplete } from "@reactor-models/helios";
// Inside a React component wrapped by <HeliosProvider>:
useHeliosChunkComplete((msg) => {
console.log(
"chunk_complete",
msg.chunk_index,
msg.active_prompt,
msg.frames_emitted,
);
});image_accepted
Emitted after set_image successfully loads a reference image.
Listener: onImageAccepted · React hook: useHeliosImageAccepted
| Field | Type | Description |
|---|---|---|
| width | number | Width in pixels of the reference image after it was center-cropped and resized to the model's output resolution. |
| height | number | Height in pixels of the reference image after it was center-cropped and resized to the model's output resolution. |
JavaScript
import { HeliosModel } from "@reactor-models/helios";
const helios = new HeliosModel();
helios.onImageAccepted((msg) => {
console.log("image_accepted", msg.width, msg.height);
});
await helios.connect(jwt);React
import { useHeliosImageAccepted } from "@reactor-models/helios";
// Inside a React component wrapped by <HeliosProvider>:
useHeliosImageAccepted((msg) => {
console.log("image_accepted", msg.width, msg.height);
});snapshot_saved
Emitted after save_snapshot successfully captures the world state.
Listener: onSnapshotSaved · React hook: useHeliosSnapshotSaved
| Field | Type | Description |
|---|---|---|
| chunk | number | Chunk index at which the snapshot was captured. |
| parent_id | number \| null | ID of the snapshot this one descends from — the value current_snapshot_id held before this call — or null when it is a root. Saving straight after a rewind makes the restored snapshot the parent, which is what turns a rewind into a branch. (default null) |
| snapshot_index | number | Monotonic snapshot ID, numbered from 1 and never reused until reset empties the buffer and restarts numbering. Pass it to rewind to restore this checkpoint; a rewind to an ID no longer in the buffer fails with rewind_failed. |
JavaScript
import { HeliosModel } from "@reactor-models/helios";
const helios = new HeliosModel();
helios.onSnapshotSaved((msg) => {
console.log(
"snapshot_saved",
msg.chunk,
msg.parent_id,
msg.snapshot_index,
);
});
await helios.connect(jwt);React
import { useHeliosSnapshotSaved } from "@reactor-models/helios";
// Inside a React component wrapped by <HeliosProvider>:
useHeliosSnapshotSaved((msg) => {
console.log(
"snapshot_saved",
msg.chunk,
msg.parent_id,
msg.snapshot_index,
);
});prompt_accepted
Emitted after set_prompt or schedule_prompt is accepted.
Listener: onPromptAccepted · React hook: useHeliosPromptAccepted
| Field | Type | Description |
|---|---|---|
| prompt | string | The prompt text that was accepted. |
JavaScript
import { HeliosModel } from "@reactor-models/helios";
const helios = new HeliosModel();
helios.onPromptAccepted((msg) => {
console.log("prompt_accepted", msg.prompt);
});
await helios.connect(jwt);React
import { useHeliosPromptAccepted } from "@reactor-models/helios";
// Inside a React component wrapped by <HeliosProvider>:
useHeliosPromptAccepted((msg) => {
console.log("prompt_accepted", msg.prompt);
});rewind_complete
Emitted once rewind has queued a restore.
Sent when the restore is accepted, not when it is applied: generation
continues on the pre-rewind branch until the next chunk boundary. The
state message carrying the new current_snapshot_id is emitted before
this one, so a client that waits on rewind_complete already holds the
updated state.
Listener: onRewindComplete · React hook: useHeliosRewindComplete
| Field | Type | Description |
|---|---|---|
| chunk | number | Chunk index the model will continue generating from. |
| snapshot_index | number | Monotonic ID of the snapshot that was restored. |
JavaScript
import { HeliosModel } from "@reactor-models/helios";
const helios = new HeliosModel();
helios.onRewindComplete((msg) => {
console.log("rewind_complete", msg.chunk, msg.snapshot_index);
});
await helios.connect(jwt);React
import { useHeliosRewindComplete } from "@reactor-models/helios";
// Inside a React component wrapped by <HeliosProvider>:
useHeliosRewindComplete((msg) => {
console.log("rewind_complete", msg.chunk, msg.snapshot_index);
});conditions_ready
Emitted after set_prompt or set_image so the client can tell
at a glance whether start will succeed.
Listener: onConditionsReady · React hook: useHeliosConditionsReady
| Field | Type | Description |
|---|---|---|
| has_image | boolean | True once a reference image has been set for the session. |
| has_prompt | boolean | True once at least one prompt has been set for the session. |
JavaScript
import { HeliosModel } from "@reactor-models/helios";
const helios = new HeliosModel();
helios.onConditionsReady((msg) => {
console.log("conditions_ready", msg.has_image, msg.has_prompt);
});
await helios.connect(jwt);React
import { useHeliosConditionsReady } from "@reactor-models/helios";
// Inside a React component wrapped by <HeliosProvider>:
useHeliosConditionsReady((msg) => {
console.log("conditions_ready", msg.has_image, msg.has_prompt);
});generation_paused
Emitted in response to pause, once the current chunk finishes.
Listener: onGenerationPaused · React hook: useHeliosGenerationPaused
| Field | Type | Description |
|---|---|---|
| chunk_index | number | Index of the last completed chunk before pausing. |
JavaScript
import { HeliosModel } from "@reactor-models/helios";
const helios = new HeliosModel();
helios.onGenerationPaused((msg) => {
console.log("generation_paused", msg.chunk_index);
});
await helios.connect(jwt);React
import { useHeliosGenerationPaused } from "@reactor-models/helios";
// Inside a React component wrapped by <HeliosProvider>:
useHeliosGenerationPaused((msg) => {
console.log("generation_paused", msg.chunk_index);
});generation_resumed
Emitted in response to resume when leaving the paused state.
Listener: onGenerationResumed · React hook: useHeliosGenerationResumed
| Field | Type | Description |
|---|---|---|
| chunk_index | number | Index of the next chunk to be generated. |
JavaScript
import { HeliosModel } from "@reactor-models/helios";
const helios = new HeliosModel();
helios.onGenerationResumed((msg) => {
console.log("generation_resumed", msg.chunk_index);
});
await helios.connect(jwt);React
import { useHeliosGenerationResumed } from "@reactor-models/helios";
// Inside a React component wrapped by <HeliosProvider>:
useHeliosGenerationResumed((msg) => {
console.log("generation_resumed", msg.chunk_index);
});generation_started
Emitted once when start succeeds and frames begin streaming.
Listener: onGenerationStarted · React hook: useHeliosGenerationStarted
| Field | Type | Description |
|---|---|---|
| prompt | string | The prompt active at the start of generation. |
| chunk_index | number | Chunk index at which generation begins. Always 0 for a fresh session or after a reset. |
JavaScript
import { HeliosModel } from "@reactor-models/helios";
const helios = new HeliosModel();
helios.onGenerationStarted((msg) => {
console.log("generation_started", msg.prompt, msg.chunk_index);
});
await helios.connect(jwt);React
import { useHeliosGenerationStarted } from "@reactor-models/helios";
// Inside a React component wrapped by <HeliosProvider>:
useHeliosGenerationStarted((msg) => {
console.log("generation_started", msg.prompt, msg.chunk_index);
});Tracks
Named media channels between your app and the Helios model. Use the typed helpers below — HeliosModel.publish<Track> / on<Track> in plain JS, and useHeliosTrack or the per-track <Helios<Track>View> components in React — so track names are checked at compile time.
main_video
A video channel you subscribe to — the model publishes this for your app to render.
JavaScript
import { HeliosModel } from "@reactor-models/helios";
const helios = new HeliosModel();
helios.onMainVideo((track, stream) => {
// attach to a <video> element, pipe to a canvas, etc.
videoEl.srcObject = stream;
});
await helios.connect(jwt);React
"use client";
import { HeliosMainVideoView } from "@reactor-models/helios";
// Inside a component wrapped by <HeliosProvider>:
export function Example() {
return <HeliosMainVideoView className="w-full aspect-video" />;
}