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
| Field | Type | Required | Description | Constraints |
|---|---|---|---|---|
ok | boolean | yes | ||
layout | one of | yes | The validated layout when ok is true; null when it is false. | |
summary | string | yes | One sentence saying what changed, or what could not be done. |
|
reasons | array of string | yes | Why this arrangement, or the validator's reasons for refusing one. |
|
receipt | object | Which model answered: the same receipt every AI run carries, at the task's own shape. |
| |
receipt.model | string | yes |
| |
receipt.provider | string |
| ||
receipt.route | string |
| ||
receipt.run_id | string |
| ||
receipt.cost_usd | number |
|
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 }] }