> ## Documentation Index
> Fetch the complete documentation index at: https://docs.reactor.inc/llms.txt
> Use this file to discover all available pages before exploring further.

# Helios schema reference

> The complete Helios command and event schema, with end-to-end examples.

This page documents the complete Helios wire surface: every command you send with
`reactor.sendCommand()`, the events the model emits back, and two end-to-end examples. For the
conceptual model and a quick start, see the [overview](/model-api-reference/helios/overview).

## Commands

Send commands to the model using `reactor.sendCommand()`. Below are all available commands:

| Command              | Description                                                                    |
| -------------------- | ------------------------------------------------------------------------------ |
| `set_prompt`         | Set the prompt (at chunk 0, or current chunk if running)                       |
| `schedule_prompt`    | Schedule a prompt at a specific chunk index                                    |
| `set_image`          | Set or change a reference image (works mid-generation)                         |
| `set_conditioning`   | Set prompt and reference image together atomically (avoids a first-chunk race) |
| `set_image_strength` | Adjust how strongly the reference image anchors output (0.0–1.0)               |
| `set_sr_scale`       | Set super-resolution scale: `"off"`, `"2x"`, or `"4x"`                         |
| `set_seed`           | Set a seed for reproducible output. Same seed = same video                     |
| `start`              | Begin video generation                                                         |
| `pause`              | Pause generation                                                               |
| `resume`             | Resume generation                                                              |
| `reset`              | Reset to initial state                                                         |

