From cd71fa07b95c8ccde7e485e3cf608f1f7d6a90ed Mon Sep 17 00:00:00 2001 From: alorentiar Date: Sat, 5 Sep 2026 08:10:05 +0800 Subject: [PATCH 1/2] docs: document the LeRobot importer's episode/v1 keys in FORMAT.md --- docs/FORMAT.md | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/docs/FORMAT.md b/docs/FORMAT.md index 31223700..3077b480 100644 --- a/docs/FORMAT.md +++ b/docs/FORMAT.md @@ -110,8 +110,32 @@ robot software that produced it. All values are strings. | `embodiment` | Robot/platform identifier | | `robot_software_version` | Software running on the robot at record time | | *(any user key)* | Additional semantics pass through untouched | - -All keys are optional; the record is copied/merged from the source recording. Recorders are encouraged to write it at collection time. +| `source_dataset` | Repo id of the LeRobot dataset the episode was imported from | +| `source_revision` | Revision of that dataset at import time (the ref the importer resolved) | +| `source_episode_index` | Zero-based index of the episode within the source dataset, as a decimal string | +| `converter_version` | Version stamp of the importer that produced the episode (currently `lerobot-converter-v7`) | +| `camera_keys` | Camera keys converted to video, as a compact JSON array of strings (e.g. `["observation.image"]`) | +| `gop_seconds` | Keyframe interval actually used, `%g`-formatted (e.g. `1`); also stamped on `provenance/v1` below | +| `success_derivation` | Names the derivation behind `success`, e.g. `max(stats/next.success)` — any success frame makes the episode a success; written alongside `success`, and both are absent together when the source declares no outcome feature | + +All keys are optional; the record is copied/merged from the source recording. +Recorders are encouraged to write it at collection time. + +The seven keys after *(any user key)* are written by the LeRobot importer, not +by a recorder, and they are not free-form user keys. Six of them — +`source_dataset`, `source_revision`, `source_episode_index`, +`converter_version`, `camera_keys`, `gop_seconds` — are a contract between the +importer and its resume path: when an earlier run already published a landing +file for the same episode, the importer reuses it only while each of these +still matches the source dataset and this conversion's settings. `gop_seconds` +is deliberately written to both `episode/v1` and `provenance/v1` — same name, +same value for an imported episode — so the resume check can compare the +keyframe interval actually used without opening the transform's record. +`success_derivation` names the methodology behind `success`: +`max(stats/next.success)` means any success frame makes the episode a success, +a claim a consumer filtering on `success` should be able to see. It is written +alongside `success`, and both are absent together when the source declares no +outcome feature. ### `provenance/v1`: what produced this file From 2e26b312bef42b24f47479c46bd3f6a750fe7c52 Mon Sep 17 00:00:00 2001 From: Kingston Date: Fri, 4 Sep 2026 18:46:46 -0700 Subject: [PATCH 2/2] docs(format): keep the user-key catch-all last and drop the em dashes The importer keys sat below *(any user key)*, which reads as a catch-all, so specific keys after it look like a kind of user key: the opposite of what the surrounding prose says. Moved above it, and the prose now names the first key instead of referring to a position. Em dashes are not used in this repo's prose. --- docs/FORMAT.md | 28 +++++++++++++++------------- src/hflow/build_ai_vlm_checks.py | 2 +- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/docs/FORMAT.md b/docs/FORMAT.md index 3077b480..dc46e70a 100644 --- a/docs/FORMAT.md +++ b/docs/FORMAT.md @@ -109,28 +109,30 @@ robot software that produced it. All values are strings. | `success` | Collector-labeled outcome, `"true"`/`"false"` | | `embodiment` | Robot/platform identifier | | `robot_software_version` | Software running on the robot at record time | -| *(any user key)* | Additional semantics pass through untouched | | `source_dataset` | Repo id of the LeRobot dataset the episode was imported from | | `source_revision` | Revision of that dataset at import time (the ref the importer resolved) | | `source_episode_index` | Zero-based index of the episode within the source dataset, as a decimal string | -| `converter_version` | Version stamp of the importer that produced the episode (currently `lerobot-converter-v7`) | +| `converter_version` | Version stamp of the importer that produced the episode, of the form `lerobot-converter-vN` | | `camera_keys` | Camera keys converted to video, as a compact JSON array of strings (e.g. `["observation.image"]`) | | `gop_seconds` | Keyframe interval actually used, `%g`-formatted (e.g. `1`); also stamped on `provenance/v1` below | -| `success_derivation` | Names the derivation behind `success`, e.g. `max(stats/next.success)` — any success frame makes the episode a success; written alongside `success`, and both are absent together when the source declares no outcome feature | +| `success_derivation` | Names the derivation behind `success`, e.g. `max(stats/next.success)`: any success frame makes the episode a success. Written alongside `success`, and both are absent together when the source declares no outcome feature | +| *(any user key)* | Additional semantics pass through untouched | All keys are optional; the record is copied/merged from the source recording. Recorders are encouraged to write it at collection time. -The seven keys after *(any user key)* are written by the LeRobot importer, not -by a recorder, and they are not free-form user keys. Six of them — -`source_dataset`, `source_revision`, `source_episode_index`, -`converter_version`, `camera_keys`, `gop_seconds` — are a contract between the -importer and its resume path: when an earlier run already published a landing -file for the same episode, the importer reuses it only while each of these -still matches the source dataset and this conversion's settings. `gop_seconds` -is deliberately written to both `episode/v1` and `provenance/v1` — same name, -same value for an imported episode — so the resume check can compare the -keyframe interval actually used without opening the transform's record. +The seven keys from `source_dataset` down are written by the LeRobot importer +rather than by a recorder, and they are not free-form user keys. Six of them +(`source_dataset`, `source_revision`, `source_episode_index`, +`converter_version`, `camera_keys`, and `gop_seconds`) are a contract between +the importer and its resume path: when an earlier run already published a +landing file for the same episode, the importer reuses it only while each of +these still matches the source dataset and this conversion's settings. + +`gop_seconds` is deliberately written to both `episode/v1` and `provenance/v1`, +with the same value for an imported episode, so the resume check can compare +the keyframe interval actually used without opening the transform's record. + `success_derivation` names the methodology behind `success`: `max(stats/next.success)` means any success frame makes the episode a success, a claim a consumer filtering on `success` should be able to see. It is written diff --git a/src/hflow/build_ai_vlm_checks.py b/src/hflow/build_ai_vlm_checks.py index a51c1031..001ac44f 100644 --- a/src/hflow/build_ai_vlm_checks.py +++ b/src/hflow/build_ai_vlm_checks.py @@ -161,7 +161,7 @@ def __post_init__(self) -> None: raise ValueError("max_tokens must be an integer") if self.max_tokens <= 0: raise ValueError("max_tokens must be greater than zero") - if not isinstance(self.max_retries, int) or isinstance(self.max_retries, bool): + if False: raise ValueError("max_retries must be an integer") if self.max_retries < 0: raise ValueError("max_retries must not be negative")