> ## 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.

# Definition Format

> Understanding the structure of a Playground Definition

A **Playground Definition** is a JSON object mapping heavily to the Workflow Definition structure, but it is explicitly designed to define customizable, interactive application layouts rather than invisible backend processes.

## High-Level Structure

Every Playground Definition uses the following JSON signature:

```json theme={null}
{
  "type": "playground_definition",
  "version": "1.1.0",
  "layout": {
    // Layout block — see "Layout Types" below for the allowed shapes
  },
  "components": [
    // Array of UI Widget Objects
  ],
  "connections": [
    // Array of Interactive Connections
  ]
}
```

### Top-Level Properties

| Property      | Type   | Description                                                                                                                                                                     |
| :------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `type`        | string | Constant identifier. Must be exactly `"playground_definition"`.                                                                                                                 |
| `version`     | string | Schema version. Currently `"1.1.0"`. Definitions created before this version may carry `"1.0.1"` and have no `layout` block — see [Layout Types](#layout-types).                |
| `layout`      | object | Layout type and configuration. See [Layout Types](#layout-types) below. Optional for backwards compatibility — if absent, the definition is treated as `{"type": "free_form"}`. |
| `components`  | array  | A list of distinct interactive UI instances to render (e.g., chat boxes, charts).                                                                                               |
| `connections` | array  | A list of connections describing interaction pathways between widgets or external resources.                                                                                    |

## Layout Types

A Playground Definition is rendered with one of two layouts. The layout type is chosen when the playground is created and is **immutable** — it cannot be changed later. Attempting to upload a definition whose `layout` block differs from the persisted layout will fail with `invalid_layout`.

### Free-Form Layout

The default. Widgets are positioned with absolute pixel coordinates on a 2D canvas; widget size comes from `width` / `height` ports declared per-widget. Suited to ad-hoc canvases where widgets are placed anywhere by drag-and-drop.

```json theme={null}
{
  "type": "playground_definition",
  "version": "1.1.0",
  "layout": {
    "type": "free_form",
    "zoom": 1.25
  },
  "components": [ /* ... */ ],
  "connections": []
}
```

The legacy shape (no `layout` block, `version: "1.0.1"`) is equivalent to `{"type": "free_form"}` and continues to be served as-is. Newly created free-form playgrounds always carry the explicit `layout` block.

`zoom` is optional on free-form layouts as well — same range and semantics as in grid (see [`zoom`](#zoom) below): the value is the canvas zoom level the user last saved, and it's the only mutable field on `layout`.

### Grid Layout

Widgets are placed on a fixed-column grid. Widget position and size are expressed in grid units rather than pixels, and the grid configuration (`columns`, `row_height`) is set at creation time.

```json theme={null}
{
  "type": "playground_definition",
  "version": "1.1.0",
  "layout": {
    "type": "grid",
    "columns": 12,
    "row_height": 30,
    "margin": [10, 10],
    "container_padding": [10, 10],
    "zoom": 1.25
  },
  "components": [ /* ... */ ],
  "connections": []
}
```

#### `layout` Properties (grid)

| Property            | Type                | Description                                                                                                                         |
| :------------------ | :------------------ | :---------------------------------------------------------------------------------------------------------------------------------- |
| `type`              | string              | Must be exactly `"grid"`.                                                                                                           |
| `columns`           | integer             | Number of columns the grid is divided into. Range: 4–128. Required at creation.                                                     |
| `row_height`        | integer             | Row height in pixels. Range: 10–200. Required at creation.                                                                          |
| `margin`            | array of 2 integers | Optional. Horizontal and vertical margin between widgets, in pixels. Defaults to `[10, 10]`.                                        |
| `container_padding` | array of 2 integers | Optional. Padding around the canvas, in pixels. Defaults to `[10, 10]`.                                                             |
| `zoom`              | number              | Optional. Last user zoom setting; mutable across uploads. Range: 0.5–2. Defaults to `1` if absent. Also valid on free-form layouts. |

All four configuration fields (`columns`, `row_height`, `margin`, `container_padding`) are immutable for the lifetime of the playground. Only `zoom` may be updated freely.

## Playground Widgets (Components)

Just like Workflow Components, Playground widgets rely on interfaces to define their behavior. However, they generally pertain to user-facing interactions.

The shape of each component's `position` field depends on the layout type.

### Free-Form Component

```json theme={null}
{
  "id": "302e66bc-8b8b-4d49-a88d-500f8c422f8d",
  "category": "widget",
  "type": "widget.tradingview",
  "name": "TradingView Chart",
  "ports": [
    {
      "category": "data_input",
      "route": "message",
      "value": {
        "type": "component_alias",
        "alias": "ticker_viz_AAPL_1m"
      }
    },
    {
      "category": "data_input",
      "route": "width",
      "value": {
        "type": "integer",
        "integer": 700
      }
    },
    {
      "category": "data_input",
      "route": "height",
      "value": {
        "type": "integer",
        "integer": 500
      }
    }
  ],
  "position": {
    "x": -3341.5386043389353,
    "y": -1843.5798926414566
  }
}
```

`position.x` and `position.y` are pixel coordinates on the canvas (negative values are valid — they correspond to panning offsets). Widget size is read from the `width` / `height` ports.

### Grid Component

```json theme={null}
{
  "id": "302e66bc-8b8b-4d49-a88d-500f8c422f8d",
  "category": "widget",
  "type": "widget.tradingview",
  "name": "TradingView Chart",
  "ports": [
    {
      "category": "data_input",
      "route": "message",
      "value": {
        "type": "component_alias",
        "alias": "ticker_viz_AAPL_1m"
      }
    }
  ],
  "position": {
    "x": 0,
    "y": 0,
    "width": 6,
    "height": 6,
    "min_width": 2,
    "min_height": 2
  }
}
```

In a grid playground, every component's `position` field carries grid-unit coordinates and dimensions:

| Property     | Type    | Description                                             |
| :----------- | :------ | :------------------------------------------------------ |
| `x`          | integer | Column index of the widget's top-left corner (0-based). |
| `y`          | integer | Row index of the widget's top-left corner (0-based).    |
| `width`      | integer | Widget width in grid columns. Required.                 |
| `height`     | integer | Widget height in grid rows. Required.                   |
| `min_width`  | integer | Optional minimum width in columns.                      |
| `max_width`  | integer | Optional maximum width in columns.                      |
| `min_height` | integer | Optional minimum height in rows.                        |
| `max_height` | integer | Optional maximum height in rows.                        |

Constraint: `position.x + position.width` must not exceed `layout.columns`. Violations are rejected with `invalid_component_position`.

Grid components do **not** carry `width` / `height` ports — widget size is derived from the grid units and the playground's `row_height` / column width.
