@reactor-models/lingbot-world-2
v1.0.1
Published
Strongly-typed SDK for the LingbotWorld2 model on Reactor
Downloads
6,218
Maintainers
Readme
@reactor-models/lingbot-world-2
Typed JavaScript + React SDK for the LingbotWorld2 model on Reactor. Version v1.0.1.
Get started
Scaffold a starter app for LingbotWorld2 with create-reactor-app:
npx create-reactor-app my-app --model=lingbot-world-2pnpm dlx create-reactor-app my-app --model=lingbot-world-2Install
npm install @reactor-models/lingbot-world-2pnpm add @reactor-models/lingbot-world-2The package exports a plain-JavaScript client and a set of React bindings. Import whichever you need from @reactor-models/lingbot-world-2:
import { LingbotWorld2Model } from "@reactor-models/lingbot-world-2";import { LingbotWorld2Provider, useLingbotWorld2 } from "@reactor-models/lingbot-world-2";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 { LingbotWorld2Provider } from "@reactor-models/lingbot-world-2";
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 (
<LingbotWorld2Provider jwtToken={token} connectOptions={{ autoConnect: true }}>
<ReactorView className="w-full aspect-video" />
</LingbotWorld2Provider>
);
}Connect
JavaScript
import { LingbotWorld2Model } from "@reactor-models/lingbot-world-2";
const lingbotWorld2 = new LingbotWorld2Model();
await lingbotWorld2.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 { LingbotWorld2Provider, useLingbotWorld2 } from "@reactor-models/lingbot-world-2";
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 } = useLingbotWorld2();
return <span>Status: {status}</span>;
}
export default function App() {
const token = use(tokenPromise);
return (
<LingbotWorld2Provider jwtToken={token}>
<Controller />
</LingbotWorld2Provider>
);
}Events
Client-to-model commands. The typed surface is LingbotWorld2Model (one method per event) in plain JS, and useLingbotWorld2() 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 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 { LingbotWorld2Model } from "@reactor-models/lingbot-world-2";
const lingbotWorld2 = new LingbotWorld2Model();
await lingbotWorld2.connect(jwt);
const reply = await lingbotWorld2.pause();
if (reply) {
console.log("generation_paused", reply.chunk_index);
}React
"use client";
import { useLingbotWorld2 } from "@reactor-models/lingbot-world-2";
function Example() {
const { pause } = useLingbotWorld2();
return <button onClick={() => pause()}>pause</button>;
}reset
Abort the current run, clear the active prompt and reference image, and return to the waiting state. Valid at any time. After reset, call set_prompt and set_image again before start to begin a new session. Emits generation_reset and state.
Returns: generation_reset — { type: "generation_reset", reason: "" } (or undefined when the send fails).
No parameters.
JavaScript
import { LingbotWorld2Model } from "@reactor-models/lingbot-world-2";
const lingbotWorld2 = new LingbotWorld2Model();
await lingbotWorld2.connect(jwt);
const reply = await lingbotWorld2.reset();
if (reply) {
console.log("generation_reset", reply.reason);
}React
"use client";
import { useLingbotWorld2 } from "@reactor-models/lingbot-world-2";
function Example() {
const { reset } = useLingbotWorld2();
return <button onClick={() => reset()}>reset</button>;
}start
Begin generating video on main_video. Requires both a prompt (via set_prompt) and a reference image (via set_image). Emits generation_started and state on success, or command_error if a precondition is missing. Has no effect while already generating.
Returns: nothing — the awaited call resolves undefined once the model's handler has run.
No parameters.
JavaScript
import { LingbotWorld2Model } from "@reactor-models/lingbot-world-2";
const lingbotWorld2 = new LingbotWorld2Model();
await lingbotWorld2.connect(jwt);
await lingbotWorld2.start();React
"use client";
import { useLingbotWorld2 } from "@reactor-models/lingbot-world-2";
function Example() {
const { start } = useLingbotWorld2();
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 { LingbotWorld2Model } from "@reactor-models/lingbot-world-2";
const lingbotWorld2 = new LingbotWorld2Model();
await lingbotWorld2.connect(jwt);
const reply = await lingbotWorld2.resume();
if (reply) {
console.log("generation_resumed", reply.chunk_index);
}React
"use client";
import { useLingbotWorld2 } from "@reactor-models/lingbot-world-2";
function Example() {
const { resume } = useLingbotWorld2();
return <button onClick={() => resume()}>resume</button>;
}setSeed
Seed for the random generator used to sample the initial noise. Must be a non-negative integer; the model never draws its own random seed — pick one explicitly (or keep the default) for reproducible runs. 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 random generator used to sample the initial noise. Must be a non-negative integer; the model never draws its own random seed — pick one explicitly (or keep the default) for reproducible runs. Read once when start fires; later changes take effect only after reset followed by a new start. (min 0, default 42) |
JavaScript
import { LingbotWorld2Model } from "@reactor-models/lingbot-world-2";
const lingbotWorld2 = new LingbotWorld2Model();
await lingbotWorld2.connect(jwt);
await lingbotWorld2.setSeed({ seed: 42 });React
"use client";
import { useLingbotWorld2 } from "@reactor-models/lingbot-world-2";
function Example() {
const { setSeed } = useLingbotWorld2();
return <button onClick={() => setSeed({ seed: 42 })}>setSeed</button>;
}setImage
Provide a reference image that anchors generation (image-to-video). Call before start; the image is required for generation to begin. Changes during generation have no effect until reset is issued and start is called again. Emits image_accepted, conditions_ready, and state on success, or command_error if the file is missing, 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 { LingbotWorld2Model } from "@reactor-models/lingbot-world-2";
const lingbotWorld2 = new LingbotWorld2Model();
await lingbotWorld2.connect(jwt);
const fileRef = await lingbotWorld2.uploadFile(blob);
const reply = await lingbotWorld2.setImage({ image: fileRef });
if (reply) {
console.log("image_accepted", reply.width, reply.height);
}React
"use client";
import { useLingbotWorld2 } from "@reactor-models/lingbot-world-2";
function Example() {
const { setImage, uploadFile } = useLingbotWorld2();
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. Valid at any time — call before start to arm generation, or hot-swap during generation to steer the next chunk. 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 { LingbotWorld2Model } from "@reactor-models/lingbot-world-2";
const lingbotWorld2 = new LingbotWorld2Model();
await lingbotWorld2.connect(jwt);
const reply = await lingbotWorld2.setPrompt({ prompt: "A sunset over the ocean" });
if (reply) {
console.log("prompt_accepted", reply.prompt);
}React
"use client";
import { useLingbotWorld2 } from "@reactor-models/lingbot-world-2";
function Example() {
const { setPrompt } = useLingbotWorld2();
return <button onClick={() => setPrompt({ prompt: "A sunset over the ocean" })}>setPrompt</button>;
}setAttnWindow
How much recent context each chunk is generated from, trading temporal stability against responsiveness to camera motion. auto (default) chooses automatically from the camera's motion: a shorter window for near-still shots (steadier, more consistent) and a longer one while the camera moves (smoother motion). small forces the shorter, still-scene window; large forces the longer, in-motion window. Can be changed at any time; the new value applies to the next chunk.
Returns: nothing — the awaited call resolves undefined once the model's handler has run.
| Parameter | Type | Description |
|---|---|---|
| attn_window | "auto" \| "small" \| "large" | How much recent context each chunk is generated from, trading temporal stability against responsiveness to camera motion. auto (default) chooses automatically from the camera's motion: a shorter window for near-still shots (steadier, more consistent) and a longer one while the camera moves (smoother motion). small forces the shorter, still-scene window; large forces the longer, in-motion window. Can be changed at any time; the new value applies to the next chunk. (default "auto") |
JavaScript
import { LingbotWorld2Model } from "@reactor-models/lingbot-world-2";
const lingbotWorld2 = new LingbotWorld2Model();
await lingbotWorld2.connect(jwt);
await lingbotWorld2.setAttnWindow({ attn_window: "auto" });React
"use client";
import { useLingbotWorld2 } from "@reactor-models/lingbot-world-2";
function Example() {
const { setAttnWindow } = useLingbotWorld2();
return <button onClick={() => setAttnWindow({ attn_window: "auto" })}>setAttnWindow</button>;
}setCameraPose
Explicit camera path, as a lower-level alternative to the discrete move_* and look_* controls. A flat list whose length is a multiple of 6, giving [rx, ry, rz, tx, ty, tz] per step: a rotation (radians, relative to the camera's current orientation) followed by a translation (relative to the camera's current position). Provide 6 values to apply a single motion across the whole next chunk, or one 6-tuple per frame of the chunk for per-frame control; any other length is resampled to fit the chunk. While set, the rotation replaces look_horizontal / look_vertical and the translation adds to move_longitudinal / move_lateral. Values are sanitized (non-finite numbers become 0, rotations clamped to ±pi, translation to ±100), so any payload is safe to send. Pass an empty list (or omit) to return control to the move_* / look_* inputs. Applies from the next chunk.
Returns: nothing — the awaited call resolves undefined once the model's handler has run.
| Parameter | Type | Description |
|---|---|---|
| camera_pose | unknown[] | Explicit camera path, as a lower-level alternative to the discrete move_* and look_* controls. A flat list whose length is a multiple of 6, giving [rx, ry, rz, tx, ty, tz] per step: a rotation (radians, relative to the camera's current orientation) followed by a translation (relative to the camera's current position). Provide 6 values to apply a single motion across the whole next chunk, or one 6-tuple per frame of the chunk for per-frame control; any other length is resampled to fit the chunk. While set, the rotation replaces look_horizontal / look_vertical and the translation adds to move_longitudinal / move_lateral. Values are sanitized (non-finite numbers become 0, rotations clamped to ±pi, translation to ±100), so any payload is safe to send. Pass an empty list (or omit) to return control to the move_* / look_* inputs. Applies from the next chunk. (maxLength 1536, default null) |
JavaScript
import { LingbotWorld2Model } from "@reactor-models/lingbot-world-2";
const lingbotWorld2 = new LingbotWorld2Model();
await lingbotWorld2.connect(jwt);
await lingbotWorld2.setCameraPose({ camera_pose: null });React
"use client";
import { useLingbotWorld2 } from "@reactor-models/lingbot-world-2";
function Example() {
const { setCameraPose } = useLingbotWorld2();
return <button onClick={() => setCameraPose({ camera_pose: null })}>setCameraPose</button>;
}setMoveLateral
Lateral (strafe left/right) camera translation. idle holds position; strafe_left / strafe_right translate sideways. Independent of move_longitudinal — both can be active together for diagonal movement. Can be changed at any time; the new value applies to the next chunk.
Returns: nothing — the awaited call resolves undefined once the model's handler has run.
| Parameter | Type | Description |
|---|---|---|
| move_lateral | "idle" \| "strafe_left" \| "strafe_right" | Lateral (strafe left/right) camera translation. idle holds position; strafe_left / strafe_right translate sideways. Independent of move_longitudinal — both can be active together for diagonal movement. Can be changed at any time; the new value applies to the next chunk. (default "idle") |
JavaScript
import { LingbotWorld2Model } from "@reactor-models/lingbot-world-2";
const lingbotWorld2 = new LingbotWorld2Model();
await lingbotWorld2.connect(jwt);
await lingbotWorld2.setMoveLateral({ move_lateral: "idle" });React
"use client";
import { useLingbotWorld2 } from "@reactor-models/lingbot-world-2";
function Example() {
const { setMoveLateral } = useLingbotWorld2();
return <button onClick={() => setMoveLateral({ move_lateral: "idle" })}>setMoveLateral</button>;
}setLookVertical
Vertical (pitch) camera rotation. idle holds pitch steady; up / down rotate the camera at the rate given by rotation_speed_deg. Can be changed at any time; the new value applies to the next chunk.
Returns: nothing — the awaited call resolves undefined once the model's handler has run.
| Parameter | Type | Description |
|---|---|---|
| look_vertical | "idle" \| "up" \| "down" | Vertical (pitch) camera rotation. idle holds pitch steady; up / down rotate the camera at the rate given by rotation_speed_deg. Can be changed at any time; the new value applies to the next chunk. (default "idle") |
JavaScript
import { LingbotWorld2Model } from "@reactor-models/lingbot-world-2";
const lingbotWorld2 = new LingbotWorld2Model();
await lingbotWorld2.connect(jwt);
await lingbotWorld2.setLookVertical({ look_vertical: "idle" });React
"use client";
import { useLingbotWorld2 } from "@reactor-models/lingbot-world-2";
function Example() {
const { setLookVertical } = useLingbotWorld2();
return <button onClick={() => setLookVertical({ look_vertical: "idle" })}>setLookVertical</button>;
}setKvCacheReset
Control how the model refreshes its accumulated scene context to keep image quality stable over long, continuous sessions. As a run goes on, the model's memory of past frames builds up and can cause quality to slowly drift; periodically clearing that memory back to the starting image keeps the stream consistent. auto (the default) clears it automatically at a regular interval and also lets you clear it on demand with trigger_kv_cache_reset; manual never clears automatically and responds only to trigger_kv_cache_reset; off never clears, which can let quality drift on very long sessions. Valid at any time; takes effect on the next chunk. Switching from off to auto after a long stretch clears context on the first chunk. Emits state.
Returns: nothing — the awaited call resolves undefined once the model's handler has run.
| Parameter | Type | Description |
|---|---|---|
| mode | "off" \| "auto" \| "manual" | auto = refresh automatically at a regular interval, and on demand via trigger_kv_cache_reset; manual = refresh only on demand via trigger_kv_cache_reset, never automatically; off = never refresh. The automatic interval is fixed for the session and cannot be changed at runtime. (default "auto") |
JavaScript
import { LingbotWorld2Model } from "@reactor-models/lingbot-world-2";
const lingbotWorld2 = new LingbotWorld2Model();
await lingbotWorld2.connect(jwt);
await lingbotWorld2.setKvCacheReset({ mode: "off" });React
"use client";
import { useLingbotWorld2 } from "@reactor-models/lingbot-world-2";
function Example() {
const { setKvCacheReset } = useLingbotWorld2();
return <button onClick={() => setKvCacheReset({ mode: "off" })}>setKvCacheReset</button>;
}setLookHorizontal
Horizontal (yaw) camera rotation. idle holds yaw steady; left / right rotate the camera at the rate given by rotation_speed_deg. Can be changed at any time; the new value applies to the next chunk.
Returns: nothing — the awaited call resolves undefined once the model's handler has run.
| Parameter | Type | Description |
|---|---|---|
| look_horizontal | "idle" \| "left" \| "right" | Horizontal (yaw) camera rotation. idle holds yaw steady; left / right rotate the camera at the rate given by rotation_speed_deg. Can be changed at any time; the new value applies to the next chunk. (default "idle") |
JavaScript
import { LingbotWorld2Model } from "@reactor-models/lingbot-world-2";
const lingbotWorld2 = new LingbotWorld2Model();
await lingbotWorld2.connect(jwt);
await lingbotWorld2.setLookHorizontal({ look_horizontal: "idle" });React
"use client";
import { useLingbotWorld2 } from "@reactor-models/lingbot-world-2";
function Example() {
const { setLookHorizontal } = useLingbotWorld2();
return <button onClick={() => setLookHorizontal({ look_horizontal: "idle" })}>setLookHorizontal</button>;
}setMoveLongitudinal
Longitudinal (forward/back) camera translation. idle holds position; forward / back translate along the look axis. Independent of move_lateral — both can be active together for diagonal movement. Can be changed at any time; the new value applies to the next chunk.
Returns: nothing — the awaited call resolves undefined once the model's handler has run.
| Parameter | Type | Description |
|---|---|---|
| move_longitudinal | "idle" \| "forward" \| "back" | Longitudinal (forward/back) camera translation. idle holds position; forward / back translate along the look axis. Independent of move_lateral — both can be active together for diagonal movement. Can be changed at any time; the new value applies to the next chunk. (default "idle") |
JavaScript
import { LingbotWorld2Model } from "@reactor-models/lingbot-world-2";
const lingbotWorld2 = new LingbotWorld2Model();
await lingbotWorld2.connect(jwt);
await lingbotWorld2.setMoveLongitudinal({ move_longitudinal: "idle" });React
"use client";
import { useLingbotWorld2 } from "@reactor-models/lingbot-world-2";
function Example() {
const { setMoveLongitudinal } = useLingbotWorld2();
return <button onClick={() => setMoveLongitudinal({ move_longitudinal: "idle" })}>setMoveLongitudinal</button>;
}setRotationSpeedDeg
Camera rotation speed in degrees per frame of the chunk, applied when look_horizontal or look_vertical is not idle — the same per-frame granularity as camera_pose. Range 0.0 – 30.0. Ignored when both look axes are idle. Can be changed at any time; the new value applies to the next chunk.
Returns: nothing — the awaited call resolves undefined once the model's handler has run.
| Parameter | Type | Description |
|---|---|---|
| rotation_speed_deg | number | Camera rotation speed in degrees per frame of the chunk, applied when look_horizontal or look_vertical is not idle — the same per-frame granularity as camera_pose. Range 0.0 – 30.0. Ignored when both look axes are idle. Can be changed at any time; the new value applies to the next chunk. (min 0, max 30, default 5) |
JavaScript
import { LingbotWorld2Model } from "@reactor-models/lingbot-world-2";
const lingbotWorld2 = new LingbotWorld2Model();
await lingbotWorld2.connect(jwt);
await lingbotWorld2.setRotationSpeedDeg({ rotation_speed_deg: 5 });React
"use client";
import { useLingbotWorld2 } from "@reactor-models/lingbot-world-2";
function Example() {
const { setRotationSpeedDeg } = useLingbotWorld2();
return <button onClick={() => setRotationSpeedDeg({ rotation_speed_deg: 5 })}>setRotationSpeedDeg</button>;
}triggerKvCacheReset
Immediately refresh the model's accumulated scene context on the next chunk, without waiting for the automatic interval — useful at a hard scene or prompt change to clear stale context right away. Works while the reset mode is auto or manual; rejected with command_error when the mode is off (see set_kv_cache_reset). Emits state on success.
Returns: nothing — the awaited call resolves undefined once the model's handler has run.
No parameters.
JavaScript
import { LingbotWorld2Model } from "@reactor-models/lingbot-world-2";
const lingbotWorld2 = new LingbotWorld2Model();
await lingbotWorld2.connect(jwt);
await lingbotWorld2.triggerKvCacheReset();React
"use client";
import { useLingbotWorld2 } from "@reactor-models/lingbot-world-2";
function Example() {
const { triggerKvCacheReset } = useLingbotWorld2();
return <button onClick={() => triggerKvCacheReset()}>triggerKvCacheReset</button>;
}Messages
Model-to-client messages. Register a typed listener with on… on LingbotWorld2Model, or a useLingbotWorld2… 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_image, start, pause, resume, reset, and
the auto-generated set_<field> setters), and after each
chunk_complete. Clients can treat this as the single source of
truth for driving UI, without having to track every individual
command and message themselves.
Listener: onState · React hook: useLingbotWorld2State
| Field | Type | Description |
|---|---|---|
| seed | number | Current value of the seed input field. The seed that was actually used by the running generation was captured when start fired — later changes to seed only take effect 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 disambiguate. |
| started | boolean | True once start has been accepted. Remains true while paused; reset to false by reset or after generation_complete when the session is not auto-restarting. |
| 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. |
| move_lateral | string | Current value of the move_lateral input field. |
| current_chunk | number | Zero-based index of the last completed chunk. 0 before the first chunk has completed, and resets to 0 on reset. |
| look_vertical | string | Current value of the look_vertical input field. |
| current_action | string | Composite action string derived from move_longitudinal, move_lateral, look_horizontal, and look_vertical — a +-joined combination of w/s/a/d and left/right/up/down, or still when idle. |
| current_prompt | string \| null | The prompt currently driving generation, or null if no prompt has been set for the session. |
| look_horizontal | string | Current value of the look_horizontal input field. |
| move_longitudinal | string | Current value of the move_longitudinal input field. |
| camera_pose_active | boolean | True when a non-empty camera_pose has been set. |
| rotation_speed_deg | number | Current value of the rotation_speed_deg input field (0.0 – 30.0). |
JavaScript
import { LingbotWorld2Model } from "@reactor-models/lingbot-world-2";
const lingbotWorld2 = new LingbotWorld2Model();
lingbotWorld2.onState((msg) => {
console.log(
"state",
msg.seed,
msg.paused,
msg.running,
msg.started,
msg.has_image,
msg.has_prompt,
msg.move_lateral,
msg.current_chunk,
msg.look_vertical,
msg.current_action,
msg.current_prompt,
msg.look_horizontal,
msg.move_longitudinal,
msg.camera_pose_active,
msg.rotation_speed_deg,
);
});
await lingbotWorld2.connect(jwt);React
import { useLingbotWorld2State } from "@reactor-models/lingbot-world-2";
// Inside a React component wrapped by <LingbotWorld2Provider>:
useLingbotWorld2State((msg) => {
console.log(
"state",
msg.seed,
msg.paused,
msg.running,
msg.started,
msg.has_image,
msg.has_prompt,
msg.move_lateral,
msg.current_chunk,
msg.look_vertical,
msg.current_action,
msg.current_prompt,
msg.look_horizontal,
msg.move_longitudinal,
msg.camera_pose_active,
msg.rotation_speed_deg,
);
});command_error
Emitted when a command is rejected because preconditions are not met or its arguments could not be processed.
Listener: onCommandError · React hook: useLingbotWorld2CommandError
| 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 { LingbotWorld2Model } from "@reactor-models/lingbot-world-2";
const lingbotWorld2 = new LingbotWorld2Model();
lingbotWorld2.onCommandError((msg) => {
console.log("command_error", msg.reason, msg.command);
});
await lingbotWorld2.connect(jwt);React
import { useLingbotWorld2CommandError } from "@reactor-models/lingbot-world-2";
// Inside a React component wrapped by <LingbotWorld2Provider>:
useLingbotWorld2CommandError((msg) => {
console.log("command_error", msg.reason, msg.command);
});chunk_complete
Emitted once per completed chunk of main_video.
Listener: onChunkComplete · React hook: useLingbotWorld2ChunkComplete
| Field | Type | Description |
|---|---|---|
| chunk_index | number | Zero-based index of the chunk that just completed. |
| active_action | string | The composite action string used to drive this chunk — a +-joined combination of translation (w/s/a/d) and look directions (left/right/up/down), or still when the camera is stationary. |
| active_prompt | string | The prompt that was active while this chunk was generated. |
| frames_emitted | number | Number of pixel frames emitted by this chunk. |
JavaScript
import { LingbotWorld2Model } from "@reactor-models/lingbot-world-2";
const lingbotWorld2 = new LingbotWorld2Model();
lingbotWorld2.onChunkComplete((msg) => {
console.log(
"chunk_complete",
msg.chunk_index,
msg.active_action,
msg.active_prompt,
msg.frames_emitted,
);
});
await lingbotWorld2.connect(jwt);React
import { useLingbotWorld2ChunkComplete } from "@reactor-models/lingbot-world-2";
// Inside a React component wrapped by <LingbotWorld2Provider>:
useLingbotWorld2ChunkComplete((msg) => {
console.log(
"chunk_complete",
msg.chunk_index,
msg.active_action,
msg.active_prompt,
msg.frames_emitted,
);
});image_accepted
Emitted after set_image successfully decodes the uploaded file.
Listener: onImageAccepted · React hook: useLingbotWorld2ImageAccepted
| 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 { LingbotWorld2Model } from "@reactor-models/lingbot-world-2";
const lingbotWorld2 = new LingbotWorld2Model();
lingbotWorld2.onImageAccepted((msg) => {
console.log("image_accepted", msg.width, msg.height);
});
await lingbotWorld2.connect(jwt);React
import { useLingbotWorld2ImageAccepted } from "@reactor-models/lingbot-world-2";
// Inside a React component wrapped by <LingbotWorld2Provider>:
useLingbotWorld2ImageAccepted((msg) => {
console.log("image_accepted", msg.width, msg.height);
});prompt_accepted
Emitted after set_prompt is accepted.
Listener: onPromptAccepted · React hook: useLingbotWorld2PromptAccepted
| Field | Type | Description |
|---|---|---|
| prompt | string | The prompt text that was accepted. |
JavaScript
import { LingbotWorld2Model } from "@reactor-models/lingbot-world-2";
const lingbotWorld2 = new LingbotWorld2Model();
lingbotWorld2.onPromptAccepted((msg) => {
console.log("prompt_accepted", msg.prompt);
});
await lingbotWorld2.connect(jwt);React
import { useLingbotWorld2PromptAccepted } from "@reactor-models/lingbot-world-2";
// Inside a React component wrapped by <LingbotWorld2Provider>:
useLingbotWorld2PromptAccepted((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: useLingbotWorld2ConditionsReady
| Field | Type | Description |
|---|---|---|
| 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. |
JavaScript
import { LingbotWorld2Model } from "@reactor-models/lingbot-world-2";
const lingbotWorld2 = new LingbotWorld2Model();
lingbotWorld2.onConditionsReady((msg) => {
console.log("conditions_ready", msg.has_image, msg.has_prompt);
});
await lingbotWorld2.connect(jwt);React
import { useLingbotWorld2ConditionsReady } from "@reactor-models/lingbot-world-2";
// Inside a React component wrapped by <LingbotWorld2Provider>:
useLingbotWorld2ConditionsReady((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: useLingbotWorld2GenerationReset
| Field | Type | Description |
|---|---|---|
| reason | string | Short human-readable reason the reset was issued. |
JavaScript
import { LingbotWorld2Model } from "@reactor-models/lingbot-world-2";
const lingbotWorld2 = new LingbotWorld2Model();
lingbotWorld2.onGenerationReset((msg) => {
console.log("generation_reset", msg.reason);
});
await lingbotWorld2.connect(jwt);React
import { useLingbotWorld2GenerationReset } from "@reactor-models/lingbot-world-2";
// Inside a React component wrapped by <LingbotWorld2Provider>:
useLingbotWorld2GenerationReset((msg) => {
console.log("generation_reset", msg.reason);
});generation_paused
Emitted in response to pause, once the current chunk finishes.
Listener: onGenerationPaused · React hook: useLingbotWorld2GenerationPaused
| Field | Type | Description |
|---|---|---|
| chunk_index | number | Index of the last completed chunk before pausing. |
JavaScript
import { LingbotWorld2Model } from "@reactor-models/lingbot-world-2";
const lingbotWorld2 = new LingbotWorld2Model();
lingbotWorld2.onGenerationPaused((msg) => {
console.log("generation_paused", msg.chunk_index);
});
await lingbotWorld2.connect(jwt);React
import { useLingbotWorld2GenerationPaused } from "@reactor-models/lingbot-world-2";
// Inside a React component wrapped by <LingbotWorld2Provider>:
useLingbotWorld2GenerationPaused((msg) => {
console.log("generation_paused", msg.chunk_index);
});generation_resumed
Emitted in response to resume when leaving the paused state.
Listener: onGenerationResumed · React hook: useLingbotWorld2GenerationResumed
| Field | Type | Description |
|---|---|---|
| chunk_index | number | Index of the last completed chunk before resuming. |
JavaScript
import { LingbotWorld2Model } from "@reactor-models/lingbot-world-2";
const lingbotWorld2 = new LingbotWorld2Model();
lingbotWorld2.onGenerationResumed((msg) => {
console.log("generation_resumed", msg.chunk_index);
});
await lingbotWorld2.connect(jwt);React
import { useLingbotWorld2GenerationResumed } from "@reactor-models/lingbot-world-2";
// Inside a React component wrapped by <LingbotWorld2Provider>:
useLingbotWorld2GenerationResumed((msg) => {
console.log("generation_resumed", msg.chunk_index);
});generation_started
Emitted once when start succeeds and frames begin streaming.
Listener: onGenerationStarted · React hook: useLingbotWorld2GenerationStarted
| Field | Type | Description |
|---|---|---|
| prompt | string | The prompt active at the start of generation. |
| chunk_num | number | Total number of chunks the run will produce before generation_complete fires. |
| frame_num | number | Total number of pixel frames the run will emit on main_video before generation_complete. |
JavaScript
import { LingbotWorld2Model } from "@reactor-models/lingbot-world-2";
const lingbotWorld2 = new LingbotWorld2Model();
lingbotWorld2.onGenerationStarted((msg) => {
console.log(
"generation_started",
msg.prompt,
msg.chunk_num,
msg.frame_num,
);
});
await lingbotWorld2.connect(jwt);React
import { useLingbotWorld2GenerationStarted } from "@reactor-models/lingbot-world-2";
// Inside a React component wrapped by <LingbotWorld2Provider>:
useLingbotWorld2GenerationStarted((msg) => {
console.log(
"generation_started",
msg.prompt,
msg.chunk_num,
msg.frame_num,
);
});generation_complete
Emitted when all chunk_num chunks of a run have streamed. If the
session is still started, a new run kicks off immediately with the
same prompt and image; call reset to stop.
Listener: onGenerationComplete · React hook: useLingbotWorld2GenerationComplete
| Field | Type | Description |
|---|---|---|
| total_chunks | number | Total number of chunks produced by the run. |
JavaScript
import { LingbotWorld2Model } from "@reactor-models/lingbot-world-2";
const lingbotWorld2 = new LingbotWorld2Model();
lingbotWorld2.onGenerationComplete((msg) => {
console.log("generation_complete", msg.total_chunks);
});
await lingbotWorld2.connect(jwt);React
import { useLingbotWorld2GenerationComplete } from "@reactor-models/lingbot-world-2";
// Inside a React component wrapped by <LingbotWorld2Provider>:
useLingbotWorld2GenerationComplete((msg) => {
console.log("generation_complete", msg.total_chunks);
});Tracks
Named media channels between your app and the LingbotWorld2 model. Use the typed helpers below — LingbotWorld2Model.publish<Track> / on<Track> in plain JS, and useLingbotWorld2Track or the per-track <LingbotWorld2<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 { LingbotWorld2Model } from "@reactor-models/lingbot-world-2";
const lingbotWorld2 = new LingbotWorld2Model();
lingbotWorld2.onMainVideo((track, stream) => {
// attach to a <video> element, pipe to a canvas, etc.
videoEl.srcObject = stream;
});
await lingbotWorld2.connect(jwt);React
"use client";
import { LingbotWorld2MainVideoView } from "@reactor-models/lingbot-world-2";
// Inside a component wrapped by <LingbotWorld2Provider>:
export function Example() {
return <LingbotWorld2MainVideoView className="w-full aspect-video" />;
}