Skip to content

Plugin System

Source

Maintained in hylo-harness: docs/plugin-system.md.

Implementation: hylo-core hylo/core/registry.py [Validated in prototype]

1. Design sources

Source Borrowed Discarded
inspect-robots registry.py importlib.metadata entry points; auto-loading can be disabled via an environment variable —
vla-eval module:Class references written directly in YAML, lazy import No entry points, no capability declarations
RPent / XPolicyLab — Directory name as plugin (no version, no metadata)

2. Plugin groups

Group (entry point group) Protocol Examples
Every contract is defined in hylo-core (module in brackets), so a plugin of any group depends on hylo-core alone.
Group (entry point group) Contract (hylo-core module) Examples
hylo.envs Environment (core.env) testing.point_reach, mujoco.planar_reach, libero
hylo.agents Agent or a factory returning one (core.agent) testing.p_controller, policy, steered, lerobot.steered
hylo.policies ChunkPolicy (core.policy) policy.flow, policy.bc, lerobot
hylo.reasoners Reasoner (core.reasoning) testing.rule_landmark
hylo.choosers Chooser (core.reasoning) chooser.rule_color, chooser.llm, chooser.vlm
hylo.planners Planner (core.reasoning) planner.identity, planner.llm
hylo.reflectors Reflector (core.reasoning) llm.reflector
hylo.memory MemoryStore / ActionMemory (core.memory, core.experience) sqlite, action_bank, lesson_book
hylo.scorers Scorer (core.scoring) success, steps, safety_interventions
hylo.gate_tests GateTest (core.scoring) mcnemar, sign, paired_permutation
hylo.benchmarks a factory returning a Benchmark (core.benchmark) testing/reach-v0, mujoco/reach-v0, libero
hylo.generators Proposer (core.improvement) rule.gain, rule.steering, llm.steering, learn
hylo.learners Learner / OnlineLearner (core.learning) critic.chunk_value, policy.flow
hylo.instruments SuccessJudge / ValueModel / WorldModel (core.instrument) judge.trace, judge.vlm
hylo.datasources DataSource (core.learning) video.frames, lerobot.dataset
hylo.guards Guard (core.safety) delta_limit, keep_out

3. Resolution rules

registry.resolve(group, "testing.point_reach")              # 1. explicitly or lazily registered name
registry.resolve(group, "my_lab.envs.kitchen:KitchenEnv") # 2. if it contains ":", import as module:attr
# 3. on a name miss, load Hylo.<group> entry points (only once; HYLO_NO_PLUGIN_AUTOLOAD=1 disables)
registry.build(group, {"type": "...", "params": {...}})   # factory call
  • Lazy: builtin.py registers string references with register_lazy, so import Hylo does not import MuJoCo [Validated in prototype].
  • Diagnosable errors: an error for an unknown name lists the known plugins [Validated in prototype].

4. Plugin metadata (introduced in v0.2)

class PluginInfo(Contract):
    name: str; version: str; group: str
    isolation: Literal["in_process", "subprocess", "container"]
    requires: dict[str, str]          # {"python": ">=3.8,<3.9", "gpu": "optional", "vulkan": "required"}
    capabilities: dict[str, bool]     # corresponds to EnvCapabilities / PolicyCapabilities
    license: str                      # code license
    weights_license: str | None       # required for policies
    assets_license: str | None        # required for envs (ManiSkill: CC BY-NC 4.0)

The Runner checks requires and capabilities before building (for example, a benchmark requires privileged_state, or an experiment requires snapshot to do shadow replay); if they are not satisfied it refuses to run, rather than failing halfway through.

5. Isolation levels

Level When to use Mechanism
in_process Pure Python, dependencies compatible with the main environment Direct import
subprocess Dependency conflicts, but a separate venv can be created on the same machine RemoteEnvironment(ref, python=<other venv>) [Validated in prototype]
container System-level dependencies (EGL/Vulkan/CUDA/Isaac) or untrusted code Same protocol, via docker exec / network endpoint

The protocol layer forbids pickle; array encoding/decoding only allows bool/int/uint/float dtypes [Validated in prototype].

6. Conformance Kit

Each plugin group provides a set of conformance tests (conformance/) that third-party adapters must pass:

  • Environment: spec() does not trigger simulation construction; two resets with the same seed yield the same obs; success vs terminated semantics; simulation error → truncated + info.sim_error; if snapshot is declared, stepping after restore is consistent step by step.
  • Agent/Policy: spec() matches the actual output dimensions; no cross-episode residual state after reset (except declared memory); ActionChunk shape.
  • MemoryStore: deduplication, key invalidation, as_of, radius queries, forget soft delete.
  • Scorer: depends only on the Trace (can run without env/agent).

The corresponding test cases in the prototype's tests/ are the embryo of the conformance kit.