No new framework. Just your Python, reflected into a UI.
The drivers your lab already writes. No SDK to adopt, no plugin to keep in sync.
Reads those drivers into an interface, runs your workflows and records every result. Works with no network at all.
Where labs share drivers, whole setups and workflows. Each driver's schema is stored, so it can be tried before it is installed.
Introspection, not integration.
Most orchestration tools need a plugin written against their SDK before they can control an instrument. IvoryOS instead inspects the Python you’ve already written — method names, type hints, docstrings, default values — and builds a matching form automatically. There is no schema to author by hand and no plugin API to keep in sync. Rename a parameter in your driver, and the generated interface updates with it.
def set_flow_rate(
self, rate: float
):
"""mL/min, 0-50"""
...This is why onboarding a new instrument is writing normal Python, not learning IvoryOS — and it’s the same mechanism that lets a driver contributed by one lab work, unmodified, in another.
You can write the Python. So can a model.
Scientists sweep parameters, engineers write drivers, and models now write workflow code too. The gap is in between: someone has to see what is about to run, before it runs.
And it compounds. The schema closes both gaps by giving all three the same thing to look at.
One place the workflow lives
Ten experiments in, workflows are usually scattered across notebooks and nobody is sure which version ran last week. Here they are stored, versioned and findable.
A preview before anything moves
Whoever proposed the step — a colleague or an assistant — you see the real parameters and their values before hardware does.
The driver stays the driver
The engineer writes ordinary Python. No interface code to keep in sync, and nothing to rewrite when the workflow changes.
Built for what wet-lab automation actually needs.
This is the app’s Optimize page, beside your instruments. Every field on it maps directly to one of the capabilities on the right, generated from your own driver’s parameters.
Prep / Main / Cleanup phases
Setup and teardown steps run once per workflow; the main sequence is what repeats, gets batched, or gets optimized.
Batch-aware execution
Mark a step as “per-sample” or “batch.” A batch step runs once per group of N samples — for equipment that processes several samples at once — instead of once per row.
Closed-loop optimization
Ax, BayBE, and NIMO are wired in behind one suggest/observe interface, with parallel-trial batches, live convergence plots, and per-objective early-stop criteria.
Human-in-the-loop pauses
A workflow can pause and ask a person for a value — load a sample, confirm a reading — then resume exactly where it left off, from any device on the network.
Full run history
Every run, step, phase, and parameter is recorded to SQLite or Postgres — queryable later, not just streamed to a CSV and forgotten.
Typed, validated parameters
Every generated form inherits your driver's real type hints, so a string typed into a float field is caught before it ever reaches your hardware.
When one queue stops being enough.
The app already coordinates every instrument on its computer, but as one linear workflow, one queue, at a time. Cloud, which we are building now, will be the layer above: one canvas where each step names the bench that runs it, and the ordering, schedules and results span all of them. It is not available yet.
Two cadences, one workflow
One station needs a step every four minutes, the next every five. On one bench they would take turns. In Cloud each step will keep its own cadence, and hold back only what depends on it.
A sample that moves
Synthesis on one platform, analysis on another, a transfer in between. Analysis will start only once synthesis reports done and someone confirms the move, and both platforms' results will land in one table.
An instrument two platforms share
Give a lightly used instrument its own computer. Cloud will send it one task at a time and hold the rest, and count runs started at the bench too, so the two sides queue instead of colliding.
Drivers. Every one still runs inside the app on its own computer, and Cloud will only ever send a bench the same run a person could start there. Hardware control stays exactly as local as it is today, and a lab keeps working if Cloud is unreachable.
On a lab network with nothing configured — a built-in broker and a local database, no accounts, no internet — or as a hosted service. A computer will join with a short pairing code, so no key is ever copied from one machine to another.
Contributed once, usable everywhere.
The Hub is part of the app: instrument drivers, whole setups, plugins and workflow templates that labs share. Every contributed driver is introspected once and its schema stored, so you can design and run against it before anything is installed, and the app installs exactly that driver when you are ready.
A driver is contributed
Someone shares a Python driver to the Hub, which registers its install metadata: the package, its constructor arguments, how to launch it.
Its schema is captured too
The same introspection the app runs against real hardware runs once against the contributed driver, and the resulting schema is stored beside it.
Try it, then install it
The schema is enough to design and run against the driver in your browser, simulated. In the app, one click installs the real package onto a bench.