npm.io
0.9.12 • Published 3d ago

@reactor-models/helios

Licence
MIT
Version
0.9.12
Deps
1
Size
274 kB
Vulns
0
Weekly
0

@reactor-models/helios

Typed JavaScript + React SDK for the Helios model on Reactor. Version v0.9.12.


Get started

Scaffold a starter app for Helios with create-reactor-app:

npx create-reactor-app my-app --model=helios
pnpm dlx create-reactor-app my-app --model=helios

Install

npm install @reactor-models/helios
pnpm add @reactor-models/helios

The 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.

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.

Emits: generation_paused, command_error

No parameters.

JavaScript
import { HeliosModel } from "@reactor-models/helios";

const helios = new HeliosModel();
await helios.connect(jwt);

await helios.pause();
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.

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.

Emits: generation_started, command_error

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.

Emits: generation_resumed, command_error

No parameters.

JavaScript
import { HeliosModel } from "@reactor-models/helios";

const helios = new HeliosModel();
await helios.connect(jwt);

await helios.resume();
React
"use client";
import { useHelios } from "@reactor-models/helios";

function Example() {
  const { resume } = useHelios();

  return <button onClick={() => resume()}>resume</button>;
}
setSeed

Set seed

Parameter Type Required 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.

Emits: image_accepted, conditions_ready, command_error

Parameter Type Required Description
image FileRef Reference to a file uploaded via the Reactor presigned-URL 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);
await helios.setImage({ image: fileRef, image_b64: "" });
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.

Emits: prompt_accepted, conditions_ready

Parameter Type Required 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);

await helios.setPrompt({ prompt: "A sunset over the ocean" });
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

Set sr_scale

Parameter Type Required 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>;
}
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.

Emits: prompt_accepted

Parameter Type Required 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);

await helios.schedulePrompt({ chunk: 0, prompt: "A sunset over the ocean" });
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).

Emits: prompt_accepted, image_accepted, conditions_ready, command_error

Parameter Type Required Description
image FileRef Reference to a file uploaded via the Reactor presigned-URL 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);
await helios.setConditioning({ image: fileRef, prompt: "A sunset over the ocean" });
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

Set image_strength

Parameter Type Required 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.

Wire envelope ------------- Published with type: "state" (the snake-cased class name) so the envelope matches the pre-0.8 Helios protocol and existing clients (public-demos, the docs examples, older SDK consumers) keep working unchanged. Field names mirror the pre-0.8 contract one-for-one; the only addition is started, which the old shape couldn't express (running=False collapsed "never started" and "paused" into the same bit).

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 unknown 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, unknown> Pending scheduled prompts, keyed by the chunk index at which they take effect. Entries are removed once applied.
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,
  );
});
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,
  );
});
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);
});
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);
});
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);
});
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" />;
}

Keywords