@reactor-models/lingbot-world-2 0.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1084 -0
- package/dist/chunk-GS3BM4VC.mjs +247 -0
- package/dist/chunk-GS3BM4VC.mjs.map +1 -0
- package/dist/chunk-NTXVRMPF.mjs +205 -0
- package/dist/chunk-NTXVRMPF.mjs.map +1 -0
- package/dist/core.d.mts +370 -0
- package/dist/core.d.ts +370 -0
- package/dist/core.js +275 -0
- package/dist/core.js.map +1 -0
- package/dist/core.mjs +15 -0
- package/dist/core.mjs.map +1 -0
- package/dist/index.d.mts +4 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +485 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +49 -0
- package/dist/index.mjs.map +1 -0
- package/dist/react.d.mts +150 -0
- package/dist/react.d.ts +150 -0
- package/dist/react.js +244 -0
- package/dist/react.js.map +1 -0
- package/dist/react.mjs +39 -0
- package/dist/react.mjs.map +1 -0
- package/package.json +54 -0
package/README.md
ADDED
|
@@ -0,0 +1,1084 @@
|
|
|
1
|
+
# @reactor-models/lingbot-world-2
|
|
2
|
+
|
|
3
|
+
> Typed JavaScript + React SDK for the **LingbotWorld2** model on [Reactor](https://reactor.inc). Version **v0.2.5**.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Get started
|
|
8
|
+
|
|
9
|
+
Scaffold a starter app for **LingbotWorld2** with [`create-reactor-app`](https://www.npmjs.com/package/create-reactor-app):
|
|
10
|
+
|
|
11
|
+
```shell
|
|
12
|
+
npx create-reactor-app my-app --model=lingbot-world-2
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
```shell
|
|
16
|
+
pnpm dlx create-reactor-app my-app --model=lingbot-world-2
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Install
|
|
22
|
+
|
|
23
|
+
```shell
|
|
24
|
+
npm install @reactor-models/lingbot-world-2
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
```shell
|
|
28
|
+
pnpm add @reactor-models/lingbot-world-2
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
The package exports a plain-JavaScript client and a set of React bindings. Import whichever you need from `@reactor-models/lingbot-world-2`:
|
|
32
|
+
|
|
33
|
+
```typescript
|
|
34
|
+
import { LingbotWorld2Model } from "@reactor-models/lingbot-world-2";
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
import { LingbotWorld2Provider, useLingbotWorld2 } from "@reactor-models/lingbot-world-2";
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
React 18 or later is required when using the provider and hooks. The token-loading examples below use [React 19's `use()`](https://react.dev/reference/react/use); on React 18, fetch the JWT in a `useEffect` and pass it to the provider once it resolves.
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Authenticate
|
|
46
|
+
|
|
47
|
+
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.
|
|
48
|
+
|
|
49
|
+
Mint a JWT with **`POST https://api.reactor.inc/tokens`** and the **`Reactor-API-Key`** header; the response JSON is `{ "jwt": "..." }`.
|
|
50
|
+
|
|
51
|
+
### JavaScript (Next.js route handler)
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
// app/api/reactor/token/route.ts
|
|
55
|
+
import { NextResponse } from "next/server";
|
|
56
|
+
|
|
57
|
+
export async function POST() {
|
|
58
|
+
const res = await fetch("https://api.reactor.inc/tokens", {
|
|
59
|
+
method: "POST",
|
|
60
|
+
headers: { "Reactor-API-Key": process.env.REACTOR_API_KEY! },
|
|
61
|
+
});
|
|
62
|
+
const { jwt } = await res.json();
|
|
63
|
+
return NextResponse.json({ jwt });
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### React (provider)
|
|
68
|
+
|
|
69
|
+
Call the `/api/reactor/token` route above from a client component and pass the result to the provider:
|
|
70
|
+
|
|
71
|
+
```tsx
|
|
72
|
+
"use client";
|
|
73
|
+
|
|
74
|
+
import { use } from "react";
|
|
75
|
+
import { LingbotWorld2Provider } from "@reactor-models/lingbot-world-2";
|
|
76
|
+
import { ReactorView } from "@reactor-team/js-sdk";
|
|
77
|
+
|
|
78
|
+
async function getToken() {
|
|
79
|
+
const r = await fetch("/api/reactor/token", { method: "POST" });
|
|
80
|
+
const { jwt } = await r.json();
|
|
81
|
+
return jwt;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const tokenPromise = getToken();
|
|
85
|
+
|
|
86
|
+
export default function App() {
|
|
87
|
+
const token = use(tokenPromise);
|
|
88
|
+
return (
|
|
89
|
+
<LingbotWorld2Provider jwtToken={token} connectOptions={{ autoConnect: true }}>
|
|
90
|
+
<ReactorView className="w-full aspect-video" />
|
|
91
|
+
</LingbotWorld2Provider>
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## Connect
|
|
99
|
+
|
|
100
|
+
### JavaScript
|
|
101
|
+
|
|
102
|
+
```typescript
|
|
103
|
+
import { LingbotWorld2Model } from "@reactor-models/lingbot-world-2";
|
|
104
|
+
|
|
105
|
+
const lingbotWorld2 = new LingbotWorld2Model();
|
|
106
|
+
await lingbotWorld2.connect(jwt);
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### React
|
|
110
|
+
|
|
111
|
+
The provider takes the JWT as a prop; fetch it from the same `/api/reactor/token` route the Authenticate example mints:
|
|
112
|
+
|
|
113
|
+
```tsx
|
|
114
|
+
"use client";
|
|
115
|
+
|
|
116
|
+
import { use } from "react";
|
|
117
|
+
import { LingbotWorld2Provider, useLingbotWorld2 } from "@reactor-models/lingbot-world-2";
|
|
118
|
+
|
|
119
|
+
async function getToken() {
|
|
120
|
+
const r = await fetch("/api/reactor/token", { method: "POST" });
|
|
121
|
+
const { jwt } = await r.json();
|
|
122
|
+
return jwt;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const tokenPromise = getToken();
|
|
126
|
+
|
|
127
|
+
function Controller() {
|
|
128
|
+
const { status } = useLingbotWorld2();
|
|
129
|
+
return <span>Status: {status}</span>;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export default function App() {
|
|
133
|
+
const token = use(tokenPromise);
|
|
134
|
+
return (
|
|
135
|
+
<LingbotWorld2Provider jwtToken={token}>
|
|
136
|
+
<Controller />
|
|
137
|
+
</LingbotWorld2Provider>
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## Events
|
|
145
|
+
|
|
146
|
+
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.
|
|
147
|
+
|
|
148
|
+
### `pause`
|
|
149
|
+
|
|
150
|
+
Pause generation after the current chunk finishes. Frames stop streaming on `main_video` until [`resume`](#resume) is called. Requires generation to be active. Emits [`generation_paused`](#generation_paused) and [`state`](#state) on success, or [`command_error`](#command_error) if not generating or already paused.
|
|
151
|
+
|
|
152
|
+
Emits: [`generation_paused`](#generation_paused), [`state`](#state), [`command_error`](#command_error)
|
|
153
|
+
|
|
154
|
+
_No parameters._
|
|
155
|
+
|
|
156
|
+
#### JavaScript
|
|
157
|
+
|
|
158
|
+
```typescript
|
|
159
|
+
import { LingbotWorld2Model } from "@reactor-models/lingbot-world-2";
|
|
160
|
+
|
|
161
|
+
const lingbotWorld2 = new LingbotWorld2Model();
|
|
162
|
+
await lingbotWorld2.connect(jwt);
|
|
163
|
+
|
|
164
|
+
await lingbotWorld2.pause();
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
#### React
|
|
168
|
+
|
|
169
|
+
```tsx
|
|
170
|
+
"use client";
|
|
171
|
+
import { useLingbotWorld2 } from "@reactor-models/lingbot-world-2";
|
|
172
|
+
|
|
173
|
+
function Example() {
|
|
174
|
+
const { pause } = useLingbotWorld2();
|
|
175
|
+
|
|
176
|
+
return <button onClick={() => pause()}>pause</button>;
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### `reset`
|
|
181
|
+
|
|
182
|
+
Abort the current run, clear the active prompt and reference image, and return to the waiting state. Valid at any time. After [`reset`](#reset), call [`set_prompt`](#setprompt) and [`set_image`](#setimage) again before [`start`](#start) to begin a new session. Emits [`generation_reset`](#generation_reset) and [`state`](#state).
|
|
183
|
+
|
|
184
|
+
Emits: [`generation_reset`](#generation_reset), [`state`](#state)
|
|
185
|
+
|
|
186
|
+
_No parameters._
|
|
187
|
+
|
|
188
|
+
#### JavaScript
|
|
189
|
+
|
|
190
|
+
```typescript
|
|
191
|
+
import { LingbotWorld2Model } from "@reactor-models/lingbot-world-2";
|
|
192
|
+
|
|
193
|
+
const lingbotWorld2 = new LingbotWorld2Model();
|
|
194
|
+
await lingbotWorld2.connect(jwt);
|
|
195
|
+
|
|
196
|
+
await lingbotWorld2.reset();
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
#### React
|
|
200
|
+
|
|
201
|
+
```tsx
|
|
202
|
+
"use client";
|
|
203
|
+
import { useLingbotWorld2 } from "@reactor-models/lingbot-world-2";
|
|
204
|
+
|
|
205
|
+
function Example() {
|
|
206
|
+
const { reset } = useLingbotWorld2();
|
|
207
|
+
|
|
208
|
+
return <button onClick={() => reset()}>reset</button>;
|
|
209
|
+
}
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### `start`
|
|
213
|
+
|
|
214
|
+
Begin generating video on `main_video`. Requires both a prompt (via [`set_prompt`](#setprompt)) and a reference image (via [`set_image`](#setimage)). Emits [`generation_started`](#generation_started) and [`state`](#state) on success, or [`command_error`](#command_error) if a precondition is missing. Has no effect while already generating.
|
|
215
|
+
|
|
216
|
+
Emits: [`generation_started`](#generation_started), [`state`](#state), [`command_error`](#command_error)
|
|
217
|
+
|
|
218
|
+
_No parameters._
|
|
219
|
+
|
|
220
|
+
#### JavaScript
|
|
221
|
+
|
|
222
|
+
```typescript
|
|
223
|
+
import { LingbotWorld2Model } from "@reactor-models/lingbot-world-2";
|
|
224
|
+
|
|
225
|
+
const lingbotWorld2 = new LingbotWorld2Model();
|
|
226
|
+
await lingbotWorld2.connect(jwt);
|
|
227
|
+
|
|
228
|
+
await lingbotWorld2.start();
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
#### React
|
|
232
|
+
|
|
233
|
+
```tsx
|
|
234
|
+
"use client";
|
|
235
|
+
import { useLingbotWorld2 } from "@reactor-models/lingbot-world-2";
|
|
236
|
+
|
|
237
|
+
function Example() {
|
|
238
|
+
const { start } = useLingbotWorld2();
|
|
239
|
+
|
|
240
|
+
return <button onClick={() => start()}>start</button>;
|
|
241
|
+
}
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
### `resume`
|
|
245
|
+
|
|
246
|
+
Resume generation from a previous [`pause`](#pause). Requires the session to be paused. Emits [`generation_resumed`](#generation_resumed) and [`state`](#state) on success, or [`command_error`](#command_error) if not paused.
|
|
247
|
+
|
|
248
|
+
Emits: [`generation_resumed`](#generation_resumed), [`state`](#state), [`command_error`](#command_error)
|
|
249
|
+
|
|
250
|
+
_No parameters._
|
|
251
|
+
|
|
252
|
+
#### JavaScript
|
|
253
|
+
|
|
254
|
+
```typescript
|
|
255
|
+
import { LingbotWorld2Model } from "@reactor-models/lingbot-world-2";
|
|
256
|
+
|
|
257
|
+
const lingbotWorld2 = new LingbotWorld2Model();
|
|
258
|
+
await lingbotWorld2.connect(jwt);
|
|
259
|
+
|
|
260
|
+
await lingbotWorld2.resume();
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
#### React
|
|
264
|
+
|
|
265
|
+
```tsx
|
|
266
|
+
"use client";
|
|
267
|
+
import { useLingbotWorld2 } from "@reactor-models/lingbot-world-2";
|
|
268
|
+
|
|
269
|
+
function Example() {
|
|
270
|
+
const { resume } = useLingbotWorld2();
|
|
271
|
+
|
|
272
|
+
return <button onClick={() => resume()}>resume</button>;
|
|
273
|
+
}
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
### `setSeed`
|
|
277
|
+
|
|
278
|
+
Set seed
|
|
279
|
+
|
|
280
|
+
| Parameter | Type | Required | Description |
|
|
281
|
+
|---|---|---|---|
|
|
282
|
+
| `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`](#start) fires; later changes take effect only after [`reset`](#reset) followed by a new [`start`](#start). _(min 0, default `42`)_ |
|
|
283
|
+
|
|
284
|
+
#### JavaScript
|
|
285
|
+
|
|
286
|
+
```typescript
|
|
287
|
+
import { LingbotWorld2Model } from "@reactor-models/lingbot-world-2";
|
|
288
|
+
|
|
289
|
+
const lingbotWorld2 = new LingbotWorld2Model();
|
|
290
|
+
await lingbotWorld2.connect(jwt);
|
|
291
|
+
|
|
292
|
+
await lingbotWorld2.setSeed({ seed: 42 });
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
#### React
|
|
296
|
+
|
|
297
|
+
```tsx
|
|
298
|
+
"use client";
|
|
299
|
+
import { useLingbotWorld2 } from "@reactor-models/lingbot-world-2";
|
|
300
|
+
|
|
301
|
+
function Example() {
|
|
302
|
+
const { setSeed } = useLingbotWorld2();
|
|
303
|
+
|
|
304
|
+
return <button onClick={() => setSeed({ seed: 42 })}>setSeed</button>;
|
|
305
|
+
}
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
### `setImage`
|
|
309
|
+
|
|
310
|
+
Provide a reference image that anchors generation (image-to-video). Call before [`start`](#start); the image is required for generation to begin. Changes during generation have no effect until [`reset`](#reset) is issued and [`start`](#start) is called again. Emits [`image_accepted`](#image_accepted), [`conditions_ready`](#conditions_ready), and [`state`](#state) on success, or [`command_error`](#command_error) if the file is missing, not an image, or cannot be decoded.
|
|
311
|
+
|
|
312
|
+
Emits: [`image_accepted`](#image_accepted), [`conditions_ready`](#conditions_ready), [`state`](#state), [`command_error`](#command_error)
|
|
313
|
+
|
|
314
|
+
| Parameter | Type | Required | Description |
|
|
315
|
+
|---|---|---|---|
|
|
316
|
+
| `image` | `FileRef` | | Reference to a file uploaded via the Reactor presigned-URL protocol. _(default `null`)_ |
|
|
317
|
+
|
|
318
|
+
#### JavaScript
|
|
319
|
+
|
|
320
|
+
```typescript
|
|
321
|
+
import { LingbotWorld2Model } from "@reactor-models/lingbot-world-2";
|
|
322
|
+
|
|
323
|
+
const lingbotWorld2 = new LingbotWorld2Model();
|
|
324
|
+
await lingbotWorld2.connect(jwt);
|
|
325
|
+
|
|
326
|
+
const fileRef = await lingbotWorld2.uploadFile(blob);
|
|
327
|
+
await lingbotWorld2.setImage({ image: fileRef });
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
#### React
|
|
331
|
+
|
|
332
|
+
```tsx
|
|
333
|
+
"use client";
|
|
334
|
+
import { useLingbotWorld2 } from "@reactor-models/lingbot-world-2";
|
|
335
|
+
|
|
336
|
+
function Example() {
|
|
337
|
+
const { setImage, uploadFile } = useLingbotWorld2();
|
|
338
|
+
|
|
339
|
+
async function handlePick(file: File) {
|
|
340
|
+
const ref = await uploadFile(file);
|
|
341
|
+
await setImage({ image: ref });
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
return <input type="file" onChange={(e) => handlePick(e.target.files![0])} />;
|
|
345
|
+
}
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
### `setPrompt`
|
|
349
|
+
|
|
350
|
+
Set the scene prompt. Valid at any time — call before [`start`](#start) to arm generation, or hot-swap during generation to steer the next chunk. Emits [`prompt_accepted`](#prompt_accepted), [`conditions_ready`](#conditions_ready), and [`state`](#state) on success.
|
|
351
|
+
|
|
352
|
+
Emits: [`prompt_accepted`](#prompt_accepted), [`conditions_ready`](#conditions_ready), [`state`](#state)
|
|
353
|
+
|
|
354
|
+
| Parameter | Type | Required | Description |
|
|
355
|
+
|---|---|---|---|
|
|
356
|
+
| `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`](#start) fires. _(default `""`)_ |
|
|
357
|
+
|
|
358
|
+
#### JavaScript
|
|
359
|
+
|
|
360
|
+
```typescript
|
|
361
|
+
import { LingbotWorld2Model } from "@reactor-models/lingbot-world-2";
|
|
362
|
+
|
|
363
|
+
const lingbotWorld2 = new LingbotWorld2Model();
|
|
364
|
+
await lingbotWorld2.connect(jwt);
|
|
365
|
+
|
|
366
|
+
await lingbotWorld2.setPrompt({ prompt: "A sunset over the ocean" });
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
#### React
|
|
370
|
+
|
|
371
|
+
```tsx
|
|
372
|
+
"use client";
|
|
373
|
+
import { useLingbotWorld2 } from "@reactor-models/lingbot-world-2";
|
|
374
|
+
|
|
375
|
+
function Example() {
|
|
376
|
+
const { setPrompt } = useLingbotWorld2();
|
|
377
|
+
|
|
378
|
+
return <button onClick={() => setPrompt({ prompt: "A sunset over the ocean" })}>setPrompt</button>;
|
|
379
|
+
}
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
### `setAttnWindow`
|
|
383
|
+
|
|
384
|
+
Set attn_window
|
|
385
|
+
|
|
386
|
+
| Parameter | Type | Required | Description |
|
|
387
|
+
|---|---|---|---|
|
|
388
|
+
| `attn_window` | `"auto" \| "small" \| "large"` | | Manual override for the DiT self-attention window. `auto` uses the motion-based still-window trigger (unchanged default behavior); `small` forces the still (small) window; `large` forces the moving (large) window. Can be changed at any time; the new value applies to the next chunk. _(default `"auto"`)_ |
|
|
389
|
+
|
|
390
|
+
#### JavaScript
|
|
391
|
+
|
|
392
|
+
```typescript
|
|
393
|
+
import { LingbotWorld2Model } from "@reactor-models/lingbot-world-2";
|
|
394
|
+
|
|
395
|
+
const lingbotWorld2 = new LingbotWorld2Model();
|
|
396
|
+
await lingbotWorld2.connect(jwt);
|
|
397
|
+
|
|
398
|
+
await lingbotWorld2.setAttnWindow({ attn_window: "auto" });
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
#### React
|
|
402
|
+
|
|
403
|
+
```tsx
|
|
404
|
+
"use client";
|
|
405
|
+
import { useLingbotWorld2 } from "@reactor-models/lingbot-world-2";
|
|
406
|
+
|
|
407
|
+
function Example() {
|
|
408
|
+
const { setAttnWindow } = useLingbotWorld2();
|
|
409
|
+
|
|
410
|
+
return <button onClick={() => setAttnWindow({ attn_window: "auto" })}>setAttnWindow</button>;
|
|
411
|
+
}
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
### `setCameraPose`
|
|
415
|
+
|
|
416
|
+
Set camera_pose
|
|
417
|
+
|
|
418
|
+
| Parameter | Type | Required | Description |
|
|
419
|
+
|---|---|---|---|
|
|
420
|
+
| `camera_pose` | `unknown[]` | | Native camera-pose layer: a flat list of per-frame motion deltas, length a multiple of 6 — `[rx, ry, rz, tx, ty, tz]` per frame (small Euler-radian rotation + translation, in the camera-local frame). 6 floats = one delta applied to the whole chunk; 6*chunk_size = one delta per latent frame; any other 6*k is resampled to chunk_size. When active, rotation OVERRIDES look_horizontal / look_vertical and translation ADDS to WASD movement. Inputs are sanitized (NaN/Inf→0, rotations clamped to ±pi, translation to ±100), so any payload is safe. Pass an empty list (or omit) to deactivate. _(maxLength 1536, default `null`)_ |
|
|
421
|
+
|
|
422
|
+
#### JavaScript
|
|
423
|
+
|
|
424
|
+
```typescript
|
|
425
|
+
import { LingbotWorld2Model } from "@reactor-models/lingbot-world-2";
|
|
426
|
+
|
|
427
|
+
const lingbotWorld2 = new LingbotWorld2Model();
|
|
428
|
+
await lingbotWorld2.connect(jwt);
|
|
429
|
+
|
|
430
|
+
await lingbotWorld2.setCameraPose({ camera_pose: null });
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
#### React
|
|
434
|
+
|
|
435
|
+
```tsx
|
|
436
|
+
"use client";
|
|
437
|
+
import { useLingbotWorld2 } from "@reactor-models/lingbot-world-2";
|
|
438
|
+
|
|
439
|
+
function Example() {
|
|
440
|
+
const { setCameraPose } = useLingbotWorld2();
|
|
441
|
+
|
|
442
|
+
return <button onClick={() => setCameraPose({ camera_pose: null })}>setCameraPose</button>;
|
|
443
|
+
}
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
### `setMoveLateral`
|
|
447
|
+
|
|
448
|
+
Set move_lateral
|
|
449
|
+
|
|
450
|
+
| Parameter | Type | Required | Description |
|
|
451
|
+
|---|---|---|---|
|
|
452
|
+
| `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"`)_ |
|
|
453
|
+
|
|
454
|
+
#### JavaScript
|
|
455
|
+
|
|
456
|
+
```typescript
|
|
457
|
+
import { LingbotWorld2Model } from "@reactor-models/lingbot-world-2";
|
|
458
|
+
|
|
459
|
+
const lingbotWorld2 = new LingbotWorld2Model();
|
|
460
|
+
await lingbotWorld2.connect(jwt);
|
|
461
|
+
|
|
462
|
+
await lingbotWorld2.setMoveLateral({ move_lateral: "idle" });
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
#### React
|
|
466
|
+
|
|
467
|
+
```tsx
|
|
468
|
+
"use client";
|
|
469
|
+
import { useLingbotWorld2 } from "@reactor-models/lingbot-world-2";
|
|
470
|
+
|
|
471
|
+
function Example() {
|
|
472
|
+
const { setMoveLateral } = useLingbotWorld2();
|
|
473
|
+
|
|
474
|
+
return <button onClick={() => setMoveLateral({ move_lateral: "idle" })}>setMoveLateral</button>;
|
|
475
|
+
}
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
### `setLookVertical`
|
|
479
|
+
|
|
480
|
+
Set look_vertical
|
|
481
|
+
|
|
482
|
+
| Parameter | Type | Required | Description |
|
|
483
|
+
|---|---|---|---|
|
|
484
|
+
| `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"`)_ |
|
|
485
|
+
|
|
486
|
+
#### JavaScript
|
|
487
|
+
|
|
488
|
+
```typescript
|
|
489
|
+
import { LingbotWorld2Model } from "@reactor-models/lingbot-world-2";
|
|
490
|
+
|
|
491
|
+
const lingbotWorld2 = new LingbotWorld2Model();
|
|
492
|
+
await lingbotWorld2.connect(jwt);
|
|
493
|
+
|
|
494
|
+
await lingbotWorld2.setLookVertical({ look_vertical: "idle" });
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
#### React
|
|
498
|
+
|
|
499
|
+
```tsx
|
|
500
|
+
"use client";
|
|
501
|
+
import { useLingbotWorld2 } from "@reactor-models/lingbot-world-2";
|
|
502
|
+
|
|
503
|
+
function Example() {
|
|
504
|
+
const { setLookVertical } = useLingbotWorld2();
|
|
505
|
+
|
|
506
|
+
return <button onClick={() => setLookVertical({ look_vertical: "idle" })}>setLookVertical</button>;
|
|
507
|
+
}
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
### `setLookHorizontal`
|
|
511
|
+
|
|
512
|
+
Set look_horizontal
|
|
513
|
+
|
|
514
|
+
| Parameter | Type | Required | Description |
|
|
515
|
+
|---|---|---|---|
|
|
516
|
+
| `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"`)_ |
|
|
517
|
+
|
|
518
|
+
#### JavaScript
|
|
519
|
+
|
|
520
|
+
```typescript
|
|
521
|
+
import { LingbotWorld2Model } from "@reactor-models/lingbot-world-2";
|
|
522
|
+
|
|
523
|
+
const lingbotWorld2 = new LingbotWorld2Model();
|
|
524
|
+
await lingbotWorld2.connect(jwt);
|
|
525
|
+
|
|
526
|
+
await lingbotWorld2.setLookHorizontal({ look_horizontal: "idle" });
|
|
527
|
+
```
|
|
528
|
+
|
|
529
|
+
#### React
|
|
530
|
+
|
|
531
|
+
```tsx
|
|
532
|
+
"use client";
|
|
533
|
+
import { useLingbotWorld2 } from "@reactor-models/lingbot-world-2";
|
|
534
|
+
|
|
535
|
+
function Example() {
|
|
536
|
+
const { setLookHorizontal } = useLingbotWorld2();
|
|
537
|
+
|
|
538
|
+
return <button onClick={() => setLookHorizontal({ look_horizontal: "idle" })}>setLookHorizontal</button>;
|
|
539
|
+
}
|
|
540
|
+
```
|
|
541
|
+
|
|
542
|
+
### `setMoveLongitudinal`
|
|
543
|
+
|
|
544
|
+
Set move_longitudinal
|
|
545
|
+
|
|
546
|
+
| Parameter | Type | Required | Description |
|
|
547
|
+
|---|---|---|---|
|
|
548
|
+
| `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"`)_ |
|
|
549
|
+
|
|
550
|
+
#### JavaScript
|
|
551
|
+
|
|
552
|
+
```typescript
|
|
553
|
+
import { LingbotWorld2Model } from "@reactor-models/lingbot-world-2";
|
|
554
|
+
|
|
555
|
+
const lingbotWorld2 = new LingbotWorld2Model();
|
|
556
|
+
await lingbotWorld2.connect(jwt);
|
|
557
|
+
|
|
558
|
+
await lingbotWorld2.setMoveLongitudinal({ move_longitudinal: "idle" });
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
#### React
|
|
562
|
+
|
|
563
|
+
```tsx
|
|
564
|
+
"use client";
|
|
565
|
+
import { useLingbotWorld2 } from "@reactor-models/lingbot-world-2";
|
|
566
|
+
|
|
567
|
+
function Example() {
|
|
568
|
+
const { setMoveLongitudinal } = useLingbotWorld2();
|
|
569
|
+
|
|
570
|
+
return <button onClick={() => setMoveLongitudinal({ move_longitudinal: "idle" })}>setMoveLongitudinal</button>;
|
|
571
|
+
}
|
|
572
|
+
```
|
|
573
|
+
|
|
574
|
+
### `setRotationSpeedDeg`
|
|
575
|
+
|
|
576
|
+
Set rotation_speed_deg
|
|
577
|
+
|
|
578
|
+
| Parameter | Type | Required | Description |
|
|
579
|
+
|---|---|---|---|
|
|
580
|
+
| `rotation_speed_deg` | `number` | | Camera rotation speed in degrees per latent frame, applied when `look_horizontal` or `look_vertical` is not `idle`. 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`)_ |
|
|
581
|
+
|
|
582
|
+
#### JavaScript
|
|
583
|
+
|
|
584
|
+
```typescript
|
|
585
|
+
import { LingbotWorld2Model } from "@reactor-models/lingbot-world-2";
|
|
586
|
+
|
|
587
|
+
const lingbotWorld2 = new LingbotWorld2Model();
|
|
588
|
+
await lingbotWorld2.connect(jwt);
|
|
589
|
+
|
|
590
|
+
await lingbotWorld2.setRotationSpeedDeg({ rotation_speed_deg: 5 });
|
|
591
|
+
```
|
|
592
|
+
|
|
593
|
+
#### React
|
|
594
|
+
|
|
595
|
+
```tsx
|
|
596
|
+
"use client";
|
|
597
|
+
import { useLingbotWorld2 } from "@reactor-models/lingbot-world-2";
|
|
598
|
+
|
|
599
|
+
function Example() {
|
|
600
|
+
const { setRotationSpeedDeg } = useLingbotWorld2();
|
|
601
|
+
|
|
602
|
+
return <button onClick={() => setRotationSpeedDeg({ rotation_speed_deg: 5 })}>setRotationSpeedDeg</button>;
|
|
603
|
+
}
|
|
604
|
+
```
|
|
605
|
+
|
|
606
|
+
## Messages
|
|
607
|
+
|
|
608
|
+
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.
|
|
609
|
+
|
|
610
|
+
### `state`
|
|
611
|
+
|
|
612
|
+
Snapshot of the session's observable state.
|
|
613
|
+
|
|
614
|
+
Emitted on connect, after every command that mutates session state ([`set_prompt`](#setprompt), [`set_image`](#setimage), [`start`](#start), [`pause`](#pause), [`resume`](#resume), [`reset`](#reset), and the auto-generated `set_<field>` setters), and after each [`chunk_complete`](#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.
|
|
615
|
+
|
|
616
|
+
Listener: `onState` · React hook: `useLingbotWorld2State`
|
|
617
|
+
|
|
618
|
+
| Field | Type | Description |
|
|
619
|
+
|---|---|---|
|
|
620
|
+
| `seed` | `number` | Current value of the `seed` input field. The seed that was actually used by the running generation was captured when [`start`](#start) fired — later changes to `seed` only take effect after [`reset`](#reset) and a new [`start`](#start). |
|
|
621
|
+
| `paused` | `boolean` | True while generation is paused via [`pause`](#pause). |
|
|
622
|
+
| `running` | `boolean` | True while the chunk loop is actively producing frames — equivalent to `started and not paused`. `False` both before [`start`](#start) and while paused; read `started` to disambiguate. |
|
|
623
|
+
| `started` | `boolean` | True once [`start`](#start) has been accepted. Remains true while paused; reset to false by [`reset`](#reset) or after [`generation_complete`](#generation_complete) when the session is not auto-restarting. |
|
|
624
|
+
| `has_image` | `boolean` | True once a reference image has been set for the session. |
|
|
625
|
+
| `has_prompt` | `boolean` | True once a prompt has been set for the session. |
|
|
626
|
+
| `move_lateral` | `string` | Current value of the `move_lateral` input field. |
|
|
627
|
+
| `current_chunk` | `number` | Zero-based index of the last completed chunk. `0` before the first chunk has completed, and resets to `0` on [`reset`](#reset). |
|
|
628
|
+
| `look_vertical` | `string` | Current value of the `look_vertical` input field. |
|
|
629
|
+
| `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. |
|
|
630
|
+
| `current_prompt` | `unknown` | The prompt currently driving generation, or `null` if no prompt has been set for the session. |
|
|
631
|
+
| `look_horizontal` | `string` | Current value of the `look_horizontal` input field. |
|
|
632
|
+
| `move_longitudinal` | `string` | Current value of the `move_longitudinal` input field. |
|
|
633
|
+
| `camera_pose_active` | `boolean` | True when a non-empty `camera_pose` has been set. |
|
|
634
|
+
| `rotation_speed_deg` | `number` | Current value of the `rotation_speed_deg` input field (0.0 – 30.0). |
|
|
635
|
+
|
|
636
|
+
#### JavaScript
|
|
637
|
+
|
|
638
|
+
```typescript
|
|
639
|
+
import { LingbotWorld2Model } from "@reactor-models/lingbot-world-2";
|
|
640
|
+
|
|
641
|
+
const lingbotWorld2 = new LingbotWorld2Model();
|
|
642
|
+
lingbotWorld2.onState((msg) => {
|
|
643
|
+
console.log(
|
|
644
|
+
"state",
|
|
645
|
+
msg.seed,
|
|
646
|
+
msg.paused,
|
|
647
|
+
msg.running,
|
|
648
|
+
msg.started,
|
|
649
|
+
msg.has_image,
|
|
650
|
+
msg.has_prompt,
|
|
651
|
+
msg.move_lateral,
|
|
652
|
+
msg.current_chunk,
|
|
653
|
+
msg.look_vertical,
|
|
654
|
+
msg.current_action,
|
|
655
|
+
msg.current_prompt,
|
|
656
|
+
msg.look_horizontal,
|
|
657
|
+
msg.move_longitudinal,
|
|
658
|
+
msg.camera_pose_active,
|
|
659
|
+
msg.rotation_speed_deg,
|
|
660
|
+
);
|
|
661
|
+
});
|
|
662
|
+
await lingbotWorld2.connect(jwt);
|
|
663
|
+
```
|
|
664
|
+
|
|
665
|
+
#### React
|
|
666
|
+
|
|
667
|
+
```tsx
|
|
668
|
+
import { useLingbotWorld2State } from "@reactor-models/lingbot-world-2";
|
|
669
|
+
|
|
670
|
+
// Inside a React component wrapped by <LingbotWorld2Provider>:
|
|
671
|
+
useLingbotWorld2State((msg) => {
|
|
672
|
+
console.log(
|
|
673
|
+
"state",
|
|
674
|
+
msg.seed,
|
|
675
|
+
msg.paused,
|
|
676
|
+
msg.running,
|
|
677
|
+
msg.started,
|
|
678
|
+
msg.has_image,
|
|
679
|
+
msg.has_prompt,
|
|
680
|
+
msg.move_lateral,
|
|
681
|
+
msg.current_chunk,
|
|
682
|
+
msg.look_vertical,
|
|
683
|
+
msg.current_action,
|
|
684
|
+
msg.current_prompt,
|
|
685
|
+
msg.look_horizontal,
|
|
686
|
+
msg.move_longitudinal,
|
|
687
|
+
msg.camera_pose_active,
|
|
688
|
+
msg.rotation_speed_deg,
|
|
689
|
+
);
|
|
690
|
+
});
|
|
691
|
+
```
|
|
692
|
+
|
|
693
|
+
### `command_error`
|
|
694
|
+
|
|
695
|
+
Emitted when a command is rejected because preconditions are not met or its arguments could not be processed.
|
|
696
|
+
|
|
697
|
+
Listener: `onCommandError` · React hook: `useLingbotWorld2CommandError`
|
|
698
|
+
|
|
699
|
+
| Field | Type | Description |
|
|
700
|
+
|---|---|---|
|
|
701
|
+
| `reason` | `string` | Human-readable explanation of why the command was rejected. |
|
|
702
|
+
| `command` | `string` | Name of the command that was rejected. |
|
|
703
|
+
|
|
704
|
+
#### JavaScript
|
|
705
|
+
|
|
706
|
+
```typescript
|
|
707
|
+
import { LingbotWorld2Model } from "@reactor-models/lingbot-world-2";
|
|
708
|
+
|
|
709
|
+
const lingbotWorld2 = new LingbotWorld2Model();
|
|
710
|
+
lingbotWorld2.onCommandError((msg) => {
|
|
711
|
+
console.log("command_error", msg.reason, msg.command);
|
|
712
|
+
});
|
|
713
|
+
await lingbotWorld2.connect(jwt);
|
|
714
|
+
```
|
|
715
|
+
|
|
716
|
+
#### React
|
|
717
|
+
|
|
718
|
+
```tsx
|
|
719
|
+
import { useLingbotWorld2CommandError } from "@reactor-models/lingbot-world-2";
|
|
720
|
+
|
|
721
|
+
// Inside a React component wrapped by <LingbotWorld2Provider>:
|
|
722
|
+
useLingbotWorld2CommandError((msg) => {
|
|
723
|
+
console.log("command_error", msg.reason, msg.command);
|
|
724
|
+
});
|
|
725
|
+
```
|
|
726
|
+
|
|
727
|
+
### `chunk_complete`
|
|
728
|
+
|
|
729
|
+
Emitted once per completed chunk of `main_video`.
|
|
730
|
+
|
|
731
|
+
Listener: `onChunkComplete` · React hook: `useLingbotWorld2ChunkComplete`
|
|
732
|
+
|
|
733
|
+
| Field | Type | Description |
|
|
734
|
+
|---|---|---|
|
|
735
|
+
| `chunk_index` | `number` | Zero-based index of the chunk that just completed. |
|
|
736
|
+
| `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. |
|
|
737
|
+
| `active_prompt` | `string` | The prompt that was active while this chunk was generated. |
|
|
738
|
+
| `frames_emitted` | `number` | Number of pixel frames emitted by this chunk. |
|
|
739
|
+
|
|
740
|
+
#### JavaScript
|
|
741
|
+
|
|
742
|
+
```typescript
|
|
743
|
+
import { LingbotWorld2Model } from "@reactor-models/lingbot-world-2";
|
|
744
|
+
|
|
745
|
+
const lingbotWorld2 = new LingbotWorld2Model();
|
|
746
|
+
lingbotWorld2.onChunkComplete((msg) => {
|
|
747
|
+
console.log(
|
|
748
|
+
"chunk_complete",
|
|
749
|
+
msg.chunk_index,
|
|
750
|
+
msg.active_action,
|
|
751
|
+
msg.active_prompt,
|
|
752
|
+
msg.frames_emitted,
|
|
753
|
+
);
|
|
754
|
+
});
|
|
755
|
+
await lingbotWorld2.connect(jwt);
|
|
756
|
+
```
|
|
757
|
+
|
|
758
|
+
#### React
|
|
759
|
+
|
|
760
|
+
```tsx
|
|
761
|
+
import { useLingbotWorld2ChunkComplete } from "@reactor-models/lingbot-world-2";
|
|
762
|
+
|
|
763
|
+
// Inside a React component wrapped by <LingbotWorld2Provider>:
|
|
764
|
+
useLingbotWorld2ChunkComplete((msg) => {
|
|
765
|
+
console.log(
|
|
766
|
+
"chunk_complete",
|
|
767
|
+
msg.chunk_index,
|
|
768
|
+
msg.active_action,
|
|
769
|
+
msg.active_prompt,
|
|
770
|
+
msg.frames_emitted,
|
|
771
|
+
);
|
|
772
|
+
});
|
|
773
|
+
```
|
|
774
|
+
|
|
775
|
+
### `image_accepted`
|
|
776
|
+
|
|
777
|
+
Emitted after [`set_image`](#setimage) successfully decodes the uploaded file.
|
|
778
|
+
|
|
779
|
+
Listener: `onImageAccepted` · React hook: `useLingbotWorld2ImageAccepted`
|
|
780
|
+
|
|
781
|
+
| Field | Type | Description |
|
|
782
|
+
|---|---|---|
|
|
783
|
+
| `width` | `number` | Width in pixels of the decoded reference image. |
|
|
784
|
+
| `height` | `number` | Height in pixels of the decoded reference image. |
|
|
785
|
+
|
|
786
|
+
#### JavaScript
|
|
787
|
+
|
|
788
|
+
```typescript
|
|
789
|
+
import { LingbotWorld2Model } from "@reactor-models/lingbot-world-2";
|
|
790
|
+
|
|
791
|
+
const lingbotWorld2 = new LingbotWorld2Model();
|
|
792
|
+
lingbotWorld2.onImageAccepted((msg) => {
|
|
793
|
+
console.log("image_accepted", msg.width, msg.height);
|
|
794
|
+
});
|
|
795
|
+
await lingbotWorld2.connect(jwt);
|
|
796
|
+
```
|
|
797
|
+
|
|
798
|
+
#### React
|
|
799
|
+
|
|
800
|
+
```tsx
|
|
801
|
+
import { useLingbotWorld2ImageAccepted } from "@reactor-models/lingbot-world-2";
|
|
802
|
+
|
|
803
|
+
// Inside a React component wrapped by <LingbotWorld2Provider>:
|
|
804
|
+
useLingbotWorld2ImageAccepted((msg) => {
|
|
805
|
+
console.log("image_accepted", msg.width, msg.height);
|
|
806
|
+
});
|
|
807
|
+
```
|
|
808
|
+
|
|
809
|
+
### `prompt_accepted`
|
|
810
|
+
|
|
811
|
+
Emitted after [`set_prompt`](#setprompt) is accepted.
|
|
812
|
+
|
|
813
|
+
Listener: `onPromptAccepted` · React hook: `useLingbotWorld2PromptAccepted`
|
|
814
|
+
|
|
815
|
+
| Field | Type | Description |
|
|
816
|
+
|---|---|---|
|
|
817
|
+
| `prompt` | `string` | The prompt text that was accepted. |
|
|
818
|
+
|
|
819
|
+
#### JavaScript
|
|
820
|
+
|
|
821
|
+
```typescript
|
|
822
|
+
import { LingbotWorld2Model } from "@reactor-models/lingbot-world-2";
|
|
823
|
+
|
|
824
|
+
const lingbotWorld2 = new LingbotWorld2Model();
|
|
825
|
+
lingbotWorld2.onPromptAccepted((msg) => {
|
|
826
|
+
console.log("prompt_accepted", msg.prompt);
|
|
827
|
+
});
|
|
828
|
+
await lingbotWorld2.connect(jwt);
|
|
829
|
+
```
|
|
830
|
+
|
|
831
|
+
#### React
|
|
832
|
+
|
|
833
|
+
```tsx
|
|
834
|
+
import { useLingbotWorld2PromptAccepted } from "@reactor-models/lingbot-world-2";
|
|
835
|
+
|
|
836
|
+
// Inside a React component wrapped by <LingbotWorld2Provider>:
|
|
837
|
+
useLingbotWorld2PromptAccepted((msg) => {
|
|
838
|
+
console.log("prompt_accepted", msg.prompt);
|
|
839
|
+
});
|
|
840
|
+
```
|
|
841
|
+
|
|
842
|
+
### `conditions_ready`
|
|
843
|
+
|
|
844
|
+
Emitted after [`set_prompt`](#setprompt) or [`set_image`](#setimage) so the client can tell at a glance whether [`start`](#start) will succeed.
|
|
845
|
+
|
|
846
|
+
Listener: `onConditionsReady` · React hook: `useLingbotWorld2ConditionsReady`
|
|
847
|
+
|
|
848
|
+
| Field | Type | Description |
|
|
849
|
+
|---|---|---|
|
|
850
|
+
| `has_image` | `boolean` | True once a reference image has been set for the session. |
|
|
851
|
+
| `has_prompt` | `boolean` | True once a prompt has been set for the session. |
|
|
852
|
+
|
|
853
|
+
#### JavaScript
|
|
854
|
+
|
|
855
|
+
```typescript
|
|
856
|
+
import { LingbotWorld2Model } from "@reactor-models/lingbot-world-2";
|
|
857
|
+
|
|
858
|
+
const lingbotWorld2 = new LingbotWorld2Model();
|
|
859
|
+
lingbotWorld2.onConditionsReady((msg) => {
|
|
860
|
+
console.log("conditions_ready", msg.has_image, msg.has_prompt);
|
|
861
|
+
});
|
|
862
|
+
await lingbotWorld2.connect(jwt);
|
|
863
|
+
```
|
|
864
|
+
|
|
865
|
+
#### React
|
|
866
|
+
|
|
867
|
+
```tsx
|
|
868
|
+
import { useLingbotWorld2ConditionsReady } from "@reactor-models/lingbot-world-2";
|
|
869
|
+
|
|
870
|
+
// Inside a React component wrapped by <LingbotWorld2Provider>:
|
|
871
|
+
useLingbotWorld2ConditionsReady((msg) => {
|
|
872
|
+
console.log("conditions_ready", msg.has_image, msg.has_prompt);
|
|
873
|
+
});
|
|
874
|
+
```
|
|
875
|
+
|
|
876
|
+
### `generation_reset`
|
|
877
|
+
|
|
878
|
+
Emitted after [`reset`](#reset) clears session state and returns to the waiting state.
|
|
879
|
+
|
|
880
|
+
Listener: `onGenerationReset` · React hook: `useLingbotWorld2GenerationReset`
|
|
881
|
+
|
|
882
|
+
| Field | Type | Description |
|
|
883
|
+
|---|---|---|
|
|
884
|
+
| `reason` | `string` | Short human-readable reason the reset was issued. |
|
|
885
|
+
|
|
886
|
+
#### JavaScript
|
|
887
|
+
|
|
888
|
+
```typescript
|
|
889
|
+
import { LingbotWorld2Model } from "@reactor-models/lingbot-world-2";
|
|
890
|
+
|
|
891
|
+
const lingbotWorld2 = new LingbotWorld2Model();
|
|
892
|
+
lingbotWorld2.onGenerationReset((msg) => {
|
|
893
|
+
console.log("generation_reset", msg.reason);
|
|
894
|
+
});
|
|
895
|
+
await lingbotWorld2.connect(jwt);
|
|
896
|
+
```
|
|
897
|
+
|
|
898
|
+
#### React
|
|
899
|
+
|
|
900
|
+
```tsx
|
|
901
|
+
import { useLingbotWorld2GenerationReset } from "@reactor-models/lingbot-world-2";
|
|
902
|
+
|
|
903
|
+
// Inside a React component wrapped by <LingbotWorld2Provider>:
|
|
904
|
+
useLingbotWorld2GenerationReset((msg) => {
|
|
905
|
+
console.log("generation_reset", msg.reason);
|
|
906
|
+
});
|
|
907
|
+
```
|
|
908
|
+
|
|
909
|
+
### `generation_paused`
|
|
910
|
+
|
|
911
|
+
Emitted in response to [`pause`](#pause), once the current chunk finishes.
|
|
912
|
+
|
|
913
|
+
Listener: `onGenerationPaused` · React hook: `useLingbotWorld2GenerationPaused`
|
|
914
|
+
|
|
915
|
+
| Field | Type | Description |
|
|
916
|
+
|---|---|---|
|
|
917
|
+
| `chunk_index` | `number` | Index of the last completed chunk before pausing. |
|
|
918
|
+
|
|
919
|
+
#### JavaScript
|
|
920
|
+
|
|
921
|
+
```typescript
|
|
922
|
+
import { LingbotWorld2Model } from "@reactor-models/lingbot-world-2";
|
|
923
|
+
|
|
924
|
+
const lingbotWorld2 = new LingbotWorld2Model();
|
|
925
|
+
lingbotWorld2.onGenerationPaused((msg) => {
|
|
926
|
+
console.log("generation_paused", msg.chunk_index);
|
|
927
|
+
});
|
|
928
|
+
await lingbotWorld2.connect(jwt);
|
|
929
|
+
```
|
|
930
|
+
|
|
931
|
+
#### React
|
|
932
|
+
|
|
933
|
+
```tsx
|
|
934
|
+
import { useLingbotWorld2GenerationPaused } from "@reactor-models/lingbot-world-2";
|
|
935
|
+
|
|
936
|
+
// Inside a React component wrapped by <LingbotWorld2Provider>:
|
|
937
|
+
useLingbotWorld2GenerationPaused((msg) => {
|
|
938
|
+
console.log("generation_paused", msg.chunk_index);
|
|
939
|
+
});
|
|
940
|
+
```
|
|
941
|
+
|
|
942
|
+
### `generation_resumed`
|
|
943
|
+
|
|
944
|
+
Emitted in response to [`resume`](#resume) when leaving the paused state.
|
|
945
|
+
|
|
946
|
+
Listener: `onGenerationResumed` · React hook: `useLingbotWorld2GenerationResumed`
|
|
947
|
+
|
|
948
|
+
| Field | Type | Description |
|
|
949
|
+
|---|---|---|
|
|
950
|
+
| `chunk_index` | `number` | Index of the last completed chunk before resuming. |
|
|
951
|
+
|
|
952
|
+
#### JavaScript
|
|
953
|
+
|
|
954
|
+
```typescript
|
|
955
|
+
import { LingbotWorld2Model } from "@reactor-models/lingbot-world-2";
|
|
956
|
+
|
|
957
|
+
const lingbotWorld2 = new LingbotWorld2Model();
|
|
958
|
+
lingbotWorld2.onGenerationResumed((msg) => {
|
|
959
|
+
console.log("generation_resumed", msg.chunk_index);
|
|
960
|
+
});
|
|
961
|
+
await lingbotWorld2.connect(jwt);
|
|
962
|
+
```
|
|
963
|
+
|
|
964
|
+
#### React
|
|
965
|
+
|
|
966
|
+
```tsx
|
|
967
|
+
import { useLingbotWorld2GenerationResumed } from "@reactor-models/lingbot-world-2";
|
|
968
|
+
|
|
969
|
+
// Inside a React component wrapped by <LingbotWorld2Provider>:
|
|
970
|
+
useLingbotWorld2GenerationResumed((msg) => {
|
|
971
|
+
console.log("generation_resumed", msg.chunk_index);
|
|
972
|
+
});
|
|
973
|
+
```
|
|
974
|
+
|
|
975
|
+
### `generation_started`
|
|
976
|
+
|
|
977
|
+
Emitted once when [`start`](#start) succeeds and frames begin streaming.
|
|
978
|
+
|
|
979
|
+
Listener: `onGenerationStarted` · React hook: `useLingbotWorld2GenerationStarted`
|
|
980
|
+
|
|
981
|
+
| Field | Type | Description |
|
|
982
|
+
|---|---|---|
|
|
983
|
+
| `prompt` | `string` | The prompt active at the start of generation. |
|
|
984
|
+
| `chunk_num` | `number` | Total number of chunks the run will produce before [`generation_complete`](#generation_complete) fires. |
|
|
985
|
+
| `frame_num` | `number` | Total number of pixel frames the run will emit on `main_video` before [`generation_complete`](#generation_complete). |
|
|
986
|
+
|
|
987
|
+
#### JavaScript
|
|
988
|
+
|
|
989
|
+
```typescript
|
|
990
|
+
import { LingbotWorld2Model } from "@reactor-models/lingbot-world-2";
|
|
991
|
+
|
|
992
|
+
const lingbotWorld2 = new LingbotWorld2Model();
|
|
993
|
+
lingbotWorld2.onGenerationStarted((msg) => {
|
|
994
|
+
console.log(
|
|
995
|
+
"generation_started",
|
|
996
|
+
msg.prompt,
|
|
997
|
+
msg.chunk_num,
|
|
998
|
+
msg.frame_num,
|
|
999
|
+
);
|
|
1000
|
+
});
|
|
1001
|
+
await lingbotWorld2.connect(jwt);
|
|
1002
|
+
```
|
|
1003
|
+
|
|
1004
|
+
#### React
|
|
1005
|
+
|
|
1006
|
+
```tsx
|
|
1007
|
+
import { useLingbotWorld2GenerationStarted } from "@reactor-models/lingbot-world-2";
|
|
1008
|
+
|
|
1009
|
+
// Inside a React component wrapped by <LingbotWorld2Provider>:
|
|
1010
|
+
useLingbotWorld2GenerationStarted((msg) => {
|
|
1011
|
+
console.log(
|
|
1012
|
+
"generation_started",
|
|
1013
|
+
msg.prompt,
|
|
1014
|
+
msg.chunk_num,
|
|
1015
|
+
msg.frame_num,
|
|
1016
|
+
);
|
|
1017
|
+
});
|
|
1018
|
+
```
|
|
1019
|
+
|
|
1020
|
+
### `generation_complete`
|
|
1021
|
+
|
|
1022
|
+
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`](#reset) to stop.
|
|
1023
|
+
|
|
1024
|
+
Listener: `onGenerationComplete` · React hook: `useLingbotWorld2GenerationComplete`
|
|
1025
|
+
|
|
1026
|
+
| Field | Type | Description |
|
|
1027
|
+
|---|---|---|
|
|
1028
|
+
| `total_chunks` | `number` | Total number of chunks produced by the run. |
|
|
1029
|
+
|
|
1030
|
+
#### JavaScript
|
|
1031
|
+
|
|
1032
|
+
```typescript
|
|
1033
|
+
import { LingbotWorld2Model } from "@reactor-models/lingbot-world-2";
|
|
1034
|
+
|
|
1035
|
+
const lingbotWorld2 = new LingbotWorld2Model();
|
|
1036
|
+
lingbotWorld2.onGenerationComplete((msg) => {
|
|
1037
|
+
console.log("generation_complete", msg.total_chunks);
|
|
1038
|
+
});
|
|
1039
|
+
await lingbotWorld2.connect(jwt);
|
|
1040
|
+
```
|
|
1041
|
+
|
|
1042
|
+
#### React
|
|
1043
|
+
|
|
1044
|
+
```tsx
|
|
1045
|
+
import { useLingbotWorld2GenerationComplete } from "@reactor-models/lingbot-world-2";
|
|
1046
|
+
|
|
1047
|
+
// Inside a React component wrapped by <LingbotWorld2Provider>:
|
|
1048
|
+
useLingbotWorld2GenerationComplete((msg) => {
|
|
1049
|
+
console.log("generation_complete", msg.total_chunks);
|
|
1050
|
+
});
|
|
1051
|
+
```
|
|
1052
|
+
|
|
1053
|
+
## Tracks
|
|
1054
|
+
|
|
1055
|
+
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.
|
|
1056
|
+
|
|
1057
|
+
### `main_video`
|
|
1058
|
+
|
|
1059
|
+
A video channel you subscribe to — the model publishes this for your app to render.
|
|
1060
|
+
|
|
1061
|
+
#### JavaScript
|
|
1062
|
+
|
|
1063
|
+
```typescript
|
|
1064
|
+
import { LingbotWorld2Model } from "@reactor-models/lingbot-world-2";
|
|
1065
|
+
|
|
1066
|
+
const lingbotWorld2 = new LingbotWorld2Model();
|
|
1067
|
+
lingbotWorld2.onMainVideo((track, stream) => {
|
|
1068
|
+
// attach to a <video> element, pipe to a canvas, etc.
|
|
1069
|
+
videoEl.srcObject = stream;
|
|
1070
|
+
});
|
|
1071
|
+
await lingbotWorld2.connect(jwt);
|
|
1072
|
+
```
|
|
1073
|
+
|
|
1074
|
+
#### React
|
|
1075
|
+
|
|
1076
|
+
```tsx
|
|
1077
|
+
"use client";
|
|
1078
|
+
import { LingbotWorld2MainVideoView } from "@reactor-models/lingbot-world-2";
|
|
1079
|
+
|
|
1080
|
+
// Inside a component wrapped by <LingbotWorld2Provider>:
|
|
1081
|
+
export function Example() {
|
|
1082
|
+
return <LingbotWorld2MainVideoView className="w-full aspect-video" />;
|
|
1083
|
+
}
|
|
1084
|
+
```
|