<Tabs>
  <Tab title="set_prompt">
    ### set\_prompt

    Convenience wrapper around `schedule_prompt` that automatically picks the right chunk index so
    you don't have to track it yourself:

    * **Not started**: schedules at chunk 0.
    * **Paused**: schedules at the current chunk (takes effect on resume).
    * **Running**: schedules at the next chunk (current chunk is already being processed).

    The easiest way to change the prompt. Call `set_prompt` and the model figures out when to
    apply it.

    **Parameters:**

    | Parameter | Type   | Required | Description                           |
    | --------- | ------ | -------- | ------------------------------------- |
    | `prompt`  | string | Yes      | The prompt text to use for generation |

    **Example:**

    <CodeGroup>
      ```typescript JavaScript theme={"theme":{"light":"github-light","dark":"github-dark-high-contrast"}}
      // Set initial prompt (before starting)
      await reactor.sendCommand("set_prompt", {
        prompt: "A serene mountain landscape at sunrise",
      });

      // Change prompt mid-generation. Automatically applies at the next chunk
      await reactor.sendCommand("set_prompt", {
        prompt: "The landscape transitions to a stormy ocean",
      });
      ```

      ```tsx React theme={"theme":{"light":"github-light","dark":"github-dark-high-contrast"}}
      const { setPrompt } = useHelios();

      // Set initial prompt (before starting)
      await setPrompt({ prompt: "A serene mountain landscape at sunrise" });

      // Change prompt mid-generation. Automatically applies at the next chunk
      await setPrompt({ prompt: "The landscape transitions to a stormy ocean" });
      ```

      ```python Python theme={"theme":{"light":"github-light","dark":"github-dark-high-contrast"}}
      # Set initial prompt (before starting)
      await reactor.send_command("set_prompt", {
          "prompt": "A serene mountain landscape at sunrise",
      })

      # Change prompt mid-generation. Automatically applies at the next chunk
      await reactor.send_command("set_prompt", {
          "prompt": "The landscape transitions to a stormy ocean",
      })
      ```
    </CodeGroup>
  </Tab>

  <Tab title="schedule_prompt">
    ### schedule\_prompt

    Schedule a prompt to be applied at a specific chunk index during video generation.

    **Parameters:**

    | Parameter | Type    | Required | Description                                  |
    | --------- | ------- | -------- | -------------------------------------------- |
    | `prompt`  | string  | Yes      | The prompt text to use                       |
    | `chunk`   | integer | Yes      | The chunk index at which to apply the prompt |

    **Behavior:**

    * Scheduling a prompt at a chunk that already has a prompt will overwrite it.
    * Prompts scheduled in the past are rejected (e.g. if the model is at chunk 10 and you
      schedule at chunk 5, an error is emitted).
    * A prompt must exist at chunk 0 before calling `start`.
    * Prompts can be scheduled while generation is running for real-time control.

    **Example:**

    <CodeGroup>
      ```typescript JavaScript theme={"theme":{"light":"github-light","dark":"github-dark-high-contrast"}}
      // Schedule initial prompt (required before start)
      await reactor.sendCommand("schedule_prompt", {
        prompt: "A serene mountain landscape at sunrise",
        chunk: 0,
      });

      // Schedule a transition at chunk 10
      await reactor.sendCommand("schedule_prompt", {
        prompt: "The mountain transforms into a futuristic city",
        chunk: 10,
      });
      ```

      ```tsx React theme={"theme":{"light":"github-light","dark":"github-dark-high-contrast"}}
      const { schedulePrompt } = useHelios();

      // Schedule initial prompt (required before start)
      await schedulePrompt({
        prompt: "A serene mountain landscape at sunrise",
        chunk: 0,
      });

      // Schedule a transition at chunk 10
      await schedulePrompt({
        prompt: "The mountain transforms into a futuristic city",
        chunk: 10,
      });
      ```

      ```python Python theme={"theme":{"light":"github-light","dark":"github-dark-high-contrast"}}
      # Schedule initial prompt (required before start)
      await reactor.send_command("schedule_prompt", {
          "prompt": "A serene mountain landscape at sunrise",
          "chunk": 0,
      })

      # Schedule a transition at chunk 10
      await reactor.send_command("schedule_prompt", {
          "prompt": "The mountain transforms into a futuristic city",
          "chunk": 10,
      })
      ```
    </CodeGroup>
  </Tab>

  <Tab title="set_image">
    ### set\_image

    Set or change the reference image for image-to-video conditioning. Can be called before or
    during generation.

    Upload the image first with `uploadFile()`, then pass the returned
    [`FileRef`](/sdk-reference/types#fileref) as the `image` parameter. See
    [File Uploads](/concepts/file-uploads) for more details.

    **Parameters:**

    | Parameter | Type    | Required | Description                                                  |
    | --------- | ------- | -------- | ------------------------------------------------------------ |
    | `image`   | FileRef | Yes      | A reference to an uploaded image, returned by `uploadFile()` |

    **Behavior:**

    * Can be set before starting or while generation is running.
    * The image is rescaled to the model's internal conditioning resolution, which is smaller than
      the output frame size. The `image_accepted` message reports the exact dimensions used.
    * Swapping the image mid-generation is an immediate switch on the next chunk; the previous
      image's history conditioning is not blended out.

    **Example:**

    <CodeGroup>
      ```typescript JavaScript theme={"theme":{"light":"github-light","dark":"github-dark-high-contrast"}}
      const ref = await reactor.uploadFile(imageFile);
      await reactor.sendCommand("set_image", { image: ref });

      // Swap mid-generation
      const newRef = await reactor.uploadFile(newImageFile);
      await reactor.sendCommand("set_image", { image: newRef });
      ```

      ```tsx React theme={"theme":{"light":"github-light","dark":"github-dark-high-contrast"}}
      const { uploadFile, setImage } = useHelios();

      const ref = await uploadFile(imageFile);
      await setImage({ image: ref });

      // Swap mid-generation
      const newRef = await uploadFile(newImageFile);
      await setImage({ image: newRef });
      ```

      ```python Python theme={"theme":{"light":"github-light","dark":"github-dark-high-contrast"}}
      ref = await reactor.upload_file(image_file)
      await reactor.send_command("set_image", {"image": ref})

      # Swap mid-generation
      new_ref = await reactor.upload_file(new_image_file)
      await reactor.send_command("set_image", {"image": new_ref})
      ```
    </CodeGroup>
  </Tab>

  <Tab title="set_conditioning">
    ### set\_conditioning

    Set the prompt and reference image in a single atomic message (Helios SDK 0.9.0+). Use it when
    both are known at once (e.g. launching a curated scene): the two ride one data-channel message,
    so the first chunk is generated with the image already in place. Sending `set_image` and
    `set_prompt` separately before `start` races, and the image can land a chunk late.

    Upload the image first with `uploadFile()`, then pass the returned
    [`FileRef`](/sdk-reference/types#fileref) as `image`. See [`set_image`](#set_image) for upload
    details.

    **Parameters:**

    | Parameter | Type    | Required | Description                                |
    | --------- | ------- | -------- | ------------------------------------------ |
    | `prompt`  | string  | Yes      | The prompt to generate from                |
    | `image`   | FileRef | Yes      | Reference image returned by `uploadFile()` |

    **Example:**

    <CodeGroup>
      ```typescript JavaScript theme={"theme":{"light":"github-light","dark":"github-dark-high-contrast"}}
      const ref = await reactor.uploadFile(imageFile);
      await reactor.sendCommand("set_conditioning", {
        prompt: "A cinematic slow zoom into the scene, golden hour lighting",
        image: ref,
      });
      await reactor.sendCommand("start", {});
      ```

      ```tsx React theme={"theme":{"light":"github-light","dark":"github-dark-high-contrast"}}
      const { uploadFile, setConditioning, start } = useHelios();

      const ref = await uploadFile(imageFile);
      await setConditioning({
        prompt: "A cinematic slow zoom into the scene, golden hour lighting",
        image: ref,
      });
      await start();
      ```

      ```python Python theme={"theme":{"light":"github-light","dark":"github-dark-high-contrast"}}
      ref = await reactor.upload_file(image_file)
      await reactor.send_command("set_conditioning", {
          "prompt": "A cinematic slow zoom into the scene, golden hour lighting",
          "image": ref,
      })
      await reactor.send_command("start", {})
      ```
    </CodeGroup>
  </Tab>

  <Tab title="set_image_strength">
    ### set\_image\_strength

    Adjust how strongly the reference image anchors generation. Ignored when no reference image is
    set.

    **Parameters:**

    | Parameter        | Type   | Required | Description                  |
    | ---------------- | ------ | -------- | ---------------------------- |
    | `image_strength` | number | Yes      | Anchor strength, `0.0`–`1.0` |

    **Behavior:**

    * The current chunk loop snapshots `image_strength` together with the reference image. A new
      value sent on its own is stored but is not applied until the reference image is next set
      (via `set_image` or `set_conditioning`), or until generation is restarted with `reset` +
      `start`.
    * Set `image_strength` immediately before `set_image` / `set_conditioning` if you want it to
      take effect on the next chunk.

    **Example:**

    <CodeGroup>
      ```typescript JavaScript theme={"theme":{"light":"github-light","dark":"github-dark-high-contrast"}}
      await reactor.sendCommand("set_image_strength", { image_strength: 0.6 });
      ```

      ```tsx React theme={"theme":{"light":"github-light","dark":"github-dark-high-contrast"}}
      const { setImageStrength } = useHelios();

      await setImageStrength({ image_strength: 0.6 });
      ```

      ```python Python theme={"theme":{"light":"github-light","dark":"github-dark-high-contrast"}}
      await reactor.send_command("set_image_strength", {"image_strength": 0.6})
      ```
    </CodeGroup>
  </Tab>

  <Tab title="set_sr_scale">
    ### set\_sr\_scale

    Set the super-resolution factor applied to each emitted frame. Takes effect on the next chunk.

    **Parameters:**

    | Parameter  | Type   | Required | Description                       |
    | ---------- | ------ | -------- | --------------------------------- |
    | `sr_scale` | string | Yes      | One of `"off"`, `"2x"`, or `"4x"` |

    **Example:**

    <CodeGroup>
      ```typescript JavaScript theme={"theme":{"light":"github-light","dark":"github-dark-high-contrast"}}
      await reactor.sendCommand("set_sr_scale", { sr_scale: "2x" });
      ```

      ```tsx React theme={"theme":{"light":"github-light","dark":"github-dark-high-contrast"}}
      const { setSrScale } = useHelios();

      await setSrScale({ sr_scale: "2x" });
      ```

      ```python Python theme={"theme":{"light":"github-light","dark":"github-dark-high-contrast"}}
      await reactor.send_command("set_sr_scale", {"sr_scale": "2x"})
      ```
    </CodeGroup>
  </Tab>

  <Tab title="set_seed">
    ### set\_seed

    Set a seed for reproducible output. Using the same seed with the same prompts will produce the
    same video.

    **Parameters:**

    | Parameter | Type    | Required | Description |
    | --------- | ------- | -------- | ----------- |
    | `seed`    | integer | Yes      | Seed value  |

    **Behavior:**

    * If generation hasn't started, the seed takes effect immediately.
    * If generation is running, the seed takes effect on the next `reset`.

    **Example:**

    <CodeGroup>
      ```typescript JavaScript theme={"theme":{"light":"github-light","dark":"github-dark-high-contrast"}}
      await reactor.sendCommand("set_seed", { seed: 42 });
      ```

      ```tsx React theme={"theme":{"light":"github-light","dark":"github-dark-high-contrast"}}
      const { setSeed } = useHelios();

      await setSeed({ seed: 42 });
      ```

      ```python Python theme={"theme":{"light":"github-light","dark":"github-dark-high-contrast"}}
      await reactor.send_command("set_seed", {"seed": 42})
      ```
    </CodeGroup>
  </Tab>

  <Tab title="start">
    ### start

    Begin the video generation process.

    **Parameters:** None.

    **Requirements:**

    * A prompt must be scheduled at chunk 0 before calling this command (via `set_prompt` or
      `schedule_prompt`).

    **Example:**

    <CodeGroup>
      ```typescript JavaScript theme={"theme":{"light":"github-light","dark":"github-dark-high-contrast"}}
      await reactor.sendCommand("start", {});
      ```

      ```tsx React theme={"theme":{"light":"github-light","dark":"github-dark-high-contrast"}}
      const { start } = useHelios();

      await start();
      ```

      ```python Python theme={"theme":{"light":"github-light","dark":"github-dark-high-contrast"}}
      await reactor.send_command("start", {})
      ```
    </CodeGroup>
  </Tab>

  <Tab title="pause">
    ### pause

    Pause the video generation after the current chunk finishes processing. The model retains its
    full state including history buffers.

    **Parameters:** None.

    **Example:**

    <CodeGroup>
      ```typescript JavaScript theme={"theme":{"light":"github-light","dark":"github-dark-high-contrast"}}
      await reactor.sendCommand("pause", {});
      ```

      ```tsx React theme={"theme":{"light":"github-light","dark":"github-dark-high-contrast"}}
      const { pause } = useHelios();

      await pause();
      ```

      ```python Python theme={"theme":{"light":"github-light","dark":"github-dark-high-contrast"}}
      await reactor.send_command("pause", {})
      ```
    </CodeGroup>
  </Tab>

  <Tab title="resume">
    ### resume

    Resume video generation from where it was paused.

    **Parameters:** None.

    **Example:**

    <CodeGroup>
      ```typescript JavaScript theme={"theme":{"light":"github-light","dark":"github-dark-high-contrast"}}
      await reactor.sendCommand("resume", {});
      ```

      ```tsx React theme={"theme":{"light":"github-light","dark":"github-dark-high-contrast"}}
      const { resume } = useHelios();

      await resume();
      ```

      ```python Python theme={"theme":{"light":"github-light","dark":"github-dark-high-contrast"}}
      await reactor.send_command("resume", {})
      ```
    </CodeGroup>
  </Tab>

  <Tab title="reset">
    ### reset

    Stop generation and reset the model to its initial state.

    **Parameters:** None.

    **Effects:**

    * Halts any ongoing generation.
    * Clears all scheduled prompts, history buffers, and the active reference image.
    * Returns the model to a clean state ready for new prompts. The currently configured seed is
      preserved; call `set_seed` after `reset` if you want to change it.

    **Example:**

    <CodeGroup>
      ```typescript JavaScript theme={"theme":{"light":"github-light","dark":"github-dark-high-contrast"}}
      await reactor.sendCommand("reset", {});
      ```

      ```tsx React theme={"theme":{"light":"github-light","dark":"github-dark-high-contrast"}}
      const { reset } = useHelios();

      await reset();
      ```

      ```python Python theme={"theme":{"light":"github-light","dark":"github-dark-high-contrast"}}
      await reactor.send_command("reset", {})
      ```
    </CodeGroup>
  </Tab>
</Tabs>

## Messages from model

Listen for messages with `reactor.on("message", ...)` (imperative) or the `useReactorMessage()`
hook (React). Every message is delivered as JSON `{ "type": "<name>", "data": { … } }`.

| Message              | When                                                   | Payload                                                            |
| -------------------- | ------------------------------------------------------ | ------------------------------------------------------------------ |
| `state`              | On connect, after every command, and after every chunk | Full session snapshot (see below)                                  |
| `prompt_accepted`    | After `set_prompt`                                     | `{ prompt: string }`                                               |
| `image_accepted`     | After `set_image` decodes                              | `{ width: int, height: int }`                                      |
| `conditions_ready`   | After `set_prompt` or `set_image`                      | `{ has_prompt: bool, has_image: bool }`                            |
| `generation_started` | After `start`                                          | `{ prompt: string, chunk_index: int }`                             |
| `chunk_complete`     | After each chunk emits                                 | `{ chunk_index: int, frames_emitted: int, active_prompt: string }` |
| `generation_paused`  | After `pause`                                          | `{ chunk_index: int }`                                             |
| `generation_resumed` | After `resume`                                         | `{ chunk_index: int }`                                             |
| `command_error`      | When a command is rejected                             | `{ command: string, reason: string }`                              |

### `state` payload

`state` is the single source of truth for driving UI. Subscribe once and treat it as the
authoritative session snapshot; you generally do not need to track the individual messages above
yourself.

| Field               | Type             | Meaning                                                                                                                                                        |
| ------------------- | ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `running`           | `bool`           | `started && !paused`. Equivalent to "frames are actively streaming".                                                                                           |
| `started`           | `bool`           | True once `start` has been accepted; stays true through pauses. Cleared by `reset`.                                                                            |
| `paused`            | `bool`           | True while generation is paused via `pause`.                                                                                                                   |
| `image_set`         | `bool`           | True once a reference image has been set this session. Cleared only by `reset`.                                                                                |
| `current_chunk`     | `int`            | Zero-based index of the chunk currently being generated. `0` before the first chunk and after `reset`.                                                         |
| `current_frame`     | `int`            | Running total of frames emitted on `main_video` since the last `reset`.                                                                                        |
| `current_prompt`    | `string \| null` | The prompt currently driving generation, or `null` if none set. Stays `null` for the first state message after `start`, until the first chunk begins emitting. |
| `image_strength`    | `number`         | Current `image_strength` (0.0–1.0). Ignored when no reference image is set.                                                                                    |
| `scheduled_prompts` | `object`         | Pending scheduled prompts, keyed by the chunk index at which they take effect.                                                                                 |

**Example handler:**

<CodeGroup>
  ```typescript JavaScript theme={"theme":{"light":"github-light","dark":"github-dark-high-contrast"}}
  reactor.on("message", (msg) => {
    switch (msg.type) {
      case "state":
        console.log(`Chunk ${msg.data.current_chunk} · frame ${msg.data.current_frame}`);
        console.log(`Running: ${msg.data.running} · prompt: ${msg.data.current_prompt}`);
        break;
      case "image_accepted":
        console.log(`Reference image set: ${msg.data.width}x${msg.data.height}`);
        break;
      case "generation_started":
        console.log(`Generation started: ${msg.data.prompt}`);
        break;
      case "command_error":
        console.error(`${msg.data.command} rejected: ${msg.data.reason}`);
        break;
    }
  });
  ```

  ```tsx React theme={"theme":{"light":"github-light","dark":"github-dark-high-contrast"}}
  import {
    useHeliosState,
    useHeliosImageAccepted,
    useHeliosGenerationStarted,
    useHeliosCommandError,
    type HeliosStateMessage,
  } from "@reactor-models/helios";

  function StateDisplay() {
    const [snapshot, setSnapshot] = useState<HeliosStateMessage | null>(null);

    // `state` fires on connect, after every command, and after every chunk.
    useHeliosState((msg) => setSnapshot(msg));
    useHeliosImageAccepted((msg) => console.log(`Reference image set: ${msg.width}x${msg.height}`));
    useHeliosGenerationStarted((msg) => console.log(`Generation started: ${msg.prompt}`));
    useHeliosCommandError((msg) => console.error(`${msg.command} rejected: ${msg.reason}`));

    if (!snapshot) return null;

    return (
      <div>
        Running: {snapshot.running ? "Yes" : "No"} | Chunk: {snapshot.current_chunk} | Frame:{" "}
        {snapshot.current_frame}
      </div>
    );
  }
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"github-dark-high-contrast"}}
  @reactor.on_message
  def handle(msg):
      data = msg["data"]
      if msg["type"] == "state":
          print(f"Chunk {data['current_chunk']} · frame {data['current_frame']}")
          print(f"Running: {data['running']} · prompt: {data['current_prompt']}")
      elif msg["type"] == "image_accepted":
          print(f"Reference image set: {data['width']}x{data['height']}")
      elif msg["type"] == "generation_started":
          print(f"Generation started: {data['prompt']}")
      elif msg["type"] == "command_error":
          print(f"{data['command']} rejected: {data['reason']}")
  ```
</CodeGroup>

## Complete example: prompt sequence

<CodeGroup>
  ```typescript JavaScript theme={"theme":{"light":"github-light","dark":"github-dark-high-contrast"}}
  import { Reactor } from "@reactor-team/js-sdk";

  const reactor = new Reactor({
    modelName: "helios",
  });

  // Set up video display
  const videoElement = document.getElementById("video") as HTMLVideoElement;
  reactor.on("trackReceived", (name, track, stream) => {
    videoElement.srcObject = stream;
    videoElement.play().catch(console.warn);
  });

  // Listen for state updates
  reactor.on("message", (msg) => {
    if (msg.type === "state") {
      document.getElementById("info")!.textContent =
        `Chunk: ${msg.data.current_chunk} | Frame: ${msg.data.current_frame}`;
    }
    if (msg.type === "chunk_complete") {
      console.log(`Now showing: ${msg.data.active_prompt}`);
    }
  });

  // Connect (see Authentication guide for how to obtain a token)
  await reactor.connect(token);

  // Set a seed for reproducibility
  await reactor.sendCommand("set_seed", { seed: 42 });

  // Schedule prompts for a cinematic sequence
  await reactor.sendCommand("schedule_prompt", {
    prompt: "A peaceful forest at dawn, soft morning light filtering through the trees",
    chunk: 0,
  });

  await reactor.sendCommand("schedule_prompt", {
    prompt: "Sunlight breaking through the canopy, golden rays illuminating the forest floor",
    chunk: 5,
  });

  await reactor.sendCommand("schedule_prompt", {
    prompt: "A deer walking through the misty forest clearing",
    chunk: 10,
  });

  // Start generation
  await reactor.sendCommand("start", {});
  ```

  ```tsx React theme={"theme":{"light":"github-light","dark":"github-dark-high-contrast"}}
  import {
    HeliosProvider,
    HeliosMainVideoView,
    useHelios,
    useHeliosState,
    useHeliosChunkComplete,
  } from "@reactor-models/helios";

  function App({ token }: { token: string }) {
    return (
      <HeliosProvider jwtToken={token}>
        <PromptSequence />
        {/* HeliosMainVideoView handles <video> setup, srcObject, and autoplay. */}
        <HeliosMainVideoView className="h-full w-full" videoObjectFit="contain" />
      </HeliosProvider>
    );
  }

  function PromptSequence() {
    const { status, setSeed, schedulePrompt, start } = useHelios();

    // `state` is the single source of truth for chunk/frame progress.
    useHeliosState((msg) =>
      console.log(`Chunk: ${msg.current_chunk} | Frame: ${msg.current_frame}`),
    );
    useHeliosChunkComplete((msg) => console.log(`Now showing: ${msg.active_prompt}`));

    async function run() {
      // Set a seed for reproducibility
      await setSeed({ seed: 42 });

      // Schedule prompts for a cinematic sequence
      await schedulePrompt({
        prompt: "A peaceful forest at dawn, soft morning light filtering through the trees",
        chunk: 0,
      });
      await schedulePrompt({
        prompt: "Sunlight breaking through the canopy, golden rays illuminating the forest floor",
        chunk: 5,
      });
      await schedulePrompt({
        prompt: "A deer walking through the misty forest clearing",
        chunk: 10,
      });

      // Start generation
      await start();
    }

    return (
      <button disabled={status !== "ready"} onClick={run}>
        Start sequence
      </button>
    );
  }
  ```
</CodeGroup>

## Complete example: image-to-video

Use a reference image to guide generation. Upload the image first, then send it together with the
prompt via `set_conditioning` before starting, so the very first chunk is conditioned on both.

<CodeGroup>
  ```typescript JavaScript theme={"theme":{"light":"github-light","dark":"github-dark-high-contrast"}}
  import { Reactor } from "@reactor-team/js-sdk";

  const reactor = new Reactor({
    modelName: "helios",
  });

  // Set up video display
  const videoElement = document.getElementById("video") as HTMLVideoElement;
  reactor.on("trackReceived", (name, track, stream) => {
    videoElement.srcObject = stream;
    videoElement.play().catch(console.warn);
  });

  // Connect
  await reactor.connect(token);

  // Upload a reference image
  const fileInput = document.getElementById("file") as HTMLInputElement;
  const imageFile = fileInput.files![0];
  const imageRef = await reactor.uploadFile(imageFile);

  // Set the image and prompt atomically. Sending set_image + set_prompt
  // separately before start races: the image can land a chunk late, so the
  // first chunk renders from the prompt alone. set_conditioning commits both
  // in one message. See set_conditioning above.
  await reactor.sendCommand("set_conditioning", {
    image: imageRef,
    prompt: "A cinematic slow zoom into the scene, golden hour lighting, gentle motion",
  });

  // Start generation
  await reactor.sendCommand("start", {});

  // Later: swap to a new image mid-generation
  const newInput = document.getElementById("new-file") as HTMLInputElement;
  const newRef = await reactor.uploadFile(newInput.files![0]);
  await reactor.sendCommand("set_image", { image: newRef });
  ```

  ```tsx React theme={"theme":{"light":"github-light","dark":"github-dark-high-contrast"}}
  import {
    HeliosProvider,
    HeliosMainVideoView,
    useHelios,
  } from "@reactor-models/helios";

  function App({ token }: { token: string }) {
    return (
      <HeliosProvider jwtToken={token}>
        <ImageToVideo />
        <HeliosMainVideoView className="h-full w-full" videoObjectFit="contain" />
      </HeliosProvider>
    );
  }

  function ImageToVideo() {
    const { status, uploadFile, setImage, setConditioning, start } = useHelios();

    async function startFromImage(imageFile: File) {
      const imageRef = await uploadFile(imageFile);

      // Set the image and prompt atomically. Sending set_image + set_prompt
      // separately before start races: the image can land a chunk late, so the
      // first chunk renders from the prompt alone. set_conditioning commits both
      // in one message. See set_conditioning above.
      await setConditioning({
        image: imageRef,
        prompt: "A cinematic slow zoom into the scene, golden hour lighting, gentle motion",
      });

      // Start generation
      await start();
    }

    // Later: swap to a new image mid-generation
    async function swapImage(newImageFile: File) {
      const newRef = await uploadFile(newImageFile);
      await setImage({ image: newRef });
    }

    return (
      <>
        <input
          type="file"
          disabled={status !== "ready"}
          onChange={(e) => e.target.files?.[0] && startFromImage(e.target.files[0])}
        />
        <input
          type="file"
          disabled={status !== "ready"}
          onChange={(e) => e.target.files?.[0] && swapImage(e.target.files[0])}
        />
      </>
    );
  }
  ```
</CodeGroup>
