ZibinDong's picture
Publish audited ActionCodec2 release files
1bfc3f0 verified
Raw History Blame
4.98 kB
from __future__ import annotations
import json
from pathlib import Path
from typing import Any
from .preprocessing import PreprocessingSpec
MANIFEST_NAME = "manifest.json"
SUPPORTED_FORMAT = 1
_USER_TO_STORAGE = {"2bin": "binary", "11bin": "eleven", "21bin": "twenty"}
_GRIPPER_LIMIT = {"2bin": 0.5, "11bin": 0.05, "21bin": 0.025}
_GRIPPER_BINS = {"2bin": 2, "11bin": 11, "21bin": 21}
_GRIPPER_COMPONENT = "gripper_open_command"
def normalize_gripper_mode(token: str) -> str:
"""Map user-facing and legacy gripper-mode tokens onto ``2bin``/``11bin``/``21bin``."""
token = str(token).strip().lower()
if token in _USER_TO_STORAGE:
return token
legacy = {v: k for k, v in _USER_TO_STORAGE.items()}
if token in legacy:
return legacy[token]
raise ValueError(
f"unknown gripper_mode {token!r}; expected one of "
f"{sorted(_USER_TO_STORAGE)} (legacy tokens accepted)"
)
def read_manifest(package: str | Path) -> dict[str, Any]:
path = Path(package)
manifest_path = path / MANIFEST_NAME
if not manifest_path.is_file():
raise FileNotFoundError(
f"{path} is not a release package: missing {MANIFEST_NAME}; "
"expected a release directory containing manifest.json"
)
manifest = json.loads(manifest_path.read_text(encoding="utf-8"))
fmt = manifest.get("format")
if type(fmt) is not int or not 1 <= fmt <= SUPPORTED_FORMAT:
raise ValueError(f"unsupported manifest format {fmt!r} in {manifest_path}")
return manifest
def release_tokenizer(manifest: dict[str, Any]) -> str:
"""Tokenizer family of a release; manifests before ActionCodec2Sparse omit it."""
return manifest.get("tokenizer", "actioncodec2")
def selected_variants(
package: str | Path, *, gripper_mode: str, order: int, tokenizer: str = "actioncodec2"
):
"""Select one vocabulary per available physical profile from a release."""
if type(order) is not int or order not in (1, 2):
raise ValueError("primitive_order must be 1 or 2")
mode = normalize_gripper_mode(gripper_mode)
manifest = read_manifest(package)
found = release_tokenizer(manifest)
if found != tokenizer:
frontend = {"actioncodec2": "ActionCodec2", "actioncodec2_sparse": "ActionCodec2Sparse"}
raise ValueError(
f"{package} is an {found!r} release; load it with {frontend.get(found, found)}"
)
selected = {}
for variant in manifest["variants"]:
if variant["order"] != order or variant["gripper_mode"] != mode:
continue
profile = variant["profile"]
if profile not in {"joint", "eef"} or profile in selected:
raise ValueError(f"invalid or duplicate release profile {profile!r}")
selected[profile] = variant
if not selected:
raise ValueError(f"{package} has no release variants for {mode}/order{order}")
return manifest, mode, selected
def check_gripper_consistency(
entry: Path,
processor,
preprocessing: PreprocessingSpec,
mode: str,
) -> None:
expected_token = _USER_TO_STORAGE[mode]
if preprocessing.gripper_mode != expected_token:
raise ValueError(
f"{entry}: preprocessing.json gripper_mode "
f"{preprocessing.gripper_mode!r} does not match requested {mode!r}"
)
component = processor.config.physical.components.get(_GRIPPER_COMPONENT)
if component is None:
return
limit = component.distortion_limit
limit = float(limit[0]) if isinstance(limit, (list, tuple)) else float(limit)
if abs(limit - _GRIPPER_LIMIT[mode]) > 1e-9:
raise ValueError(
f"{entry}: gripper distortion_limit {limit} does not match "
f"{mode} ({_GRIPPER_LIMIT[mode]})"
)
if processor.bins[-1] != _GRIPPER_BINS[mode]:
raise ValueError(
f"{entry}: last primitive bin count {processor.bins[-1]} "
f"does not match {mode} ({_GRIPPER_BINS[mode]})"
)
def check_release_gates(entry: Path) -> None:
validation_path = entry / "validation.json"
derived_path = entry / "derived_report.json"
if validation_path.is_file():
report = json.loads(validation_path.read_text(encoding="utf-8"))
additive = [x for x in report["additive_within_limit"] if x is not None]
ok = (
report["primitive_zero_exact"]
and report["set_bpe_cell_roundtrip_exact"]
and all(additive)
and report["passed"]
)
if not ok:
raise ValueError(f"{entry}: recorded validation gates failed")
elif derived_path.is_file():
report = json.loads(derived_path.read_text(encoding="utf-8"))
if report["additive_within_limit_segments"] != report["segments"]:
raise ValueError(f"{entry}: derived probe gates failed")
else:
raise FileNotFoundError(f"{entry}: no validation.json or derived_report.json")