JobFrame platform.job-frame@1
Generated at from
openvibe-contracts v0.86.0 and
openvibe-sdk v0.26.0.
- Version
- 1.0.0
- Owner
- network
- Visibility
- public
- Status
- active
- Compatibility
- backward
- Decision
- ADR-034
- Schema
https://openvibe.network/contracts/platform/job-frame.v1.json
platform.job-frame@1: one job lifecycle frame on the device control link (plan T14 Run; ADR-034 proposed). The link is OpenVibe.Node's WebSocket to OpenVibe.Bot (Node docs/protocol.md section 2); Fabric may terminate it later. Each frame is one JSON object in one text message, with the link's envelope at the top level: `v` (1), `seq` (per-direction counter from 1 on each connection), `ts` (sender's clock, Unix ms) and `type`. Server to device: `job`, `job_cancel`, `job_exit_ack`. Device to server: `job_started`, `job_stdout`, `job_usage`, `job_exit`. The link's existing `ack`/`nack` frames, keyed by the job id, accept or refuse a `job`; a worker that runs jobs advertises its classes in `status.capabilities`. A running `function` job is metered per wall-clock second into platform.usage-sample@1 readings: see `job_usage` and `job_exit`.
Fields
This schema has no named fields.
Examples
From the contract's own test fixtures: valid ones validate, rejected ones must fail.
Valid: job-cancel
{
"v": 1,
"seq": 8,
"ts": 1790935201150,
"type": "job_cancel",
"id": "job_01JAB2C3D4E5F6G7H8J9K0MNPQ"
}Valid: job-exit-ack
{
"v": 1,
"seq": 9,
"ts": 1790935202650,
"type": "job_exit_ack",
"id": "job_01JAB2C3D4E5F6G7H8J9K0MNPQ"
}Valid: job-exit-never-started
{
"v": 1,
"seq": 9,
"ts": 1790935260250,
"type": "job_exit",
"id": "job_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"reason": "ttl",
"code": null,
"result": null,
"usage": {
"wall_ms": 0
}
}Valid: job-exit
{
"v": 1,
"seq": 15,
"ts": 1790935202600,
"type": "job_exit",
"id": "job_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"reason": "exited",
"code": 0,
"result": {
"url": "media:object-7"
},
"usage": {
"started_ms": 1790935200250,
"wall_ms": 2350,
"cpu_ms": 1800,
"mem_peak_bytes": 41943040
}
}Valid: job-started
{
"v": 1,
"seq": 11,
"ts": 1790935200255,
"type": "job_started",
"id": "job_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"started_ms": 1790935200250
}Valid: job-stdout
{
"v": 1,
"seq": 13,
"ts": 1790935201350,
"type": "job_stdout",
"id": "job_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"chunk_seq": 1,
"chunk": "resized 1 of 1\n"
}Valid: job-usage
{
"v": 1,
"seq": 12,
"ts": 1790935201250,
"type": "job_usage",
"id": "job_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"started_ms": 1790935200250,
"second": 0,
"cpu_ms": 640
}Valid: job
{
"v": 1,
"seq": 7,
"ts": 1790935200000,
"type": "job",
"job": {
"id": "job_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"class": "function",
"artifact": {
"name": "thumbnail",
"version": "1.2.0"
},
"args": {
"width": 320
},
"ttl_ms": 60000,
"limits": {
"wall_ms": 30000,
"cpu_ms": 30000,
"mem_bytes": 268435456
}
}
}Rejected: envelope-v2
{
"v": 2,
"seq": 8,
"ts": 1790935200250,
"type": "job_cancel",
"id": "job_01JAB2C3D4E5F6G7H8J9K0MNPQ"
}Rejected: exit-ran-without-started-ms
{
"v": 1,
"seq": 15,
"ts": 1790935202600,
"type": "job_exit",
"id": "job_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"reason": "exited",
"code": 0,
"result": null,
"usage": {
"wall_ms": 2350
}
}Rejected: exit-unknown-reason
{
"v": 1,
"seq": 15,
"ts": 1790935202600,
"type": "job_exit",
"id": "job_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"reason": "oom",
"code": null,
"result": null,
"usage": {
"started_ms": 1790935200250,
"wall_ms": 2350
}
}Rejected: stdout-without-chunk-seq
{
"v": 1,
"seq": 13,
"ts": 1790935201350,
"type": "job_stdout",
"id": "job_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"chunk": "x"
}Rejected: unknown-type
{
"v": 1,
"seq": 15,
"ts": 1790935200250,
"type": "job_pause",
"id": "job_01JAB2C3D4E5F6G7H8J9K0MNPQ"
}Rejected: usage-partial-second
{
"v": 1,
"seq": 12,
"ts": 1790935201250,
"type": "job_usage",
"id": "job_01JAB2C3D4E5F6G7H8J9K0MNPQ",
"started_ms": 1790935200250,
"second": 2,
"quantity": 0.35
}Validate
const contracts = require('openvibe-contracts');
contracts.validate('platform.job-frame@1', value); // { valid, errors: [{ path, message }] }