Skip to main content
Version: 2.1.0

Orca Framework

Orca Framework 2.0.0 is released 🎉

Install it from GitHub: see Installation.

Orca Framework operates your lab. It schedules the work, moves labware between your instruments, and keeps the run going when something goes wrong.

You describe your instruments once, write your workflows in plain Python, and submit them to a service that stays running. The same code runs in simulation and on hardware, so you can build and debug an assay with nothing plugged in.

What you get​

  • The instruments you already own. No rip and replace, workflows you can validate, and visibility into every run.
  • Workflows in plain Python. Four decorators, and your normal editor, diffs and code review.
  • A runtime that stays up. Submit a workflow now, submit another an hour later, pause, resume, stop, or recover one labware thread without touching the rest.
  • Three ways to drive it. The Python API, a localhost daemon over REST and SSE, and the orca CLI.

What a workflow looks like​

import orca.orca as orca
from orca.workflow_models.action_context import ActionContext
from orca.workflow_models.method_context import MethodContext
from orca.workflow_models.thread_context import ThreadContext

@orca.action(device=shaker, inputs=[plate])
async def shake(ctx: ActionContext):
await ctx.device().shake(duration=30, speed=500)

@orca.method
async def shake_step(ctx: MethodContext):
yield shake

@orca.thread(labware=plate, start="plate_pad", end="plate_pad")
async def sample_thread(ctx: ThreadContext):
yield shake_step

@orca.workflow(name="sample_assay")
def sample_assay(wf):
wf.start(sample_thread)

That is a complete workflow. Read it from the bottom: the workflow starts one labware thread, the thread is one plate's path through the lab, the method is a named sequence of steps, and the action is one step at one device. The runtime takes it from there.

Where to go next​

Advanced​

Two things that matter if you are comparing products or planning an integration. Skip both until your first workflow runs.

Coming from Legacy Orca​

The high-level shape is unchanged: workflows compose labware threads, threads compose methods, methods compose actions. These are the differences that change what you would build.

  • The runtime stays up. A long-lived SystemRuntime accepts submissions whenever they arrive. Legacy ran one workflow then exited.
  • Python, not JSON. @orca.method, @orca.thread, @orca.workflow. The JSON workflow path is gone, so you get real IDE support, real diffs and real refactors.
  • Nothing is scheduled up front. Threads take reservations as they go. A knot in the wait-for structure is detected as a deadlock, and one thread is told to yield and move its labware out of the way. What cannot be resolved that way is caught by the stall detector, which pauses the run and hands the operator something to act on.
  • Plates converge. Labware arrives at a shared device from independent threads, and co-labware coordination is a first-class concept.
  • Three run modes, sim first. PURE_SIM, DEVICE_SIM and LIVE. Each submission carries its own mode and drivers are resolved at dispatch, so you can validate an assay with zero hardware.
  • More than one sample per submission, and more samples later. One submission can fan N samples into one shared final plate. Later submissions can join an in-flight batchable execution, so an operator can drip-feed samples over hours into one run.
  • One list of what is stopping the run. Device faults, error-paused threads, a paused execution, a plate waiting on a person: all of it derived into one list, each entry carrying the remedies that clear it. Anything the record cannot answer is listed as unsettled with the verb that settles it. No hunting across four surfaces to find out why nothing is moving.
  • An operator can take over mid-run. The runtime holds the device so the engine cannot schedule it in between, and records every command against the run. A command that would rewrite the driver's own picture of where labware is is refused, and the refusal names the verb that writes the driver and the record together. An operator can also place a catalog type the workflow never declared, just by naming it.
  • The instrument gets a vote. A liquid handler reports what is actually on its deck. Disagreement with the record is raised as an incident instead of being silently overwritten.
  • State survives a restart. Labware positions and well volumes are persisted, so a runtime that comes back up knows where things are and what is in them. Stores are pluggable: in-memory or embedded SQLite for development, database-backed in production.
  • Calibration lives outside your source. Workflows, methods and topology are Python files your repo already diffs and reviews. Teachpoints, deck layouts, access configs, grip profiles, move defaults and labware catalog entries live in stores you read and edit through the API and the CLI.
  • Every status change fires an event. External systems subscribe. No polling, no log scraping.

The legacy docs are still available. Pick Orca Legacy from the Orca menu in the navbar.

Network access, MCP and AI agents​

Orca Framework's daemon listens on localhost. Orca AI wraps the same runtime with authenticated REST, MCP and WebSocket surfaces, which is what an AI agent, a dashboard, or another machine on the network talks to.

See also​