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

# Playgrounds

> A widget canvas bound to a session: the interactive face of a workflow.

export const Scope = ({type, href}) => {
  const scopes = {
    workflow: ['the ', 'Workflow', ' blob type', '/blob-types/introduction#workflow'],
    scheduler: ['the ', 'Scheduler', ' blob type', '/blob-types/scheduler/overview'],
    onnx: ['the ', 'ONNX Model', ' blob type', '/blob-types/introduction#onnx'],
    worker: ['', 'blobhub-worker', ', which runs on your machines', '/worker/introduction']
  };
  const scope = scopes[type];
  if (!scope) {
    return <p>Unknown scope: {type}</p>;
  }
  return <p className="text-sm text-gray-600 dark:text-gray-400">
      Provided by {scope[0]}<strong>{scope[1]}</strong>{scope[2]}. · <a href={href || scope[3]}>Reference</a>
    </p>;
};

export const Shot = ({src, alt, caption}) => <Frame caption={caption}>
    <img className="block dark:hidden" src={src} alt={alt} />
    <img className="hidden dark:block" src={src.replace(/\.(png|svg)$/, '.dark.$1')} alt={alt} />
  </Frame>;

<Scope type="workflow" href="/blob-types/workflow/playgrounds/definition-format" />

A playground is a canvas of widgets that shows a session's objects and lets a person act on them. It is stored the
way a workflow definition is, as a definition of the playground category, so anyone who opens it sees the same
layout. You use it against one session at a time, picked from its session menu.

Being a definition, a playground is versioned with its revision, and a new revision carries it forward. A revision
holds several playgrounds, each with its own alias, up to the `workflow.playgrounds_per_revision`
[limit](/general/limits#workflow).

## Layouts

A playground's layout is chosen when it is created and never changes:

* **Free form** places each widget at pixel coordinates on a canvas you pan around, sized by its own width and
  height.
* **Grid** places widgets on a fixed number of columns, positioned and sized in grid units. Its row height follows
  one of three modes: a fixed pixel pitch that scrolls, a scale that fits every occupied row on the screen, or a
  fixed number of rows that fills the screen so each widget keeps its share at any resolution. The mode can be
  changed later; the columns and the pixel pitch cannot.

The demo's `triage-review` playground below is a grid of two widgets, and its sibling `triage-desk` lays two threads
side by side in free form. [Definition Format](/blob-types/workflow/playgrounds/definition-format) has both shapes.

<Shot src="/general/images/playgrounds/grid.png" alt="The triage-review playground in grid layout: a thread and a message widget, each bound to a session object" caption="A playground binds widgets to one session's objects." />

## Widgets

The palette groups widgets into families the way the workflow palette groups components, and the platform's widget
registry is the list of what exists:

* **Data:** `widget.message` and `widget.messages` show a single message or a list of them; `widget.thread` shows a
  [thread](/general/threads-and-objects#threads) as a conversation and posts to it from its composer;
  `widget.graph` lays out a [graph object](/general/threads-and-objects#graphs) and follows its changes;
  `widget.html` renders a standalone HTML document, carried in a message object, in an isolated frame on an origin
  apart from the app's, and a port decides whether its scripts run.
* **Controls:** `widget.chat` takes typed input and starts a run with it.
* **Financial:** `widget.tradingview` draws a market chart from the bars in a message object.
* **Apps:** Mission Control, `app.missions.control`, the widget the [Missions](/general/apps) app is built on.

A display widget binds to a session object through a port that holds the object's alias: a thread widget's port
names a thread object, such as `inbox/thread`, and a graph widget's names a graph. Other ports set how it renders.
[Widgets](/blob-types/workflow/playgrounds/widgets) has each widget's ports.

## Staying current

When a playground opens on a session, it lists the session's objects, which gives it their aliases, sizes and times
but no values, and loads a value only when a widget asks for it. A widget that changes an object loads it fresh
first, because an upload replaces the whole value.

While sync is on, the playground polls the session's event log. A widget showing an object that changed refreshes
on its own; an object nobody is showing is marked as changed and fetched the next time something asks for it. It is
the same event log any client can page through, not a channel of the playground's own.

Sync switches on when you send a chat message or turn on the **Sync** switch. A widget with work in progress also
switches it on and holds it there: the chat widget while the run it started is going, and Mission Control while a
mission has cells the orchestrator is still moving or a request not yet picked up. Once nothing holds it, sync stops
three minutes later, even while objects keep changing. Turning the switch off stops it, whatever holds it.

## Running from a playground

The chat widget starts a new execution in the playground's session each time you send, against the definition its
port names, with what you typed as the run's input. A bare alias in that port names a definition in the
playground's own revision. The path form, `org/blob/revision/definition`, names one in another workflow you can
read, which still runs in your session under the rules of your session's blob, as any run by
[reference](/general/workflows#workflow-references) does.

The run writes into the session's objects as it goes, posting to a thread or writing a message, and the widgets
bound to them show the result while sync runs. Nothing about this is reserved to the playground. The debugger and
any API call reach the same session, its runs and its objects, and `blobhub workflow execute` and the SDK's
`Workflow` module start runs in it.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.