Documentation

Give ReasoningOne the job.

One call describes an outcome. Everything underneath — model, robot, skill, credentials, failure policy — is absorbed.

Quickstart

Install the SDK and run a job. There is no robot to configure at this stage.

npm install @reasoningone/sdk
import { JobsClient } from '@reasoningone/sdk';

const jobs = new JobsClient({ baseUrl: process.env.REASONINGONE_URL });

const { job } = await jobs.run({
  objective: 'Inspect production area A',
  requirements: {
    inspection_standard: 'visual_v1',
    completionBefore:    '06:00',
    siteId:              'plant-3',
  },
  priceUsd: 70,
});

// job.tasks    — the WorkGraph
// job.result   — verified outcome + evidence episodes
// job.result.economics — including energy and depreciation

The stack runs locally with zero credentials — a mock provider keeps every endpoint total, so you can drive the whole loop before you have a robot or an API key.

API reference

POST/v1/jobsrunJob() — the one call your code makes
GET/v1/jobs/:idstatus, WorkGraph, result, economics
GET/v1/jobs/:id/graphthe graph depth-first, plus the P&L
POST/v1/machinesa robot advertises its body
POST/v1/machines/:id/claimpull work — never pushed to a machine
POST/v1/tasks/:id/reportoutcome, evidence, whether a human helped
GET/v1/metrics/vajverified autonomous jobs + operating dashboard
GET/v1/combinationswhich model × body × skill completes paid work

Assignment is pull-based: the cloud never assumes it can reach a robot in a basement, a lift shaft or the back of a trailer. A machine that is charging, blocked or e-stopped simply does not ask, and nothing has to time out to discover that.

Capability protocol

A body describes itself in terms a task can be matched against. Never a brand.

{
  "locomotion":        "legged",        // ranked: none → wheeled → legged
  "manipulation":      "bimanual",      // none → simple → dexterous → bimanual
  "mobility":          ["walk", "stairs", "doors"],
  "manipulationVerbs": ["grasp", "lift", "place", "fold"],
  "payloadKg":    15,
  "precisionMm":   5,        // lower is better
  "runtimeHours":  3,
  "hands":         2         // a bed needs two
}

Matching is ranked, with one exception: flight is not a superset of ground travel. A drone outranks a rover on the locomotion scale and still cannot push a cart.

A body that does not advertise gets pessimistic defaults. An underclaimed robot is passed over for work it could have done, costing throughput; an overclaimed one accepts work it cannot do, costing a failed task, a callout, and a customer’s trust.

Write an adapter

Five methods. Implement them and every ReasoningOne application runs on your robot.

class MyBotAdapter(Robot):
    name, vendor = "mybot", "acme"

    def observe(self, modality) -> Observation | None: ...
    def capabilities(self) -> dict: ...
    def execute(self, action: Action) -> Result: ...
    def health(self) -> RobotHealth: ...
    def stop(self) -> None: ...

Declare an entry point, and the runtime finds you — no release from us required.

[project.entry-points."reasoningone.adapters"]
mybot = "reasoningone_mybot:MyBotAdapter"

Two rules the contract enforces: an unwired adapter must report health().ok == False, and a missing capability is a failed Result, not an exception. One broken driver must never crash a fleet.

Publish a skill

name: open-door
requires:
  morphology:    [arm, gripper]
  manipulation:  dexterous
  maxPrecisionMm: 10
  minRuntimeHours: 0.5
postconditions:
  - kind: entity_state
    args: { label: door, state: open, minAngleDeg: 60 }

Two things are rejected at publish time. A manifest naming a robot brand or a policy model — the first one accepted turns the registry into a pile of vendor plugins. And a skill with no checkable postcondition: nothing could verify it ran, so its work could never count as autonomous.

ro-skill validate ./skills/open-door
ro-skill publish  ./skills/open-door