REFERENCE
SDK Demos
How to use @asgard-js/core and @asgard-js/react, with demos you can try on the page.
Sandbox Cold-start HUD
When the agent needs a sandbox to continue, the backend emits sandbox.launch /
sandbox.ready on the stream. Core folds them into sandboxPhase, and the SDK floats
a self-contained "launching" HUD into the chat view's bottom-right, playing a short
ready beat before it fades out.
This is automatic — consumers wire nothing.
The 1s Threshold
A warm sandbox is often ready in 100–300ms. Flashing an animation then is just noise, so the phase must stay
launchingpast the threshold (1000ms by default) before the HUD shows; anything finishing inside it stays completely silent.Conversely, the HUD does not vanish the instant ready arrives: it lingers for a ready beat (900ms by default) so the user sees "done", then fades out. If ready beat the threshold (the HUD never showed), the whole thing stays quiet.
phase: idle ──► launching ─────────────────► ready ──► idle
│◄── 1000ms ──►│
stage: hidden hidden launching ready ──► leaving ──► hidden
(animation) (beat) (fade)sandboxPhasetype SandboxPhase = "idle" | "launching" | "ready";Available from
Channelas either a subscription or a snapshot:channel.sandboxPhase$.subscribe((phase) => { /* … */ });
const phase = channel.getSandboxPhase();Drawing Your Own Launch Cue
To replace the built-in HUD,
useSandboxLaunchmaps the phase onto a display stage:import { useSandboxLaunch } from "@asgard-js/react";
const { stage, visible } = useSandboxLaunch(phase, {
thresholdMs: 1000, // launches finishing sooner never show
readyBeatMs: 900, // how long "ready" lingers before the exit begins
exitMs: 600, // fade-out duration; must match your CSS
});
// stage: 'hidden' | 'launching' | 'ready' | 'leaving'
// visible: convenience flag for stage !== 'hidden'Every timer is cleaned up on unmount or phase change.
Independent From the Run Indicator
The connection line at the footer seam (
RunningIndicator) binds the whole run's connection; the HUD tracks only "is the sandbox stuck cold-starting". They can appear together and never interfere.The Launched-Sandbox List
launchedSandboxes$carries each sandbox's identity and capabilities:interface LaunchedSandbox {
sandboxName: string; // authoritative key; every fs / browser API locates by it
sandboxBlueprintName: string; // the blueprint that created it — usually more readable
workingDirectory: string; // the File Explorer tree root
editorServerEnabled: boolean;
browserEnabled: boolean; // gates the browser-handoff card
}It does not share a source withsandboxPhasesandboxPhaseis folded straight from the SSE events;launchedSandboxes$is not. This list's sole authority isGET /channel/metadata— SSE events never write into it directly.asgard.sandbox.launchis only a hint: it records the name as pending and triggers one metadata refetch, and whatever comes back decides who is live.So never infer "which sandboxes exist right now" from the
sandbox.launchevents yourself — that diverges from the backend's authoritative state.The File Explorer's sandbox dropdown is fed by this list.
See Also
- sandbox:// Handoff Cards — hand the user off to a sandbox browser or file
- File Explorer — browse and edit files inside a sandbox