Oasis CLI

Industrial AI Harness

Professional coding harness for building industrial automation applications.

PREEMPT_RTIEC 61131-3EtherCATOPC UAModbusSelf Hosted AIMCP SupportLanguage-Agnostic

Put it on the machine

$curl -fsSL https://get.mutexer.com/oasis/install.sh | bash
Linux and WSL Rust, statically linked, no runtime
[root@edge-01:~/dosing-skid]# ./target/release/oasis-agent
[pack] modbus capability pack registered (ModbusRead, ModbusWrite)
[pack] opc ua capability pack registered (OpcUaBrowse, OpcUaRead, OpcUaWrite)
[pack] ethercat capability pack registered (EtherCatScan, EtherCatIdentify, EtherCatSdoRead, EtherCatSdoWrite)
  ██████╗  █████╗ ███████╗██╗███████╗
 ██╔═══██╗██╔══██╗██╔════╝██║██╔════╝
 ██║   ██║███████║███████╗██║███████╗
 ██║   ██║██╔══██║╚════██║██║╚════██║
 ╚██████╔╝██║  ██║███████║██║███████║
  ╚═════╝ ╚═╝  ╚═╝╚══════╝╚═╝╚══════╝
        ❯ agent cli   // made by mutexer
oasis-agent v0.14.2+g8f21ac0 · model: magnum-1 · endpoint: http://10.8.0.23:8080 · cwd: /srv/dosing-skid
modules   [✓] PREEMPT_RT   [✓] Modbus   [✓] OPC UA   [✓] EtherCAT   [✓] IEC 61131-3
type /help for commands, /exit to quit · Tab completes · Shift+Tab switches permission mode · \ or Alt+Enter for a newline · Ctrl+C cancels
› the skid on eth0 is new. tell me what is on it, then start the master.
EtherCatScan · {"interface":"eth0","subdevices":3,"not_in_op":3,… · 1 lines · 22ms
  ╰ {"interface":"eth0","subdevices":3,"not_in_op":3,"faulted":0,"latency_ms":3.368635,"positions":[{"position":0,"al_state":"init","al_error":false…
Three SubDevices, all in init. No master has claimed them yet, so nothing is energised.
ModbusRead · {"unit":1,"point":"holding:4012","values":[1847,423]… · 1 lines · 12ms
  ╰ {"unit":1,"point":"holding:4012","count":2,"values":[1847,423],"latency_ms":12,"budget_ms":250,"map":"config/dosing.map.json"…
OpcUaRead · {"node_id":"s=Skid.Interlock","value":false,"quality":"Good"… · 1 lines · 31ms
  ╰ {"node_id":"s=Skid.Interlock","value":false,"quality":"Good","source_timestamp":"2026-08-24T09:14:11Z","security_policy":"Basic256Sha256"…
Level 1847 mm, 42.3 °C, interlock clear. Now the master. The skill is explicit that these tools observe a segment and the application is the master, so I will read it before writing anything.
Skill · # Building an EtherCAT control application · 255 lines · 0ms
  │ # Building an EtherCAT control application
  │ The tools in this harness **observe** a segment. The application you are about
  ╰ … +252 more lines · /expand t-4
The skill puts one decision ahead of the rest: what the target image carries. This board has no ec_master module and never loads one at boot, so it is ethercrab, and the edition has to come down to match the toolchain that is actually on the device.
 /srv/dosing-skid/Cargo.toml +5 −1
@@ -1,7 +1,11 @@
 [package]
 name = "dosing-master"
 version = "0.1.0"
-edition = "2024"
+edition = "2021"
 
 [dependencies]
+ethercrab = "0.7"
+futures-lite = "0.3"
+tokio = { version = "1", features = ["rt-multi-thread", "macros"] }
+anyhow = "1"
That is the manifest. Cycle time is yours to set and I am not going to pick it for you: the sync manager watchdog window follows from it, and getting it wrong faults the segment rather than slowing it down.
← turn done · 31.6s · ctx 28.4k/228.6k 12% · 1.2k new + 0.6k out · 3 model calls
○ manual: ask before every dangerous tool · shift+tab to cycle

Getting started

Three steps

Install it on the hardware, point it at a model you control, and start building. There is no account to create and no service to sign up for before the first turn runs.

01

Install it on your hardware device

One command, one file. No package manager, no runtime, nothing left behind to maintain. It runs on an industrial PC in a cabinet, a jump host on the OT network, or a controller on the bench.

$curl -fsSL https://get.mutexer.com/oasis/install.sh | bash

Linux and WSL · 24 ms cold start

02

Point it at a model you host

There is no baked-in address. Point it at your own inference server inside your own network, or at Magnum 1 in mutexer Cloud. Either way your code, your prompts and your tag names go where you decide they go.

$oasis-agent --base-url http://10.8.0.23:8080 --show-config

Self-hosted or Magnum 1 · no default endpoint

03

Build industrial code

The agent that writes the configuration is the one that reads the device back. It edits the repository, runs the build, opens the socket, and then runs the conformance check against what it just did.

bring the segment up and prove it is in OP

One loop · one audit trail · one artefact

The tool surface

Detect, diagnose, build

Oasis CLI is built for one job: building, configuring and deploying industrial systems.

Self-hosted inference

  • Any OpenAI-compatible endpoint, and no default address to leak to
  • 94 to 100% prefix cache reuse, so a turn lands in about 0.35 s
  • A strict harness that holds a smaller model to the same shape of answer

Protocols and conformance

  • Modbus, OPC UA and EtherCAT as tool calls, not integrations to write later
  • Every pack ships its own prober, so a reading is measured here rather than parsed out of a vendor CLI
  • Checks run against a stated budget, and a probe with no number returns not_applicable rather than a pass

Industrial skills

  • IEC 61131-3 structured text, written for a toolchain that will actually build it
  • EtherCAT bring-up and application design, Modbus debugging, OPC UA commissioning
  • PREEMPT_RT provisioning and tuning, measured against a jitter budget

Tools the agent can call

EtherCatScanEtherCatIdentifyEtherCatSdoReadEtherCatSdoWriteEtherCatReadIoEtherCatWriteIoEtherCatPulseIoEtherCatGoOperationalEtherCatStopIoModbusReadModbusWriteOpcUaBrowseOpcUaReadOpcUaWriteCheckAuditReadWriteAppendEditMultiEditBashBashSessionGlobGrepMonitorWebFetchViewImageSkillAgentMemoryUpdatePlanExitPlanModeAskUserQuestionand more each release

Sandboxed, with escalation per tool. A PLC write always asks. Run /help for the full set.

Industrial harness process

Four steps on a live network

Shown the way the terminal shows them.

Read what is there

What actually answered, not what the drawing says.

EtherCatScan interface=eth1
   0  EK1100   0x044c2c52  OP
   1  EL1008   0x03f03052  OP
   2  EL2008   0x07d83052  OP
   3  EL3064   0x0bf83052  OP

Write only when you allow it

The tool and the exact arguments, every time.

ModbusWrite unit=1 point=holding:40 value=1
  ? allow this write   1. yes   2. no
  wrote holding:40 = 1
  audit ~/.oasis/audit.jsonl

Check one claim

A measured number against a stated budget.

Check l2.modbus.reachable
  proven   latency_ms=12   max=250 ms
  IEC-62443-3-3 SR 7.2
  NIST SP 800-53 SI-4

Audit the whole module

Including a section for what it could not assess.

Audit profile=preempt-rt
  33 descriptors   28 proven
   3 indicative     2 not_applicable
  not assessed, and why: 2 entries

Conformance

Never a false pass

Every check returns one of four verdicts. Only one of them means it passed.

provenMeasured on this machine, by this process.
indicativeAn inference, and labelled as one.
not_applicableNothing was measured, so nothing passed.
errorIt went wrong, with the reason attached.
id            = "l2.modbus.reachable"
confidence    = "proven"
criteria      = { max = 250.0, unit = "ms" }

The threshold is on the latency, not on "did it answer". An endpoint that replies in four seconds has failed a control network.

Real-time readiness

Most of the catalogue is about PREEMPT_RT

Real-time determinism on mainline Linux is what makes hardware a purchasing decision rather than a ten-year architectural commitment. It is also easy to claim and hard to demonstrate. These are the checks the agent runs to establish whether a machine is actually configured for it.

kernel.preempt-rt-active
kernel.preempt-mode
kernel.clocksource-tsc
kernel.high-res-timers
rt.isolcpus-effective
rt.threads-pinned
rt.sched-policy
rt.jitter-within-budget
sched.rt-throttling-disabled
sched.timer-migration-off
sched.runqueue-delay
sched.involuntary-preemption
irq.affinity-excludes-isolated
irq.smi-count-stable
power.governor-performance
power.cstates-limited
power.smt-disabled
mem.swap-disabled
mem.control-process-locked
mem.thp-not-always
boot.isolcpus / nohz-full
boot.rcu-nocbs-set
loop.cycle-time
virt.no-steal-time

Twenty-four of the thirty-three shown. Each carries written remediation, so a failure arrives with what to do about it rather than a red tick. Read more about the kernel work behind this on the mutexer Agent page.

Control

You decide how much it is allowed to do

Four permission modes, cycled with Shift+Tab. The active mode is always visible under the prompt, and it can be changed while a turn is running, so you can hand over more autonomy without waiting for the model to finish.

planRead-only. Mutating tools are refused until you approve a plan.
manualAsk before every dangerous tool. The default, and the right one on a live network.
accept editsFile writes apply without asking. Bash and unknown tools still ask.
autoNothing routine is asked.
○ manual: ask before every dangerous tool · shift+tab to cycle

Every write produces one actor-stamped JSONL line in ~/.oasis/audit.jsonl, whatever mode it happened under.

Long-running work

Work that outlives the terminal

Commissioning does not fit inside one sitting at a laptop that stays open. A build, a soak test, a migration across twelve sites: all of it has to survive the SSH session dropping.

Background jobs

A build or a test run returns its job id at once and reports its exit back into the conversation. A live row under the prompt shows what is running and for how long. /jobs tails or kills one, and reading a job's output does not consume it.

Handoff and rejoin

Ctrl+B detaches a job mid-turn. /background moves the whole conversation to a detached agent that keeps working after the terminal closes, and /agents takes it back, streaming its work in as it lands.

Resumable conversations

Every conversation is saved and replayable. One that stopped to ask you something is marked as waiting, so a session left overnight tells you it needs an answer instead of looking finished. Resuming costs the prompt cache nothing.

Speed

A turn lands in about a third of a second

That number is not a faster model. It is prefix reuse. The prompt cache is treated as the first-class citizen of the design: the system prompt, the tool registry, tool schemas, registration order and history rendering are all held stable, because any one of them turning over costs the whole prefix.

134ms

Turn boundary at 100%
reuse, against 17.2 s at 0%

24ms

Process start to first
inference request, p50

94%

Prefix cache reuse in steady
state, and up to 100%

669

Tests, run against every
release build

Your model

The endpoint is yours to choose

--base-url is required and has no default. You choose where the model runs.

Host it yourself

Your hardware, your weights

Any OpenAI-compatible endpoint. Nothing leaves the site, so air-gapped is just the ordinary case with a shorter cable.

oasis-agent --base-url http://10.8.0.23:8080

Or Magnum 1, in mutexer Cloud

Inference tuned for industrial code

Open-weight models running in your own environment. Your code never reaches a third-party model, and you pay for capacity rather than per token.

oasis-agent --base-url <mutexer-resource-id>
See Magnum 1

Run oasis-agent --show-config to see which endpoint is in use, and where the setting came from.

Put it on the machine

Install it, point it at your own endpoint, and give it something to look at.

$curl -fsSL https://get.mutexer.com/oasis/install.sh | bash
Linux and WSL