npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@reactor-models/visko-orbis-stable

v2.3.0

Published

Strongly-typed SDK for the ViskoOrbisStable model on Reactor

Downloads

360

Readme

@reactor-models/visko-orbis-stable

Typed JavaScript + React SDK for the ViskoOrbisStable model on Reactor. Version v2.3.0.


Get started

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

npx create-reactor-app my-app --model=visko-orbis-stable
pnpm dlx create-reactor-app my-app --model=visko-orbis-stable

Install

npm install @reactor-models/visko-orbis-stable
pnpm add @reactor-models/visko-orbis-stable

The package exports a plain-JavaScript client and a set of React bindings. Import whichever you need from @reactor-models/visko-orbis-stable:

import { ViskoOrbisStableModel } from "@reactor-models/visko-orbis-stable";
import { ViskoOrbisStableProvider, useViskoOrbisStable } from "@reactor-models/visko-orbis-stable";

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 { ViskoOrbisStableProvider } from "@reactor-models/visko-orbis-stable";
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 (
    <ViskoOrbisStableProvider jwtToken={token} connectOptions={{ autoConnect: true }}>
      <ReactorView className="w-full aspect-video" />
    </ViskoOrbisStableProvider>
  );
}

Connect

JavaScript

import { ViskoOrbisStableModel } from "@reactor-models/visko-orbis-stable";

const viskoOrbisStable = new ViskoOrbisStableModel();
await viskoOrbisStable.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 { ViskoOrbisStableProvider, useViskoOrbisStable } from "@reactor-models/visko-orbis-stable";

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 } = useViskoOrbisStable();
  return <span>Status: {status}</span>;
}

export default function App() {
  const token = use(tokenPromise);
  return (
    <ViskoOrbisStableProvider jwtToken={token}>
      <Controller />
    </ViskoOrbisStableProvider>
  );
}

Events

Client-to-model commands. The typed surface is ViskoOrbisStableModel (one method per event) in plain JS, and useViskoOrbisStable() 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; the model keeps its place, so resuming continues the same shot rather than starting a new one. Emits generation_paused and state 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 { ViskoOrbisStableModel } from "@reactor-models/visko-orbis-stable";

const viskoOrbisStable = new ViskoOrbisStableModel();
await viskoOrbisStable.connect(jwt);

const reply = await viskoOrbisStable.pause();

if (reply) {
  console.log("generation_paused", reply.chunk_index);
}

React

"use client";
import { useViskoOrbisStable } from "@reactor-models/visko-orbis-stable";

