Tools
Part of the OpenRAL public-symbol inventory. Hand-curated;
(LNN)markers are refreshed bytools/refresh_methods_linenos.py.
tools/lifecycle_autostart.py
Drives a lifecycle node through configure → activate after ros2 launch brings it up. Spawned as an ExecuteProcess per node by packages/openral_rskill_ros/launch/sim_e2e.launch.py (HAL, safety kernel, reasoner).
--transition-timeout-s— per-transition spin budget, default300.0(lifecycle_autostart.py:161). The kernel gets a 120 s literal and the reasoner 300 s; the HAL's is derived per scene byopenral_hal.sim_bringup.hal_transition_timeout_s(sim_e2e.launch.py), not hardcoded. There is still noopenral deploy simflag — raise the scene'sbackend_options.boot_timeout_sinstead and the lifecycle budget follows.- Why the HAL's is derived. The bound covers everything the scene factory does inside
on_configure, including a sidecar's spawn +_wait_for_boot. Those backends carry their own, larger budgets —isaac_sim900 s,behavior1200 s,robotwin600 s (rlbench300 s, and it passes the constant directly sobackend_options.boot_timeout_sis silently ignored) — and all fourscenes/deploy/isaac_*.yamlplusscenes/deploy/behavior_r1pro.yamlsetboot_timeout_s: 1200. Against the old fixed 300 s those five scenes declared a budget the launcher would not honour. Measured (scenes/sim/isaac_franka_bowl_plate.yaml, headless, RTX 4070 Laptop 8 GB): Isaac Sim 5.1 reachesapp readyin 12.6 s, so nominal boot is not the problem. The reachable case is a sidecar that wedges after startup — observed live on this host, whereconnect()waited the client's full 1200 s before raisingdid not answer ping within 1200s. The transition's worst case is therefore the declaredboot_timeout_s, not the nominal boot time. On expiry_drive_transitionraises and the autostart exits non-zero whileon_configurekeeps running, which can leave the HAL parked in INACTIVE with nothing left to drive ACTIVATE and no message naming the cause. Cost of the fix: on those scenes a genuinely wedged HAL now goes unreported for up to ~21 min, which is why the 300 s floor still applies to every scene that does not ask for more.
tools/profile_policy_load.py
One-shot wall-time breakdown of a single policy load. Drives openral_sim.factory.make_policy against an in-tree rSkill manifest and prints a phase-by-phase summary built from every <prefix>_<name>_{start,done} event emitted by openral_rskill._diagnostics.phase_timer. Use when ros2 launch openral_rskill_ros …_e2e.launch.py or openral sim run is slow to first action — answers "where do the seconds go" before changing any code.
Wired as just profile-load <rskill> [args] (Justfile). Measured on an RTX 4070 with rskills/act-so101-pen (warm cache): imports 4.6 s (54%), snapshot 0.3 s, from_pretrained 0.7 s, to_device 0.0 s, 8.5 s end-to-end — the import tax dominates even a small ResNet+transformer policy. Families whose adapter lacks a _<family>_phase helper (xvla, diffusion) report "no phase_timer events captured"; the end-to-end total is still valid.
class _PhaseCapture—structlogprocessor that buffers_start/_doneevents and pairs them by name. Insertion-ordered so the rendered table mirrors the actual load order. (L49)_parse_args(argv) -> argparse.Namespace—--rskill <dir>(required),--device(defaultauto). (L88)_build_env_cfg(rskill_dir, *, device) -> _SimpleEnvCfg— Builds a minimal env_cfg from<rskill_dir>/rskill.yaml; mirrorsrskill_runner_node._SimpleEnvCfg. (L122)_render(pairs, total_s) -> str— Formats the captured pairs asphase / elapsed_s / sharecolumns plus an(unaccounted)row when phase coverage misses >1 s. (L141)main(argv=None) -> int— Late-importsopenral_sim.factory.make_policyso the import cost lands inside the profiled total; reportsHF_HUB_OFFLINEstatus alongside the result.
tools/viz_collision.py
Overlays a robot's kernel collision primitives (the box/capsule geometry the C++ safety kernel checks, lowered by collision_params_from_description) on its real MJCF meshes at any joint pose — the offline way to eyeball whether the SO-101 base OBB (issue #84) hugs the housing and clears the folded distal links without a deploy run. Standalone inspection tool, not a pytest test. Run the venv python with PYTHONPATH=packages/openral_safety.
--viewer— interactive MuJoCo window (MUJOCO_GL=glfw).--screenshot PATH— offscreen PNG (MUJOCO_GL=egl).--rviz— real RViz (spawnsrobot_state_publisherfor RobotModel + TF and publishes the primitives as a latched/collision_markersMarkerArray; needs ROS sourced).--robot <id>(defaultso101_follower),--deg <j...>sets the pose in degrees (manifest joint order). Box = translucent red, capsules = translucent blue (cylinder + end spheres in RViz).
tools/schema_export.py
Generates JSON Schema files for every public openral_core model.
_enum_schema(cls) -> dict[str, Any]— Minimal JSON Schema for astrEnum. (L145)export_schemas(out_dir=_OUT_DIR) -> dict[str, Any]— Export JSON Schema for every public model. (L157)check_drift(out_dir=_OUT_DIR) -> bool— On-disk schemas == regenerated. (L209)
tools/audit_sim_configs.py
Real GPU rollout audit for every YAML under scenes/. Operator-driven (not a pytest test); 1 episode per config; writes outputs/audit_sim_configs.json and prints a Markdown table. See just sim-audit. Two modes: default (full rollout for sim/benchmark, Tier-2 launch + SIGINT for deploy) and --check-compatibility (cheap in-process scene+rSkill+HAL gate, no subprocess / no GPU).
DEFAULT_TIMEOUT_S = 600/DEFAULT_DEPLOY_ALIVE_GRACE_S = 90/DEFAULT_DEPLOY_SHUTDOWN_GRACE_S = 30(L57) — Module-level grace constants overridable via--timeout/--deploy-alive-grace/--deploy-shutdown-grace.RunMode = Literal["sim", "benchmark", "deploy"](L61) — Tier selector on eachConfigSpecrow; drives_run_onevs_run_one_deploydispatch.@dataclass(frozen=True) class ConfigSpec(config, rskill, uv_group, run_mode)(L65) — One row in the audit catalogue.uv_groupis one oflibero / metaworld / robocasa / maniskill3 / simpler-env / sim;run_modeis"sim"/"benchmark"/"deploy";rskillis""for deploy rows (env-only — reasoner picks at runtime). Catalogue holds only pairs that actually exist in the tree — scenes without a matching in-tree rSkill are tracked in the scene YAML itself (and intests/unit/test_examples_sim_configs_load.pyfor schema-load coverage), not as audit rows.CATALOGUE: tuple[ConfigSpec, ...](L99) — Explicit (YAML → rSkill → uv group → run_mode) mapping for every config currently in the tree: 13 sim + 7 benchmark + 4 deploy = 24 rows.@dataclass class AuditRow(config, rskill, status, exit_code, wall_s, peak_vram_mib, tail)(L195) — One result.status∈ {pass,pass-compat,fail-oom,fail-asset,fail-sidecar,fail-timeout,fail-other,fail-compat,skipped-opt-dep,skipped-host-setup}._classify(returncode: int, tail: str) -> str(L250) — Map subprocess result to a status by substring-matching stderr against_OOM_PATTERNS/_ASSET_PATTERNS/_SIDECAR_PATTERNS/_OPT_DEP_PATTERNS/_HOST_SETUP_PATTERNS. Exit 139 (MuJoCo/GL atexit SIGSEGV in gym-aloha) is treated aspasswhen no error patterns appear.class _VramSampler(L289) — Backgroundnvidia-smi --query-gpu=memory.usedpoller, 200 ms cadence;peak_mibreported on.stop(). No-op withoutnvidia-smion$PATH._check_compat(spec: ConfigSpec) -> AuditRow(L334) —--check-compatibilitygate: load scene viaopenral_core.load_scene_strict, validate rSkill manifest (sim/benchmark) or assert robot resolves inopenral_cli.deploy_sim._ROBOT_HAL_REGISTRY(deploy). No subprocess, no GPU. Returnspass-compat/fail-compat._build_run_cmd(spec: ConfigSpec) -> list[str](L431) — Build theuv run … openral <sim|benchmark> …argv for sim/benchmark rows. Refactored out of_run_oneso the deploy path can stay focused on lifecycle teardown._run_one_deploy(spec, *, alive_grace_s, shutdown_grace_s, timeout_s) -> AuditRow(L480) — Tier-2 deploy launch viaopenral deploy sim --config <yaml> --no-dashboard:Popenin its own process group, waitalive_grace_s, send SIGINT to the group, waitshutdown_grace_s, escalate to SIGKILL on timeout. Pass criteria: banner seen in stdout AND returncode in{0, -SIGINT, 130, -SIGTERM}._classify_or_fallback(returncode, tail, spec, wall_s, peak_vram) -> AuditRow(L665) — Deploy-mode wrapper around_classifythat defaults tofail-otherwhen no pattern matches (sim path defaults topass)._run_one(spec: ConfigSpec, timeout_s: int) -> AuditRow(L710) — Tier-3 sim/benchmark rollout via_build_run_cmd(spec)withMUJOCO_GL=eglandOPENRAL_SIM_SEQUENTIAL_INIT=1.main(argv) -> int(L848) — CLI entry; flags--timeout/--deploy-alive-grace/--deploy-shutdown-grace/--check-compatibility/--report. Returns 0 on all-pass, 1 if any config failed, 2 on filter mismatch.
tools/select_tests.py
Selective test execution — maps a git diff to the minimal pytest targets that can observe it. Backs just test-changed / the test-selective workflow. See docs/contributing/selective-testing.md.
class SelectionConfig(BaseModel)(L65) — Typed view oftools/test_selection.toml:full_run_globs,ignore_globs,isolate_globs,extra_triggers.class SelectionResult(BaseModel)(L75) —full_run/full_run_reason/affected_packages/targets/isolated_targets(own-process, issue #24) /reasons(per-target rationale).load_config(path) -> SelectionConfig(L99) — Load + validate the TOML config.package_dir_import_names(repo_root) -> dict[str, str](L111) —python/<dir>→ itssrc/openral_*import name.build_dependency_graph(repo_root) -> dict[str, set[str]](L130) — Import-name → directopenraldeps, derived from eachpyproject.toml(never hand-written).transitive_dependents(graph, changed) -> set[str](L154) — Closure of packages that depend on any changed package (includeschanged).map_test_imports(repo_root) -> dict[str, set[str]](L181) — Each top-leveltests/file → theopenral_*packages it imports.select(repo_root, changed_files, config) -> SelectionResult(L297) — Resolve changed paths to pytest targets (blast-radius → full run; else per-package dirs + import-intersecting tests), peelingisolate_globsmatches intoisolated_targets.changed_files_from_git(base, head, repo_root) -> list[str](L404) — Merge-basegit diff --name-only base...head.main(argv=None) -> int(L444) — CLI;--files/--base/--head,--github-outputfor CI step outputs.
tools/audit_tests.py
Test-suite auditor — flags dead / shadowed / duplicate / no-assertion tests; writes docs/contributing/test-audit.md. Read-only; never deletes. Backs just test-audit.
class TestFuncInfo(BaseModel)(L73) — Onetest_*function:path,qualname(class-scoped),markers,has_assertion,is_trivial,body_hash, …class DuplicateGroup(BaseModel)(L88) — Abody_hashshared by ≥2 functions and theirmembers.class AuditReport(BaseModel)(L93) — Inventory (by_tier/by_marker/by_directory) plustrivial/shadowed/no_assertion/duplicate_groups.collect(repo_root) -> list[TestFuncInfo](L212) — Scope-aware AST walk over every test root (same name in two classes is not conflated).build_report(records) -> AuditReport(L245) — Group into the inventory + finding buckets;shadowed= same(path, qualname)redefined (earlier def is dead).render_markdown(report) -> str(L297) — Render the committed report.main(argv=None) -> int(L384) — CLI;--json/--write-report.
python/observability/src/openral_observability/replay/
Query-time joiner for rosbag2 (mcap) ↔ OTel spans. Backs openral replay + openral record.
bag_reader.py:@dataclass(frozen=True) class BagMessage(topic, log_time_ns, publish_time_ns, trace_id, traceparent, schema_name, payload_summary)(L43) — One mcap record surfaced to the correlator.read_bag(bag_path: str | Path) -> Iterator[BagMessage](L109) — Iterate an.mcapfile or rosbag2 directory; extractstrace_idfromjsonschema-encoded payloads (a packed W3Ctraceparentin thetrace_idfield, OR — for theopenral_msgs/Tickschema — a raw 32-hextrace_id+ raw 16-hexspan_idpair, ISSUE-109) orros2msg-encoded CDR payloads (regex match on the W3Ctraceparentsubstring). Norosbag2_pydep.trace_query.py:class TraceQueryError(RuntimeError)(L17) — Raised on a non-JSON or unreachable dashboard response.@dataclass(frozen=True) class DashboardTraceClient(base_url="http://127.0.0.1:8000", timeout_s=5.0)(L24) —list_traces() -> list[dict]over/api/traces;get_spans(trace_id) -> list[dict]over/api/spans/<id>.correlator.py:@dataclass(frozen=True) class TimelineEntry(kind, ts_ns, trace_id, topic, span_name, attrs, duration_ms)(L26) — One row of the joined timeline;.to_json()returns a plain dict.list_bag_trace_ids(bag_messages) -> list[dict](L67) — Distinct trace_ids in the bag with counts, busiest first.build_timeline(bag_messages, spans, *, trace_id=None) -> list[TimelineEntry](L94) — Pure join. Filters both inputs totrace_id, merges, sorts ascending byts_ns.cli.py:RECORD_PROFILES: dict[str, dict[str, list[str]]](L45) — Slim and full topic + regex presets.build_record_command(*, profile, output_dir, storage="mcap", extra_topics=(), extra_regex=()) -> list[str](L85) — Composeros2 bag recordargv.@dataclass(frozen=True) class ReplayResult(trace_id, bag_trace_ids, timeline, bag_path)(L132) —.to_json()returns a plain dict.run_replay(*, bag_path, trace_id, dashboard_url) -> ReplayResult(L162) — Read a bag, fetch matching spans from the dashboard, return the joined timeline.run_record(*, profile, output_dir, storage="mcap", extra_topics=(), extra_regex=(), dry_run=False) -> tuple[list[str], CompletedProcess | None](L210) — Spawnros2 bag recordin a new process group; forwards SIGINT/SIGTERM received by the parent as SIGINT to the child group so rosbag2 flushesmetadata.yamlcleanly. Waits up to 5 s after the child exits for that file to appear.write_timeline(result: ReplayResult, out_path: Path) -> None(L246) — Persist the timeline JSON.
tools/rskill_publisher.py
Package and publish a local rSkill directory to the HF Hub.
public_visibility_error(manifest, public) -> str | None(L106) — §9 license gate (pure, no network): returns an error string if--publicis requested for a non-commercial-licensed skill (not manifest.is_commercial_use_allowed), elseNone. Letsmainfail fast before any HF call._resolve_token(token_arg) -> str— Prefer CLI arg, fall back to env. (L151)_validate_manifest(skill_dir) -> RSkillManifest(L170)_validate_docs(skill_dir, manifest) -> DocValidationReport— Print + return the README / manifest documentation report via_rskill_doc_validator.validate_rskill_docs. Runs in both dry-run and--publishpaths; the caller decides whether to exit on errors._rewrite_manifest_name(manifest_path, old_name, new_name) -> None— Rewrite the top-levelname:value ofrskill.yamlin place (column-0 line only, so nestedname:keys are untouched; preserves quotes + trailing comment). Exits 1 if the line isn't found exactly once. Backs--fix-name._enforce_repo_name(skill_dir, manifest, *, fix_name) -> RSkillManifest— Enforce the ratified naming grammar viaopenral_core.schemas.repo_name_is_canonical(kind-aware:rskill-playbook-<name>for playbooks,rskill-<model>-<robot>-<task>-<quant>otherwise). No kind is exempt. On a non-canonical name:fix_name=Truerewrites toexpected_repo_name(manifest)+ reloads;fix_name=Falsehard-fails (exit 1) printing the suggested name (exit 1 too if no canonical name can be suggested). Runs in both dry-run and--publishpaths._bump_revision(manifest_path, weights_uri_base, token) -> str— Resolve latest weights commit, patchrskill.yaml. (L376)_ensure_private(api, repo_id) -> None— Abort if the repo is public. (L427)_ensure_public(api, repo_id) -> None— The--publiccounterpart: abort if the (reused) repo is private, so a--publicpublish never lands in a private repo._publish(skill_dir, manifest, token, *, public=False) -> str— Create the HF repo (private unlesspublic) and upload; runs the matching visibility gate (_ensure_public/_ensure_private) aftercreate_repo.main() -> None— Entry point. Sequence: parse args (--publish/--public/--bump-revision/--fix-name/--token) → validate manifest →_enforce_repo_name(exit 1 on a non-compliant VLA name unless--fix-name) → validate task space → validate docs →public_visibility_errorgate (exit 1 if--publicon a non-commercial skill) → exit 1 on doc errors → optional--bump-revision→--publish(private unless--public).
tools/rskill_scaffolder.py
Standalone argparse wrapper around openral_cli._rskill_scaffolder.scaffold_rskill.
Mirrors openral rskill new; exists so power users can scaffold without installing the CLI distribution.
_parse_args(argv) -> argparse.Namespace— argparse setup. (L35)main(argv=None) -> int— Entry point; returns a process exit code. (L77)
tools/generate_rskill_skillmd.py
Generate the standard agent-skill SKILL.md discovery view for every in-tree rSkill from its rskill.yaml.
The single canonical producer of the SKILL.md mirror (CLAUDE.md §1.3): rskill.yaml is authoritative; the generated SKILL.md is discovery-only and never hand-edited. --check fails on any stale/missing SKILL.md, so the same process applies to every kind — including playbook, whose _KIND_NOUN entry renders identically to vla/detector/vlm/reward.
render_skill_md(manifest_path: Path) -> str(L162) — Render theSKILL.mdtext (YAML frontmatter + capability/verb summary + license/provenance) from one manifest;_KIND_NOUNmaps eachkindto its discovery noun.main(argv=None) -> int(L261) — Entry point. No args = regenerate everyrskills/<id>/SKILL.md; positional ids regenerate a subset;--checkreports stale/missing without writing (exit 1 on drift).
tools/rldx_sidecar.py
Boot helper for the RLDX-1 inference sidecar (companion to openral_sim.policies.rldx).
Materialises a Python 3.10 venv under _DEFAULT_HOME (~/.cache/openral/rldx-sidecar, override via --home), clones the upstream RLWRLD/RLDX-1 repo, runs uv sync (rldx + transformers + flash-attn + …) — on aarch64, an override-driven uv pip install instead, see _install_deps_aarch64 — optionally adds bitsandbytes for NF4, then writes a wrapper that monkey-patches transformers.AutoModel.from_pretrained to apply NF4 / int8 to the Qwen3-VL-8B backbone (the MSAT diffusion head is left at bf16) and os.execvpes into rldx.eval.run_rldx_server. Required because the rldx package pins requires-python = "~=3.10" and ships a custom architectures=["RLDX"] class not in HF Transformers.
_install_deps(*, source, uv, quantization) -> Path—uv syncin the cloned source tree (createssource/.venvwith rldx + deps), thenuv pip install --python <venv>/bin/python bitsandbytes>=0.43.0whenquantization in {nf4, int8}. Returns the venv path. Delegates to_install_deps_aarch64on aarch64, where thatuv synccannot succeed. (L141)_install_deps_aarch64(*, source, quantization) -> Path— aarch64 replacement for theuv syncpass: same<source>/.venvand same Python 3.10, provisioned byensure_pip_venv+uv pip install -e <source> --torch-backend=cu128undersidecar_requirements/rldx-aarch64-override.txt(torch 2.9.1 / torchvision 0.24.1;torchcodecandflash-attnmarker-dropped) and the sharedaarch64-nvrtc-override.txt. Second pass addsnvidia-cuda-nvcc-cu12==12.9.86(sm_121ptxas) plusbitsandbytesfor NF4/int8. Sentinel is keyed on both override texts so a corrected pin repairs an existing venv. (L69)_aarch64_extras(quantization) -> list[str]— the packages installed on top of upstream's own dependency set on aarch64; shared between the install pass and the sentinel spec so they cannot drift. (L122)_make_wrapper(*, work, source, args) -> Path— Generate<work>/boot_server.py: monkey-patchesAutoModel.from_pretrainedfor the Qwen3-VL backbone with NF4 / int8 / no-op, setsRLDX_ATTN_IMPL=sdpawhenflash_attnis not importable (upstream's own documented opt-out; a no-op on x86_64, whereuv syncinstalls it), setssys.argv, and calls intorldx.eval.run_rldx_server. (L182)main() -> int— argparse entry point; flags--model,--port,--quantization {none,nf4,int8},--home. Callsrun_sidecar(..., family="rldx", ...), which stamps the sidecar identity record (so the adapter can verify reuse) and thenos.execvpes into the sidecar venv so SIGINT reaches the server. (L355)
tools/xr1_sidecar.py + tools/_xr1_server.py
Boot helper + inference server for Xiaomi Robotics XR-1. The launcher provisions torch 2.9.1 / transformers 4.57.1 / FlashAttention 2.8.3 + bitsandbytes and execs the server (torch is one minor ahead of upstream's 2.8.0, which has no linux-aarch64 cu128 wheel — docs/reference/aarch64-support.md). The server loads the pinned MiBoT custom-code checkpoint in manifest-selected NF4 (or BF16), recreates Xiaomi's benchmark-specific chat template and padded state tensor, decodes actions with the checkpoint processor, and serves ping/reset/get_action/close over the shared ZMQ/msgpack ndarray wire.
- main() -> int (launcher) — parse model/profile/quantization/host/port/home; --export-dir persists an NF4 checkpoint and exits, otherwise stamp sidecar identity and os.execvpe into _xr1_server.py.
- _messages(profile, images, instruction) -> list[dict[str, Any]] — exact RoboCasa, RoboCasa365-video, or VLABench message layout from upstream revision 7c20088.
- _pad_state(state) -> NDArray[np.float32] — pad one frame or a four-frame history to XR-1's 60-D internal state.
- class _XR1Policy — pinned AutoModel/AutoProcessor custom-code loader; bitsandbytes NF4 uses a BF16 compute dtype + CUDA device map, prequantized_nf4 reloads a saved packed checkpoint without re-quantizing, and checkpoint-owned action de-normalization remains unchanged. export_pretrained(output_dir) writes sharded packed safetensors, custom MiBoT code/processor assets, and quantization_metadata.json while explicitly excluding cached BF16 shards.
tools/qwen_vlm_sidecar.py + tools/_qwen_vlm_server.py
Boot helper + server for the Qwen3.5-4B scene-VLM sidecar, companion to openral_runner.backends.gstreamer.qwen_scene_vlm.QwenSceneVlm. The launcher provisions an isolated venv (OPENRAL_QWEN_VLM_SIDECAR_VENV to reuse one) with transformers + bitsandbytes + qwen-vl-utils + pyzmq/msgpack, then os.execvpes into the server. The server answers a ZMQ REQ/REP + msgpack protocol ({"op":"query","image","question"} → {"ok","answer"}); out-of-process for dependency/VRAM isolation (same pattern as rldx_sidecar). Apache-2.0 model.
ensure_venv(home, *, override=None) -> Path(sidecar) — return the sidecar venv python, provisioning + installing pinned deps if absent (sentinel-guarded); honours$OPENRAL_QWEN_VLM_SIDECAR_VENV.main() -> int(sidecar) — argparse (--model,--host,--port,--max-side,--home,--venv); stripsPYTHONPATH/PYTHONHOMEandos.execvpes into_qwen_vlm_server.py._load(model_id) -> (processor, model)/_query(...) -> str/main() -> int(server) — dual-path NF4 load (auto-detect a pre-quantized checkpoint via the embeddedquantization_config→ load 4-bit directly; else quantize-at-load, serial materialization for 8 GB); one scene-question→answer generate via the canonical Qwen-VL recipe (strips the<think>trace); ZMQ REP loop (ping/query/shutdown). Validated live (CLAUDE.md §1.2).
tools/da3_depth_sidecar.py + tools/_da3_depth_server.py
Boot helper + server for the Depth Anything 3 monocular metric-depth sidecar, companion to openral_perception_ros's depth-provider node (and Da3DepthClient, docs/methods/07-eval-sim.md). depth-anything/DA3-SMALL ships as the depth-anything-3 package rather than transformers-native, so it runs in its own Python 3.12 venv behind a ZMQ REQ/REP + msgpack wire (ping / depth / shutdown); the provider republishes the reply as a 32FC1 depth Image + CameraInfo for nvblox. Measured 0.27 GB / ~27 Hz on an 8 GB Ada. The launcher loads _sidecar_common by file path (not from openral_sim…) so it stays runnable by any python3 — the deploy launch autostarts it under a plain interpreter (slam_depth_sidecar_autostart).
ensure_venv(home, *, override=None) -> Path— return the sidecar venv python, provisioning it if absent (sentinel-guarded, keyed on the platform's pin set — including the override text, so raising nvrtc repairs existing venvs); honours$OPENRAL_DA3_DEPTH_SIDECAR_VENV. x86_64 installs_REQUIREMENTS(depth-anything-3,pyzmq,msgpack) in one pass. aarch64 (GB10 / DGX Spark, Jetson Thor) cannot:open3dandpycolmappublish no linux-aarch64 wheel, so it installs_AARCH64_REQUIREMENTS(upstream's dependency list minusopen3d/pycolmap/xformers/pre-commit, plus the undeclaredaddictand the repo'storch==2.9.1aarch64 pins) and then_AARCH64_DA3(depth-anything-3==0.1.1) with--no-deps— both passes under--overrides _NVRTC_OVERRIDE(sidecar_requirements/aarch64-nvrtc-override.txt), which is load-bearing here: DA3's@torch.jit.script affine_inverseis NVRTC-fused once the profiling executor warms up, so on stock nvrtc 12.8 request #1 succeeds and every later one dies on sm_121._site_packages(py) -> Path— thesite-packagesof the venv owningpy;SystemExitif absent._defer_pycolmap_import(py) -> None— aarch64 only. Rewrites the module-levelimport pycolmapin the installeddepth_anything_3/utils/export/colmap.pyinto a lazy__getattr__proxy, becauseapi.pyimports the export subsystem eagerly andpycolmaphas no aarch64 wheel. A deferred import, not a stub (§1.11):export_to_colmapstill raises the realModuleNotFoundError. Idempotent; unlinks before writing (uv hardlinks wheel contents out of its shared cache); raisesSystemExitif the anchor statement is not found exactly once.main() -> int— argparse (--modeldefaultdepth-anything/DA3-SMALL,--host,--portdefault 5771,--process-resdefault 504,--home,--venv); stripsPYTHONPATH/PYTHONHOMEandos.execvpes into_da3_depth_server.py. No JIT/fuser env knobs — the sm_121 problem is fixed at install time by the nvrtc override, so TorchScript stays on._load(model_id) -> (torch, model)/_infer(torch, model, image, process_res) -> (depth, K, latency_ms)/main() -> int(server) — load DA3 to CUDA in eval mode; one image → metric depth(H, W)float32 + 3×3 intrinsics; ZMQ REP loop that replies with{"ok": False, "error": …}rather than dying on a bad frame. Validated live on both an 8 GB Ada and a GB10 (CLAUDE.md §1.2,docs/reference/aarch64-support.md).
tools/cosmos3_reasoner_sidecar.py
Boot helper for the curated NVIDIA Cosmos 3 Edge reasoner model (OPENRAL_REASONER_MODEL=cosmos3-edge), companion to openral_reasoner.cosmos3.Cosmos3ToolUseClient. Provisions an isolated Python 3.12 venv (OPENRAL_COSMOS3_SIDECAR_VENV to reuse one) from the pure-PyPI hash-pinned tools/sidecar_requirements/cosmos3_reasoner.lock (vllm≥0.23) plus a SHA-pinned transformers overlay (_TRANSFORMERS_EDGE_SHA — no released transformers recognises cosmos3_edge yet), then — for the Edge diffusers layout — downloads the checkpoint and builds a flattened reasoner view (vLLM's loader can't follow the diffusers subfolder weight_map) before os.execvpeing into vllm serve <view> --served-model-name nvidia/Cosmos3-Edge --enable-auto-tool-choice --tool-call-parser hermes --max-model-len 8192 --gpu-memory-utilization 0.90 --enforce-eager. No ZMQ server script: vLLM's OpenAI-compatible HTTP API is the wire contract the reasoner already speaks. Out-of-process for the same dependency/VRAM isolation reasons as qwen_vlm_sidecar.py. Cosmos 3 weights are OpenMDW-1.1 (commercial OK) — no license guard. Boots live on an 8 GB RTX 4070; forward-pass inference is blocked by an upstream get_rope_index bug (see docs/reference/cosmos3-edge-reasoner.md).
ensure_venv(home, *, override=None) -> Path— return the sidecar venv python, provisioning + installing the pinned lock and the SHA-pinned transformers overlay if absent (sentinel-guarded); honours$OPENRAL_COSMOS3_SIDECAR_VENV.is_diffusers_reasoner_layout(model_dir) -> bool— True when the top-levelmodel.safetensors.index.jsonmaps tensors into subfolders (the Edge layout needing a view); Nano/Super (bare top-level shards) return False.materialize_reasoner_view(model_dir, dest) -> Path— build a vLLM-loadable flat view: bare-named shard symlinks + a rewritten weight index + tokenizer/config symlinks. Idempotent.resolve_served_model(model, home) -> tuple[str, str | None]— resolve a repo id / local dir to avllm servetarget + optional--served-model-name(snapshot-downloads and builds the view for the Edge layout; serves Nano/Super by id).build_serve_argv(*, vllm_bin, model, host, port, tool_call_parser, max_model_len, gpu_memory_utilization, enforce_eager, served_model_name=None, kv_cache_dtype="auto") -> list[str]— thevllm serveargv.--max-model-len(default 8192) holds the reasoner prompt + tools;--enforce-eager+--gpu-memory-utilization(default 0.90,$OPENRAL_COSMOS3_GPU_MEM_UTIL) +--kv-cache-dtype fp8are the 8 GB-fit knobs (fp8 KV verified required for the 8192 window with the native Edge impl on an 8 GB 4070).main() -> int— argparse (--modeldefaultnvidia/Cosmos3-Edge,--host,--portdefault 8901,--tool-call-parser,--max-model-len,--gpu-memory-utilization,--no-enforce-eager,--kv-cache-dtype,--home,--venv); stripsPYTHONPATH/PYTHONHOME, sets the expandable-segments allocator config (fragmentation OOM fix verified live;PYTORCH_ALLOC_CONForPYTORCH_CUDA_ALLOC_CONFdepending on the sidecar venv's torch — seealloc_conf_var/venv_torch_version), resolves the served view, andos.execvpes intovllm serve.
tools/behavior_groot_sidecar.py
Python 3.10 sidecar for the official 2026 BEHAVIOR-1K GR00T N1.7 checkpoint. Imports the pinned wensi-ai/Isaac-GR00T behavior runtime, registers the official R1Pro modality slices, wraps Gr00tPolicy with B1KPolicyWrapper, and serves ZMQ ping/reset/get_action/close. Two 8 GB-host memory measures: whole-model NF4 (--quantization nf4, default) and dropping the unused Qwen3-VL lm_head (the wrapper reads only hidden states; ~840 MiB saved — 2.77 GiB inference peak, live-validated alongside OmniGibson).
main(argv) -> int— Parse checkpoint/task/instruction/control-mode/device/endpoint plus--quantization {none,nf4,int8}/--nf4-min-params(the min-params threshold applies to both quantizers), set the expandable-segments allocator config (PYTORCH_ALLOC_CONForPYTORCH_CUDA_ALLOC_CONFdepending on the installed torch), load the real checkpoint (CPU-first under NF4/int8), and serve the 23-D action API.OPENRAL_BEHAVIOR_GROOT_DUMP_OBS=<dir>pickles the first 32 observations for offline quantization A/Bs._drop_backbone_lm_head(model) -> None— Replace the Qwen3-VLlm_headwithIdentity; the B1K wrapper consumes onlyhidden_states[-1], so the full-vocab logits projection is dead weight and was the largest single inference allocation._quantize_nf4(model, *, device, min_params) -> None— Whole-modelbitsandbytesLinear4bitrewrite of largenn.Linears (manifest pinsnf4_min_params: 1000000), keeping small layers floating; patches the modeldtypeproperty to the first floating parameter dtype, then moves to CUDA. Offline A/B/C on captured obs: 2531 MiB peak, action MAE 0.0029 vs bf16 — behaviourally lossless for this checkpoint._quantize_int8(model, *, device, min_params) -> None— Same rewrite withbitsandbytesLinear8bitLt(LLM.int8, threshold 6.0). 3678 MiB peak / MAE 0.0017 vs bf16 on the same captured obs — too big next to OmniGibson on 8 GB, so its role is offline quality comparison, not co-resident serving.
tools/behavior_scene_sidecar.py
Official OmniGibson evaluator environment sidecar for scene.id=behavior. Resolves the configured task instance, exposes the challenge wrapper observation, applies external 23-D actions, and returns success/metrics/sim time over ZMQ.
main(argv) -> int— Parse task/instance/mode/wrapper/max-steps/endpoint, load the real BEHAVIOR environment, and serveping/reset/step/close.
tools/_robometer_scorer.py
In-process stateless scorer for the Robometer-4B reward monitor, companion to openral_runner.backends.reward.robometer_reward.RobometerInProcessReward. reward_monitor_node imports _robometer_scorer.py::_Scorer directly; there is no separate Robometer ZMQ process or dedicated venv. As of lerobot 0.6.0 the reward model is lerobot's in-tree lerobot.rewards.robometer.RobometerRewardModel — a vanilla AutoModelForImageTextToText (Qwen3-VL-4B) loaded with plain transformers. There is no pinned robometer git package and no transformers==4.57.1 force-pin. The scorer keeps OpenRAL's NF4 pre-quantized checkpoint (OpenRAL/rskill-robometer_4b-any-general-nf4, ~3.3 GB resident), meta-builds the native RobometerRewardModel skeleton and drops the packed 4-bit weights (remapped into the native module) in directly — no bf16 spike, no Qwen weight download. Validated live: 3.33 GB NF4, progress ramps to 0.88 + success 0.90 at task completion.
class _Scorer(scorer) — meta-builds the nativeRobometerRewardModel, remaps + loads the NF4 prequant pack, thenscore(frames_rgb, task, num_bins) -> (progress, success)computes per-frame progress via the module-leveldecode_progress_outputson_compute_rbm_logits(notcompute_reward, which returns only a scalar)._load_prequantized,_native_config,_remap_backbone_key,_resolve_local_dirsupport the meta-load.
tools/build_qwen_vlm_nf4_checkpoint.py
Reproducible recipe for the published OpenRAL/rskill-qwen35_4b-any-general-nf4 pre-quantized NF4 checkpoint. Runs in the sidecar venv. main() -> int — argparse (--source, --out); loads the upstream model once (NF4 + serial materialization so the bf16 pass fits 8 GB), save_pretraineds the 4-bit weights + processor, then verifies the checkpoint reloads directly as 4-bit (no bf16 spike) and answers a smoke query. Pre-quantizing lets deployment load the 4-bit weights directly (~3.3 GB) with no loader workaround. Distinct from quantize_rskill.py, which writes an install_prequantized_linears-loaded pack for the in-process lerobot runtime; this writes a transformers-native save_pretrained checkpoint for the isolated VLM sidecar.
tools/fix_libero_config.py
Auto-fix for the stale ~/.libero/config.yaml pitfall.
Detects and repairs $LIBERO_CONFIG_PATH/config.yaml (default ~/.libero/config.yaml) when its absolute paths no longer match the currently-active libero package — the file is written once at first LIBERO import and never refreshed, so switching venv / clone / workspace path leaves it pointing at a directory that no longer exists. Wired into the Justfile as _ensure-libero-config (chained off sim-libero / sim-xvla-libero / sim-pi05-libero). Idempotent.
_expected_config(libero_pkg_dir) -> dict[str, str]— Compute the canonicalassets/bddl_files/benchmark_root/datasets/init_statespayload that LIBERO writes on first import. (L47)_parse_yaml_map(text) -> dict[str, str]— Parse the flatkey: valuemap LIBERO writes — no PyYAML dependency. (L65)_render_yaml(payload) -> str— Render the same flat layout. (L79)_locate_active_libero() -> Path—import liberoand return its package directory; raisesRuntimeErrorwith a clear message when LIBERO is absent (caller treats as no-op). (L84)main() -> int— argparse entry point; flags--dry-run,--verbose. Returns 0 when the config matches or after rewriting. (L110)