UiLayoutSuggestion ui.layout-suggestion@1

Generated at from openvibe-contracts v0.419.0 and openvibe-sdk v0.161.0.

Version
1.0.0
Owner
contracts
Visibility
public
Status
active
Compatibility
backward
Schema
https://openvibe.network/contracts/ui/layout-suggestion.v1.json

ui.layout-suggestion@1: OpenVibe.AI's answer to ui.layout.suggest. ok true carries the layout, already checked by openvibe-sdk/ui-layout against the catalog sent with the request, and a one-sentence summary of what changed plus the model's reasons. ok false is an honest refusal: no layout, one sentence saying what it could not do, and the validator's reasons in plain words (for example "Stop has to stay visible."). A receipt names the model that answered, with the run and the route. The suggestion is previewed, never applied silently; Network or the product stores it only after the person accepts it.

Fields

FieldTypeRequiredDescriptionConstraints
okbooleanyes
layoutone ofyesThe validated layout when ok is true; null when it is false.
summarystringyesOne sentence saying what changed, or what could not be done.
  • minLength 1
  • maxLength 300
reasonsarray of stringyesWhy this arrangement, or the validator's reasons for refusing one.
  • maxItems 20
  • items: minLength 1
  • items: maxLength 300
receiptobjectWhich model answered: the same receipt every AI run carries, at the task's own shape.
  • no other fields
receipt.modelstringyes
  • minLength 1
  • maxLength 200
receipt.providerstring
  • minLength 1
  • maxLength 100
receipt.routestring
  • minLength 1
  • maxLength 200
receipt.run_idstring
  • minLength 1
  • maxLength 80
receipt.cost_usdnumber
  • minimum 0

Examples

From the contract's own test fixtures: valid ones validate, rejected ones must fail.

Valid: couldnt
{
  "ok": false,
  "layout": null,
  "summary": "Couldn't do that: Stop has to stay visible.",
  "reasons": [
    "Stop has to stay visible.",
    "Every pressed part has to be at least 44 px."
  ],
  "receipt": {
    "model": "deepseek-flash",
    "provider": "deepseek",
    "route": "ui.layout.suggest",
    "run_id": "run_01JAB2C3D4E5F6G7H8J9K0MNPR"
  }
}
Valid: suggestion
{
  "ok": true,
  "layout": {
    "surface": "bot.controls",
    "surface_version": 1,
    "device": "phone",
    "name": "One-thumb controls",
    "author": {
      "name": "Ana"
    },
    "sharing": "private",
    "parts": [
      {
        "id": "stop",
        "visible": true,
        "place": {
          "x": 0,
          "y": 0,
          "w": 4,
          "h": 2
        },
        "style": {
          "tint": "danger",
          "shape": "round",
          "opacity": 1,
          "label": true
        },
        "bindings": {
          "keys": [
            "Space"
          ],
          "gamepad": [
            "south"
          ]
        }
      },
      {
        "id": "stick",
        "visible": true,
        "place": {
          "x": 0,
          "y": 2,
          "w": 4,
          "h": 3
        },
        "style": {
          "tint": "surface",
          "shape": "round",
          "opacity": 1,
          "label": false
        },
        "bindings": {
          "keys": [
            "W",
            "A",
            "S",
            "D"
          ],
          "gamepad": [
            "left-stick"
          ]
        }
      }
    ]
  },
  "summary": "Put Stop across the top and the drive stick below it where a thumb reaches.",
  "reasons": [
    "Stop had to stay visible, so it became the top row.",
    "The stick moved under the thumb."
  ],
  "receipt": {
    "model": "deepseek-flash",
    "provider": "deepseek",
    "route": "ui.layout.suggest",
    "run_id": "run_01JAB2C3D4E5F6G7H8J9K0MNPQ",
    "cost_usd": 0.0004
  }
}
Rejected: ok-false-with-layout
{
  "ok": false,
  "layout": {
    "surface": "bot.controls",
    "surface_version": 1,
    "device": "phone",
    "name": "Still here",
    "author": {
      "name": "Ana"
    },
    "sharing": "private",
    "parts": [
      {
        "id": "stop",
        "visible": true,
        "place": {
          "x": 0,
          "y": 0,
          "w": 2,
          "h": 2
        },
        "style": {
          "tint": "danger",
          "shape": "round",
          "opacity": 1,
          "label": true
        },
        "bindings": {
          "keys": [],
          "gamepad": []
        }
      }
    ]
  },
  "summary": "Couldn't do that.",
  "reasons": [
    "Stop has to stay visible."
  ]
}
Rejected: ok-true-without-layout
{
  "ok": true,
  "layout": null,
  "summary": "Put Stop on the left.",
  "reasons": []
}

Validate

const contracts = require('openvibe-contracts');
contracts.validate('ui.layout-suggestion@1', value);   // { valid, errors: [{ path, message }] }