function Example() {
  const { pause } = useViskoOrbisStable();

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

reset

Abort the current run, clear the active prompt and starting image, and return to the waiting state. Valid at any time. After reset, call set_prompt (and optionally set_image) again before start. Emits generation_reset and state.

Returns: generation_reset{ type: "generation_reset", reason: "" } (or undefined when the send fails).

No parameters.

JavaScript

import { ViskoOrbisStableModel } from "@reactor-models/visko-orbis-stable";

const viskoOrbisStable = new ViskoOrbisStableModel();
await viskoOrbisStable.connect(jwt);

const reply = await viskoOrbisStable.reset();

if (reply) {
  console.log("generation_reset", reply.reason);
}

React

"use client";
import { useViskoOrbisStable } from "@reactor-models/visko-orbis-stable";

function Example() {
  const { reset } = useViskoOrbisStable();

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

start

Begin generating video on main_video. Requires a prompt (via set_prompt); a starting image is optional. Emits generation_started and state 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 { ViskoOrbisStableModel } from "@reactor-models/visko-orbis-stable";

const viskoOrbisStable = new ViskoOrbisStableModel();
await viskoOrbisStable.connect(jwt);

await viskoOrbisStable.start();

React

"use client";
import { useViskoOrbisStable } from "@reactor-models/visko-orbis-stable";

function Example() {
  const { start } = useViskoOrbisStable();

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

resume

Resume generation from a previous pause. Requires the session to be paused. Emits generation_resumed and state on success, or command_error if not paused.

Returns: generation_resumed{ type: "generation_resumed", chunk_index: 0 } (or undefined when the send fails).

No parameters.

JavaScript

import { ViskoOrbisStableModel } from "@reactor-models/visko-orbis-stable";

const viskoOrbisStable = new ViskoOrbisStableModel();
await viskoOrbisStable.connect(jwt);

const reply = await viskoOrbisStable.resume();

if (reply) {
  console.log("generation_resumed", reply.chunk_index);
}

React

"use client";
import { useViskoOrbisStable } from "@reactor-models/visko-orbis-stable";

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

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

setSeed

Seed for the noise the first chunk is sampled from. Must be a non-negative integer; the model never draws its own seed, so the same seed with the same prompts reproduces the same video. Read once when start fires — 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 noise the first chunk is sampled from. Must be a non-negative integer; the model never draws its own seed, so the same seed with the same prompts reproduces the same video. Read once when start fires — later changes take effect only after reset followed by a new start. (min 0, default 42) |

JavaScript

import { ViskoOrbisStableModel } from "@reactor-models/visko-orbis-stable";

const viskoOrbisStable = new ViskoOrbisStableModel();
await viskoOrbisStable.connect(jwt);

await viskoOrbisStable.setSeed({ seed: 42 });

React

"use client";
import { useViskoOrbisStable } from "@reactor-models/visko-orbis-stable";

function Example() {
  const { setSeed } = useViskoOrbisStable();

  return <button onClick={() => setSeed({ seed: 42 })}>setSeed</button>;
}

setImage

Provide a starting frame the video grows out of (image-to-video). Optional — with no image the model generates from the prompt alone. Call before start; the image anchors the first chunk and every later chunk inherits it through the model's own history, so a change during generation has no effect until reset and a new start. Emits image_accepted, conditions_ready, and state on success, or command_error if the file is missing, is not an image, or cannot be decoded.

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) |

JavaScript

import { ViskoOrbisStableModel } from "@reactor-models/visko-orbis-stable";

const viskoOrbisStable = new ViskoOrbisStableModel();
await viskoOrbisStable.connect(jwt);

const fileRef = await viskoOrbisStable.uploadFile(blob);
const reply = await viskoOrbisStable.setImage({ image: fileRef });

if (reply) {
  console.log("image_accepted", reply.width, reply.height);
}

React

"use client";
import { useViskoOrbisStable } from "@reactor-models/visko-orbis-stable";

function Example() {
  const { setImage, uploadFile } = useViskoOrbisStable();

  async function handlePick(file: File) {
    const ref = await uploadFile(file);
    await setImage({ image: ref });
  }

  return <input type="file" onChange={(e) => handlePick(e.target.files![0])} />;
}

setPrompt

Set the scene prompt that guides generation. Valid at any time — call before start to arm generation, or hot-swap during generation to steer the next chunk. The picture morphs into the new prompt at the next chunk boundary rather than cutting. Characters and setting persist across prompts until reset. Emits prompt_accepted, conditions_ready, and state on success.

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 the previously active prompt. Applied on the next chunk when generating; otherwise takes effect when start fires. (default "") |

JavaScript

import { ViskoOrbisStableModel } from "@reactor-models/visko-orbis-stable";

const viskoOrbisStable = new ViskoOrbisStableModel();
await viskoOrbisStable.connect(jwt);

const reply = await viskoOrbisStable.setPrompt({ prompt: "A sunset over the ocean" });

if (reply) {
  console.log("prompt_accepted", reply.prompt);
}

React

"use client";
import { useViskoOrbisStable } from "@reactor-models/visko-orbis-stable";

function Example() {
  const { setPrompt } = useViskoOrbisStable();

  return <button onClick={() => setPrompt({ prompt: "A sunset over the ocean" })}>setPrompt</button>;
}

setResolution

Choose the delivery resolution for main_video from this deployment's offered list (available_resolutions in the state snapshot — e.g. 1080p, 2k, 4k). Session-scoped: read when start fires, so the track's geometry never jumps mid-shot — call it before start, or any time to arm the next run. Unlike the prompt it survives reset. Emits resolution_accepted and state on success, or command_error naming the offered list when the value is not on it.

Returns: resolution_accepted{ type: "resolution_accepted", width: 0, height: 0, resolution: "" } (or undefined when the send fails).

| Parameter | Type | Description | |---|---|---| | resolution | string | One of the deployment's offered resolutions, exactly as listed in the state snapshot's available_resolutions — named delivery tiers (1080p = 1920x1080, 2k = 2560x1440, 4k = 3840x2160). (default "") |

JavaScript

import { ViskoOrbisStableModel } from "@reactor-models/visko-orbis-stable";

const viskoOrbisStable = new ViskoOrbisStableModel();
await viskoOrbisStable.connect(jwt);

const reply = await viskoOrbisStable.setResolution({ resolution: "" });

if (reply) {
  console.log(
    "resolution_accepted",
    reply.width,
    reply.height,
    reply.resolution,
  );
}

React

"use client";
import { useViskoOrbisStable } from "@reactor-models/visko-orbis-stable";

function Example() {
  const { setResolution } = useViskoOrbisStable();

  return <button onClick={() => setResolution({ resolution: "" })}>setResolution</button>;
}

setAudioPrompt

Set the sound description the audio is generated from. Valid at any time — call before start, or during generation to change the sound from the next chunk on. Pass an empty string to clear it, which switches the audio model to generating sound from the picture alone. Emits audio_prompt_accepted and state on success; rejected with command_error on a deployment that has no audio track.

Returns: audio_prompt_accepted{ type: "audio_prompt_accepted", audio_prompt: null } (or undefined when the send fails).

| Parameter | Type | Description | |---|---|---| | prompt | string | What the scene should SOUND like — instruments, voices, materials, ambience. Not a description of what is on screen: sending a scene description here makes the audio worse than leaving it empty. Keep it to about one sentence; roughly the first 128 tokens are used and the rest is dropped without warning. Example: "Acoustic guitar strums a rhythmic melody, with soft finger noise on the strings and quiet room ambience." Empty clears it, and the audio is then generated from the picture alone. (default "") |

JavaScript

import { ViskoOrbisStableModel } from "@reactor-models/visko-orbis-stable";

const viskoOrbisStable = new ViskoOrbisStableModel();
await viskoOrbisStable.connect(jwt);

const reply = await viskoOrbisStable.setAudioPrompt({ prompt: "A sunset over the ocean" });

if (reply) {
  console.log("audio_prompt_accepted", reply.audio_prompt);
}

React

"use client";
import { useViskoOrbisStable } from "@reactor-models/visko-orbis-stable";

function Example() {
  const { setAudioPrompt } = useViskoOrbisStable();

  return <button onClick={() => setAudioPrompt({ prompt: "A sunset over the ocean" })}>setAudioPrompt</button>;
}

setAudioEnabled

Enable or disable sound for runs started from now on. When false the audio model is skipped entirely — main_audio carries silence and each chunk is cheaper to produce. Session-scoped like set_resolution: read when start fires, and it survives reset. Emits audio_enabled_accepted and state on success; rejected with command_error on a deployment that has no audio track. A client that never wants audio can also simply omit main_audio from its track mapping when connecting — that needs no command, but still spends the compute; this command is how the compute is saved.

Returns: audio_enabled_accepted{ type: "audio_enabled_accepted", audio_enabled: true } (or undefined when the send fails).

| Parameter | Type | Description | |---|---|---| | audio_enabled | boolean | True to generate sound on main_audio (the default), false to skip the audio model and deliver silence from the next start on. (default true) |

JavaScript

import { ViskoOrbisStableModel } from "@reactor-models/visko-orbis-stable";

const viskoOrbisStable = new ViskoOrbisStableModel();
await viskoOrbisStable.connect(jwt);

const reply = await viskoOrbisStable.setAudioEnabled({ audio_enabled: true });

if (reply) {
  console.log("audio_enabled_accepted", reply.audio_enabled);
}

React

"use client";
import { useViskoOrbisStable } from "@reactor-models/visko-orbis-stable";

function Example() {
  const { setAudioEnabled } = useViskoOrbisStable();

  return <button onClick={() => setAudioEnabled({ audio_enabled: true })}>setAudioEnabled</button>;
}

Messages

Model-to-client messages. Register a typed listener with on… on ViskoOrbisStableModel, or a useViskoOrbisStable… hook in React, to receive only the messages you care about.

state

Snapshot of the session's observable state.

Emitted on connect, after every command that mutates session state (set_prompt, set_audio_prompt, set_image, set_seed, set_resolution, set_audio_enabled, start, pause, resume, reset), and after each chunk_complete. A client can treat this as the single source of truth for driving UI instead of tracking every individual message.

Listener: onState · React hook: useViskoOrbisStableState

| Field | Type | Description | |---|---|---| | seed | number | Current value of the seed input field. The seed actually driving a running generation was captured when start fired — later changes take effect only after reset and a new start. | | 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 tell those apart. | | started | boolean | True once start has been accepted. Stays true while paused; cleared by reset. | | has_image | boolean | True once a reference image has been set for the session. | | has_prompt | boolean | True once a prompt has been set for the session. | | resolution | string | The delivery resolution the next start will use — the client's set_resolution choice, or the deployment's default if it has not spoken. Like seed, the value driving a RUNNING generation was captured when start fired. | | audio_prompt | string \| null | The sound description currently conditioning the audio, or null. Null means one of two things and the distinction does not matter to a client: either no set_audio_prompt has been sent, so this deployment's configured default is in force, or the caption was cleared and the audio is generated from the picture alone. Always null on a deployment with no main_audio track. | | audio_enabled | boolean | Whether the next start will generate sound — the client's set_audio_enabled choice, or true if it has not spoken. Like seed, the value driving a RUNNING generation was captured when start fired. Always false on a deployment with no main_audio track. | | current_chunk | number | Zero-based index of the last completed chunk. 0 before the first chunk has completed, and back to 0 on reset. | | available_resolutions | string[] | The delivery resolutions this deployment offers, in its configured order — the valid inputs to set_resolution. Fixed at startup; the named tiers are upscaler-delivered (1080p = 1920x1080, 2k = 2560x1440, 4k = 3840x2160). |

JavaScript

import { ViskoOrbisStableModel } from "@reactor-models/visko-orbis-stable";

const viskoOrbisStable = new ViskoOrbisStableModel();
viskoOrbisStable.onState((msg) => {
  console.log(
    "state",
    msg.seed,
    msg.paused,
    msg.running,
    msg.started,
    msg.has_image,
    msg.has_prompt,
    msg.resolution,
    msg.audio_prompt,
    msg.audio_enabled,
    msg.current_chunk,
    msg.available_resolutions,
  );
});
await viskoOrbisStable.connect(jwt);

React

import { useViskoOrbisStableState } from "@reactor-models/visko-orbis-stable";

// Inside a React component wrapped by <ViskoOrbisStableProvider>:
useViskoOrbisStableState((msg) => {
  console.log(
    "state",
    msg.seed,
    msg.paused,
    msg.running,
    msg.started,
    msg.has_image,
    msg.has_prompt,
    msg.resolution,
    msg.audio_prompt,
    msg.audio_enabled,
    msg.current_chunk,
    msg.available_resolutions,
  );
});

command_error

Emitted when a command is rejected because its preconditions are not met, or its arguments could not be processed.

Listener: onCommandError · React hook: useViskoOrbisStableCommandError

| 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 { ViskoOrbisStableModel } from "@reactor-models/visko-orbis-stable";

const viskoOrbisStable = new ViskoOrbisStableModel();
viskoOrbisStable.onCommandError((msg) => {
  console.log("command_error", msg.reason, msg.command);
});
await viskoOrbisStable.connect(jwt);

React

import { useViskoOrbisStableCommandError } from "@reactor-models/visko-orbis-stable";

// Inside a React component wrapped by <ViskoOrbisStableProvider>:
useViskoOrbisStableCommandError((msg) => {
  console.log("command_error", msg.reason, msg.command);
});

chunk_complete

Emitted once per completed chunk of main_video.

Listener: onChunkComplete · React hook: useViskoOrbisStableChunkComplete

| Field | Type | Description | |---|---|---| | chunk_index | number | Zero-based index of the chunk that just completed. | | audio_samples | number \| null | Number of audio samples emitted on main_audio for this chunk, at 48 kHz mono, or null when this deployment has no audio track. Always equals frames_emitted / fps * 48000 rounded, so a client can check A/V alignment without decoding anything. | | frames_emitted | number | Number of pixel frames emitted by this chunk. |

JavaScript

import { ViskoOrbisStableModel } from "@reactor-models/visko-orbis-stable";

const viskoOrbisStable = new ViskoOrbisStableModel();
viskoOrbisStable.onChunkComplete((msg) => {
  console.log(
    "chunk_complete",
    msg.chunk_index,
    msg.audio_samples,
    msg.frames_emitted,
  );
});
await viskoOrbisStable.connect(jwt);

React

import { useViskoOrbisStableChunkComplete } from "@reactor-models/visko-orbis-stable";

// Inside a React component wrapped by <ViskoOrbisStableProvider>:
useViskoOrbisStableChunkComplete((msg) => {
  console.log(
    "chunk_complete",
    msg.chunk_index,
    msg.audio_samples,
    msg.frames_emitted,
  );
});

image_accepted

Emitted after set_image successfully decodes the uploaded file.

Listener: onImageAccepted · React hook: useViskoOrbisStableImageAccepted

| Field | Type | Description | |---|---|---| | width | number | Width in pixels of the decoded reference image. | | height | number | Height in pixels of the decoded reference image. |

JavaScript

import { ViskoOrbisStableModel } from "@reactor-models/visko-orbis-stable";

const viskoOrbisStable = new ViskoOrbisStableModel();
viskoOrbisStable.onImageAccepted((msg) => {
  console.log("image_accepted", msg.width, msg.height);
});
await viskoOrbisStable.connect(jwt);

React

import { useViskoOrbisStableImageAccepted } from "@reactor-models/visko-orbis-stable";

// Inside a React component wrapped by <ViskoOrbisStableProvider>:
useViskoOrbisStableImageAccepted((msg) => {
  console.log("image_accepted", msg.width, msg.height);
});

prompt_accepted

Emitted after set_prompt is accepted.

Listener: onPromptAccepted · React hook: useViskoOrbisStablePromptAccepted

| Field | Type | Description | |---|---|---| | prompt | string | The prompt text that was accepted, exactly as the client sent it. |

JavaScript

import { ViskoOrbisStableModel } from "@reactor-models/visko-orbis-stable";

const viskoOrbisStable = new ViskoOrbisStableModel();
viskoOrbisStable.onPromptAccepted((msg) => {
  console.log("prompt_accepted", msg.prompt);
});
await viskoOrbisStable.connect(jwt);

React

import { useViskoOrbisStablePromptAccepted } from "@reactor-models/visko-orbis-stable";

// Inside a React component wrapped by <ViskoOrbisStableProvider>:
useViskoOrbisStablePromptAccepted((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: useViskoOrbisStableConditionsReady

| Field | Type | Description | |---|---|---| | has_image | boolean | True once a reference image has been set for the session. Optional — with no image the model generates from the prompt alone (text-to-video). | | has_prompt | boolean | True once a prompt has been set for the session. |

JavaScript

import { ViskoOrbisStableModel } from "@reactor-models/visko-orbis-stable";

const viskoOrbisStable = new ViskoOrbisStableModel();
viskoOrbisStable.onConditionsReady((msg) => {
  console.log("conditions_ready", msg.has_image, msg.has_prompt);
});
await viskoOrbisStable.connect(jwt);

React

import { useViskoOrbisStableConditionsReady } from "@reactor-models/visko-orbis-stable";

// Inside a React component wrapped by <ViskoOrbisStableProvider>:
useViskoOrbisStableConditionsReady((msg) => {
  console.log("conditions_ready", msg.has_image, msg.has_prompt);
});

generation_reset

Emitted after reset clears session state and returns to the waiting state.

Listener: onGenerationReset · React hook: useViskoOrbisStableGenerationReset

| Field | Type | Description | |---|---|---| | reason | string | Short human-readable reason the reset was issued. |

JavaScript

import { ViskoOrbisStableModel } from "@reactor-models/visko-orbis-stable";

const viskoOrbisStable = new ViskoOrbisStableModel();
viskoOrbisStable.onGenerationReset((msg) => {
  console.log("generation_reset", msg.reason);
});
await viskoOrbisStable.connect(jwt);

React

import { useViskoOrbisStableGenerationReset } from "@reactor-models/visko-orbis-stable";

// Inside a React component wrapped by <ViskoOrbisStableProvider>:
useViskoOrbisStableGenerationReset((msg) => {
  console.log("generation_reset", msg.reason);
});

generation_paused

Emitted in response to pause, once the current chunk finishes.

Listener: onGenerationPaused · React hook: useViskoOrbisStableGenerationPaused

| Field | Type | Description | |---|---|---| | chunk_index | number | Index of the last completed chunk before pausing. |

JavaScript

import { ViskoOrbisStableModel } from "@reactor-models/visko-orbis-stable";

const viskoOrbisStable = new ViskoOrbisStableModel();
viskoOrbisStable.onGenerationPaused((msg) => {
  console.log("generation_paused", msg.chunk_index);
});
await viskoOrbisStable.connect(jwt);

React

import { useViskoOrbisStableGenerationPaused } from "@reactor-models/visko-orbis-stable";

// Inside a React component wrapped by <ViskoOrbisStableProvider>:
useViskoOrbisStableGenerationPaused((msg) => {
  console.log("generation_paused", msg.chunk_index);
});

generation_resumed

Emitted in response to resume when leaving the paused state.

Listener: onGenerationResumed · React hook: useViskoOrbisStableGenerationResumed

| Field | Type | Description | |---|---|---| | chunk_index | number | Index of the last completed chunk before resuming. |

JavaScript

import { ViskoOrbisStableModel } from "@reactor-models/visko-orbis-stable";

const viskoOrbisStable = new ViskoOrbisStableModel();
viskoOrbisStable.onGenerationResumed((msg) => {
  console.log("generation_resumed", msg.chunk_index);
});
await viskoOrbisStable.connect(jwt);

React

import { useViskoOrbisStableGenerationResumed } from "@reactor-models/visko-orbis-stable";

// Inside a React component wrapped by <ViskoOrbisStableProvider>:
useViskoOrbisStableGenerationResumed((msg) => {
  console.log("generation_resumed", msg.chunk_index);
});

generation_started

Emitted once when start succeeds and frames begin streaming.

Listener: onGenerationStarted · React hook: useViskoOrbisStableGenerationStarted

| Field | Type | Description | |---|---|---| | fps | number | Frame rate the video is generated at. | | width | number | Width in pixels of every frame this run emits on main_video. | | height | number | Height in pixels of every frame this run emits on main_video. | | max_chunks | number | Maximum number of chunks this run will produce before generation_complete fires. 0 means the run is unlimited: it continues until pause/reset or the session ends, and generation_complete is never emitted. | | resolution | string | The delivery resolution this run generates at — a named tier such as 1080p, 2k, 4k. Fixed for the run; set_resolution applies from the next start. | | audio_enabled | boolean | Whether this run generates sound. False either because the session set set_audio_enabled(false)main_audio then carries silence — or because this deployment has no main_audio track at all; read the schema to tell the two apart. Fixed for the run, like resolution. | | frames_per_chunk | number | Number of pixel frames each chunk emits on main_video. | | image_conditioned | boolean | True when a reference image anchors this run (image-to-video); false for text-to-video. |

JavaScript

import { ViskoOrbisStableModel } from "@reactor-models/visko-orbis-stable";

const viskoOrbisStable = new ViskoOrbisStableModel();
viskoOrbisStable.onGenerationStarted((msg) => {
  console.log(
    "generation_started",
    msg.fps,
    msg.width,
    msg.height,
    msg.max_chunks,
    msg.resolution,
    msg.audio_enabled,
    msg.frames_per_chunk,
    msg.image_conditioned,
  );
});
await viskoOrbisStable.connect(jwt);

React

import { useViskoOrbisStableGenerationStarted } from "@reactor-models/visko-orbis-stable";

// Inside a React component wrapped by <ViskoOrbisStableProvider>:
useViskoOrbisStableGenerationStarted((msg) => {
  console.log(
    "generation_started",
    msg.fps,
    msg.width,
    msg.height,
    msg.max_chunks,
    msg.resolution,
    msg.audio_enabled,
    msg.frames_per_chunk,
    msg.image_conditioned,
  );
});

generation_complete

Emitted when the run reaches max_chunks.

The session returns to the waiting state rather than rolling straight into another run — a new run begins at chunk 0, which is a hard visual cut, and issuing one unasked would be a surprise. Call start again to continue, or reset to clear the conditions first. Never emitted on a deployment with max_chunks: 0 (unlimited runs).

Listener: onGenerationComplete · React hook: useViskoOrbisStableGenerationComplete

| Field | Type | Description | |---|---|---| | total_chunks | number | Total number of chunks produced by the run. |

JavaScript

import { ViskoOrbisStableModel } from "@reactor-models/visko-orbis-stable";

const viskoOrbisStable = new ViskoOrbisStableModel();
viskoOrbisStable.onGenerationComplete((msg) => {
  console.log("generation_complete", msg.total_chunks);
});
await viskoOrbisStable.connect(jwt);

React

import { useViskoOrbisStableGenerationComplete } from "@reactor-models/visko-orbis-stable";

// Inside a React component wrapped by <ViskoOrbisStableProvider>:
useViskoOrbisStableGenerationComplete((msg) => {
  console.log("generation_complete", msg.total_chunks);
});

resolution_accepted

Emitted after set_resolution is accepted.

Listener: onResolutionAccepted · React hook: useViskoOrbisStableResolutionAccepted

| Field | Type | Description | |---|---|---| | width | number | Width in pixels main_video will deliver at once a run starts with this tier — so a client can size its canvas without a name-to-size lookup table. | | height | number | Height in pixels main_video will deliver at once a run starts with this tier. | | resolution | string | The delivery resolution that was accepted. Applies from the next start — a running generation keeps the resolution it started with. |

JavaScript

import { ViskoOrbisStableModel } from "@reactor-models/visko-orbis-stable";

const viskoOrbisStable = new ViskoOrbisStableModel();
viskoOrbisStable.onResolutionAccepted((msg) => {
  console.log(
    "resolution_accepted",
    msg.width,
    msg.height,
    msg.resolution,
  );
});
await viskoOrbisStable.connect(jwt);

React

import { useViskoOrbisStableResolutionAccepted } from "@reactor-models/visko-orbis-stable";

// Inside a React component wrapped by <ViskoOrbisStableProvider>:
useViskoOrbisStableResolutionAccepted((msg) => {
  console.log(
    "resolution_accepted",
    msg.width,
    msg.height,
    msg.resolution,
  );
});

audio_prompt_accepted

Emitted after set_audio_prompt is accepted.

Listener: onAudioPromptAccepted · React hook: useViskoOrbisStableAudioPromptAccepted

| Field | Type | Description | |---|---|---| | audio_prompt | string \| null | The sound description that was accepted, or null if it was cleared — which puts the audio model in its video-only mode, generating sound from the picture alone. |

JavaScript

import { ViskoOrbisStableModel } from "@reactor-models/visko-orbis-stable";

const viskoOrbisStable = new ViskoOrbisStableModel();
viskoOrbisStable.onAudioPromptAccepted((msg) => {
  console.log("audio_prompt_accepted", msg.audio_prompt);
});
await viskoOrbisStable.connect(jwt);

React

import { useViskoOrbisStableAudioPromptAccepted } from "@reactor-models/visko-orbis-stable";

// Inside a React component wrapped by <ViskoOrbisStableProvider>:
useViskoOrbisStableAudioPromptAccepted((msg) => {
  console.log("audio_prompt_accepted", msg.audio_prompt);
});

audio_enabled_accepted

Emitted after set_audio_enabled is accepted.

Listener: onAudioEnabledAccepted · React hook: useViskoOrbisStableAudioEnabledAccepted

| Field | Type | Description | |---|---|---| | audio_enabled | boolean | The value that was accepted. False means runs started from now on skip the audio model and main_audio carries silence; applies from the next start — a running generation keeps the setting it started with. |

JavaScript

import { ViskoOrbisStableModel } from "@reactor-models/visko-orbis-stable";

const viskoOrbisStable = new ViskoOrbisStableModel();
viskoOrbisStable.onAudioEnabledAccepted((msg) => {
  console.log("audio_enabled_accepted", msg.audio_enabled);
});
await viskoOrbisStable.connect(jwt);

React

import { useViskoOrbisStableAudioEnabledAccepted } from "@reactor-models/visko-orbis-stable";

// Inside a React component wrapped by <ViskoOrbisStableProvider>:
useViskoOrbisStableAudioEnabledAccepted((msg) => {
  console.log("audio_enabled_accepted", msg.audio_enabled);
});

Tracks

Named media channels between your app and the ViskoOrbisStable model. Use the typed helpers below — ViskoOrbisStableModel.publish<Track> / on<Track> in plain JS, and useViskoOrbisStableTrack or the per-track <ViskoOrbisStable<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 { ViskoOrbisStableModel } from "@reactor-models/visko-orbis-stable";

const viskoOrbisStable = new ViskoOrbisStableModel();
viskoOrbisStable.onMainVideo((track, stream) => {
  // attach to a <video> element, pipe to a canvas, etc.
  videoEl.srcObject = stream;
});
await viskoOrbisStable.connect(jwt);

React

"use client";
import { ViskoOrbisStableMainVideoView } from "@reactor-models/visko-orbis-stable";

// Inside a component wrapped by <ViskoOrbisStableProvider>:
export function Example() {
  return <ViskoOrbisStableMainVideoView className="w-full aspect-video" />;
}

main_audio

A audio channel you subscribe to — the model publishes this for your app to render.

JavaScript

import { ViskoOrbisStableModel } from "@reactor-models/visko-orbis-stable";

const viskoOrbisStable = new ViskoOrbisStableModel();
viskoOrbisStable.onMainAudio((track, stream) => {
  // attach to a <audio> element, pipe to a canvas, etc.
  videoEl.srcObject = stream;
});
await viskoOrbisStable.connect(jwt);

React

"use client";
import { useViskoOrbisStableTrack } from "@reactor-models/visko-orbis-stable";

// Inside a component wrapped by <ViskoOrbisStableProvider>:
export function Example() {
  const track = useViskoOrbisStableTrack("main_audio");
  // attach `track` to an <audio> element via a ref + srcObject.
  return null;
}