i think this is helpful and kinda wish a community would work on this. it feels like devs have always wanted this layer between a protocol and PLR atomic commands, and several papers have tried to make it, but it never ended up becoming the standard. somehow, though, i think PLR is capable of doing it now since it has gotten good at the lower level.
previously, i was unsure whether this would be of interest to PLR, since the scope before seemed to focus more on the atomic command level. i vibe coded one repo for this for my own use—would this be similar to what you are referring to?
basically, it provides higher-level commands at the step level, which is usually how experimentalists read a lab protocol. i always feel that an LLM has a tendency to miss something crucial when working at the lower level of executing lab steps, so wrapping them into a good higher-level step makes them more reusable and safer.
in my repo, PLR is an adapter, and i organized these as nodes so they can be connected modularly. this was inspired by XOD, the no-code IDE for Arduino. connected nodes can also be assembled into a higher-level node, such as a recipe, i.e. a protocol.
so, for example, one recipe might involve active cooling. as long as the devices in PLR support it, it should work regardless of whether the device is a heater-shaker or a thermocycler. this also makes it more portable for sharing, though, as you said, coding agents can now easily rewrite the code to match the instruments we have in our lab.
(base) […] % tree modulap/nodes
modulap/nodes
├── init.py
├── _composition.py
├── _manual_placement.py
├── _request_hooks.py
├── _specs.py
├── imaging
│ ├── init.py
│ ├── calibrate.py
│ ├── map_pixels.py
│ ├── model.py
│ └── specs.py
├── liquid_handling
│ ├── init.py
│ ├── _support.py
│ ├── aliquot.py
│ ├── channel_policy.py
│ ├── combine.py
│ ├── dilute.py
│ ├── formulate.py
│ ├── jog.py
│ ├── mixture_formulation.py
│ ├── model.py
│ ├── prefill.py
│ ├── request_hooks.py
│ ├── runner.py
│ ├── serial_dilution.py
│ ├── specs.py
│ ├── spotting.py
│ └── transfer.py
├── meta
│ ├── init.py
│ ├── assert_step.py
│ ├── init_liquids.py
│ ├── log.py
│ ├── mark.py
│ ├── notify.py
│ ├── pause.py
│ ├── request.py
│ └── wait.py
├── movement
│ ├── init.py
│ └── labware_manual.py
├── plate_reading
│ ├── init.py
│ ├── _support.py
│ ├── absorbance.py
│ ├── capture.py
│ ├── fluorescence.py
│ ├── luminescence.py
│ ├── model.py
│ ├── read.py
│ ├── runner.py
│ ├── specs.py
│ └── tray.py
├── recipes
│ ├── _golden_gate_support.py
│ ├── _request_orchestration.py
│ ├── _transformation_support.py
│ ├── golden_gate_program.py
│ └── transformation_heat_shock.py
├── runtime
│ ├── init.py
│ ├── _support.py
│ ├── deck.py
│ ├── device.py
│ └── specs.py
├── sealing
│ ├── init.py
│ ├── model.py
│ ├── runner.py
│ ├── seal.py
│ └── specs.py
├── separation
│ └── init.py
└── thermal
├── init.py
├── _support.py
├── _waiters.py
├── cool.py
├── heat_shock.py
├── incubate.py
├── model.py
├── presets.py
├── program.py
├── runner.py
└── thermocycle.py
11 directories, 76 files