React

This tutorial shows how to integrate the Gamilab Browser SDK into a React application. Try the live demo below, then read through the walkthrough.

Live demo

Flow overview

The SDK requires a strict sequence of calls:

  1. Initialize -- listen for gami:init to get the singleton
  2. Connect -- open the WebSocket with gami.connect()
  3. Select portal -- activate a portal with gami.use_portal(id, token)
  4. Create thread -- start a session with gami.create_thread()
  5. Record -- capture audio with gami.toggle_recording()
  6. Extract -- call gami.extract() after pausing to run extraction

Each step must complete before the next is available.

Initialization

The SDK is loaded via a <script> tag and emits a gami:init event on window when ready. Wrap it in a useEffect to get the singleton:

useEffect(() => {
    function on_init(evt) {
        set_gami(evt.detail.Gami());
    }
    window.addEventListener("gami:init", on_init);
    return () => {
        window.removeEventListener("gami:init", on_init);
    };
}, []);

Event subscriptions

The SDK uses gami.on(event, callback) which returns a ref for cleanup with gami.off(ref). This maps directly to useEffect:

useEffect(() => {
    if (gami === null) return;
    const ref = gami.on("audio", (data) => {
        set_audio(data);
    });
    return () => gami.off(ref);
}, [gami]);

The key events are:

  • audio -- recording state (idle, recording, paused)
  • text_history -- finalized transcription
  • text_current -- in-progress transcription segment
  • extraction_status -- idle or running
  • struct_current -- extracted structured data matching the portal schema

Portal and model

use_portal accepts either positional or object arguments:

await gami.use_portal(portal_id, token);
await gami.use_portal({ portal_id, token });

After selecting a portal, get_model() returns the extraction schema. The schema is a recursive tree of fields with type (string, number, boolean, object, array), form_config (label, hint, widget), and nested fields or item for compound types.

Recording and extraction

toggle_recording() starts or pauses audio capture. When pausing, call extract() to trigger structured data extraction from the transcription:

const was_recording = gami.is_recording();
await gami.toggle_recording();
if (was_recording) {
    await gami.extract();
}

extract() returns a promise that resolves when extraction completes. The result is delivered via the struct_current event.

Full source

Download the full source