kualia.ai documentation
Teach your robot new tricks
kualia turns a sentence into a trained robot skill. Pick a MuJoCo robot, describe the trick in any language, and alia writes a training task, builds the world the trick needs and checks it. You train a policy in simulation, watch it practise in your browser, iterate in versions and export an ONNX policy for the real robot.
Twelve robots, or yours
A world for the trick
13 automated checks
Watch it learn
AI review & versions
ONNX out
kualia never generates robot physics
Tasks are built on a fixed, validated MuJoCo model. alia writes only the task layer: what the robot is rewarded for, when an episode ends, what counts as success and which objects are in the world. It cannot change the robot’s bodies, joints or actuators, and those rules are re-applied on every change.No code is required. Everything alia writes is visible, though: the Plan page shows the full Python task, and this documentation explains exactly how it is structured, so you can read it, reason about it and ask for precise changes.
Getting started
Quick start: your first trick in five minutes
The fastest route from a blank page to a trained policy. Use a small robot for your first run; the workflow is identical for the big ones.
Open “Teach a new trick”
Sign in and open the Dashboard. The start screen is Teach a new trick: choose a robot, describe the trick, adjust the training settings.Pick a robot that learns quickly
InvertedPendulum (balance a pole) and Reacher (a two-link arm) learn in tens of thousands of steps. Walker2d is pre-selected, but a biped needs far more practice, and the realistic robots (Go2, Spot, OP3, G1) need millions of steps. See Robots.Describe the trick in one sentence
Or press Try an example, which fills the robot, the trick and a measurable success criterion. For example, on InvertedPendulum:
Keep the default settings
Success criterion Let kualia pick, safety Standard, reward Dense shaping, difficulty Easy. The Estimated cost panel shows the plan estimate and the price of a first 10K-step run before you click.Build the training plan
A world planner first decides which objects the trick needs (if any). alia then writes the reward, termination and success rules, runs the 13 checks and repairs failures on its own (up to four attempts). This takes a minute or two.Review the plan and the world
On Plan & world, read Your trick and What success looks like (the task restated in one sentence and a short step list of a successful episode), open the reward explanation, press play in the 3D world for a zero-torque drop test, and confirm the checks read 13 / 13. Anything you want changed, tell alia.Start a first run
Choose First try · 10K steps and press Start training. Watch the reward chart and the checkpoint film strip fill in. A short run is a sanity check: does the robot move sensibly, do episodes last?Read the results, then iterate or export
Open the run’s results: evaluation episodes, failure cases and an AI analysis with proposed changes. Train longer, create the next version from the analysis, or go to Export and download the ONNX policy.
Short runs are for checking the task, not for mastering it
10K steps is enough for a cart-pole to improve and for you to see whether the reward points the right way. Bigger robots need hundreds of thousands to millions of steps; the Learn it budget suggests a typical number for each robot.Getting started
Core concepts
A handful of words are used throughout the Studio and these docs.
- Robot
- A MuJoCo model: one of the twelve built-in robots or a model you uploaded. Its physics stay fixed.
- Trick
- What you want the robot to learn, in your words, plus the optional success criterion, safety level, reward style and starting difficulty. Together they form the brief.
- Task
- The Python training environment alia writes from the brief: a Gymnasium
Envwith the reward, termination and success rules and, if needed, world objects. Also called the task code. - Training plan
- The structured summary of the task shown on the Plan page: the trick in one sentence, what success looks like step by step, reward design, success criteria, failure conditions, observation signals, action space and curriculum stages.
- World
- What the robot practises in: the floor plus the objects declared in the task’s
SCENE. The world planner decides which objects a trick needs. The same world is used in the checks, in training and in the browser. - Policy
- The neural network that maps what the robot senses (observations) to motor commands (actions). Training improves it; export turns it into an ONNX file.
- Run
- One training job with a step budget on one task version. A run has a reward curve, checkpoints, evaluation episodes, a trained model and an AI analysis.
- Checkpoint
- A snapshot of the policy recorded during a run (untrained, 25 %, 50 %, 75 %, final) with a video and a 3D trajectory.
- Version
- Every change to the task creates a new numbered version (v1 is the one built from your brief). Runs are pinned to the version they trained on, so results stay comparable; any older version can be made current again.
- Training steps
- What a run spends. Every plan includes a monthly number of them; alia, the assistant, is included too. See Plans & training steps.
The brief kualia sends
The form on Teach a new trick is assembled into a plain-text brief. Seeing it helps when you later ask alia for changes:
Getting started
The Studio, step by step
A trick moves through five screens. alia is available on every one of them and can change the task at any point.
1
Teach a new trick
Dashboard
- Choose a robot
- Describe the trick
- Settings + cost estimate
2
Plan & world
/studio/…/task
- Training plan
- 3D world
- 13 checks · budget
3
Training
/studio/…/train
- Live simulation
- Checkpoints · chart
- Stop · keep training
4
Results
/studio/…/evaluate
- Runs & versions
- Evaluation · AI review
- Compare · rollback
5
Export
/studio/…/export
- Deterministic ONNX
- Metadata · SHA256
- Robot runtime
| Screen | What you do there |
|---|---|
| 1 · Teach a new trick | Pick a built-in robot or import one (MJCF/URDF), describe the trick (up to 1,000 characters), choose success criterion, safety level, reward style and starting difficulty. A task summary splits your sentence into steps and the cost panel estimates plan and training prices. |
| 2 · Plan & world | Read your trick for this version, what success looks like, the training plan (six cards), the reward explanation and the generated task code. Inspect the world in the 3D simulator (World / Robot / Observations tabs, physics drop test). See the 13 checks, pick a practice budget and start training. |
| 3 · Training | Watch the live simulation, the checkpoint film strip (0 / 25 / 50 / 75 % and final), the learning-progress chart, the training log and run statistics. Stop the run, train the version again, or keep training from the previous model. |
| 4 · Results | Runs & versions lists every run of every version: design a new run with alia, train again as it is, compare two runs, make an older version current. Each run has its own results page with the best policy rollout, evaluation episodes, failure cases and the AI analysis. |
| 5 · Export | Try the exported policy live in the browser, review its input/output schema, control rate and checksum, download the ONNX file and copy a minimal on-robot inference loop. |
Inside a project, stages 2–5 are the tabs of the Studio’s stage bar. Plan & world is where you land after building a plan, and where you review every assistant change before training it.
Build a task
Robots
Every task is pinned to one MuJoCo robot. Start with one of the eighteen built-in models — tiny maker robots first — or import your own robot description.
There are three shelves of built-in robots. Joints is the number of actuators (the size of the action vector), Obs the size of the robot’s own observation, Control the rate at which the policy acts, and Learn it the step budget the Studio suggests for learning a real skill with PPO (a rough order of magnitude, not a guarantee).
Tiny & maker robots
Real, desk-sized robots that people build and buy: the Open Duck Mini biped, Stanford’s ToddlerBot, the ROBOTIS OP3, the LeRobot SO-101 and low-cost arms, a two-servo Dynamixel arm and Bitcraze’s Crazyflie quadcopter. Their models come from MuJoCo Menagerie and the Open Duck project; kualia trains them on its own servers today. The arms and the quadcopter learn in a run or two; the bipeds need millions of steps.
| Robot | Kind | Joints | Obs | Control | Tier | Learn it | Notes |
|---|---|---|---|---|---|---|---|
| Duck | Open Duck Mini v2 biped | 16 | 43 | 50 Hz | hard | ~2M | The open-source 3D-printed desk biped (Apache-2.0): legs, neck, head and antennas. Starts from the Playground’s standing pose (base ≈ 0.15 m). |
| Toddlerbot | Stanford ToddlerBot humanoid | 30 | 99 | 50 Hz | hard | ~5M | A 0.5 m open-source humanoid (MIT) with arms, waist and neck; starts from its “home” pose (base ≈ 0.31 m). Heavy meshes, long budgets. |
| OP3 | ROBOTIS small humanoid | 20 | 51 | 50 Hz | hard | ~5M | A ~50 cm hobby humanoid with legs, arms and head. Ships no keyframe: it starts standing straight at zero joint angles (base ≈ 0.30 m). |
| SO101 | SO-101 arm + gripper | 6 | 12 | 50 Hz | medium | ~300K | The LeRobot desktop arm (Apache-2.0): five joints and a gripper, fixed base, ~0.4 m reach. Reach, push, press on the table. |
| LowCostArm | low-cost arm + gripper | 6 | 12 | 50 Hz | medium | ~200K | Alexander Koch’s 3D-printed arm (Apache-2.0): five joints and a gripper, ~0.25 m reach; starts from its “home” pose. |
| Dynamixel2R | 2-link Dynamixel arm | 2 | 4 | 50 Hz | easy | ~50K | Two Dynamixel servos on a 0.55 m stand (MIT). The simplest real arm: reach a target in minutes. |
| Crazyflie | nano quadcopter | 4 | 11 | 50 Hz | medium | ~300K | Bitcraze’s 27 g quadcopter (MIT): thrust plus roll/pitch/yaw moments. A zero action is the hover trim; the floor is a crash. |
Bigger real robots (MuJoCo Menagerie)
Four models of larger real robots. Go2 trains here; Spot, G1 and Panda are previews: you can plan a task, run the checks and start short tries (capped at 30,000 steps), but a real gait or grasp on them needs GPU-scale training, which kualia does not offer yet. Ask for it with the GPU runs waitlist button in the Studio.
| Robot | Kind | Joints | Obs | Control | Tier | Learn it | Notes |
|---|---|---|---|---|---|---|---|
| Go2 | Unitree robot dog | 12 | 35 | 50 Hz | hard | ~3M | A real consumer quadruped. Uses Menagerie’s position-controlled go2_mjx variant; starts from its standing “home” pose (base ≈ 0.27 m). |
| Spot | Boston Dynamics quadruped | 12 | 35 | 50 Hz | hard | ~3M | Preview, sim only. The industrial quadruped, heavier and steadier than Go2; starts standing (base ≈ 0.46 m). Runs capped at 30K steps. |
| OP3 | ROBOTIS small humanoid | 20 | 51 | 50 Hz | hard | ~5M | A ~50 cm hobby humanoid with legs, arms and head. Ships no keyframe: it starts standing straight at zero joint angles (base ≈ 0.30 m). |
| G1 | Unitree humanoid | 29 | 69 | 50 Hz | hard | ~10M | Preview, sim only. A full-size humanoid that starts from its “stand” pose (pelvis ≈ 0.79 m). Runs capped at 30K steps. |
| Panda | Franka arm + gripper | 8 | 18 | 50 Hz | medium | ~500K | Preview, sim only. 7-axis research arm plus one gripper actuator, fixed base; starts from its “home” pose. Runs capped at 30K steps. |
- Always the kualia_sim route. There is no Gymnasium environment for these robots, so every task subclasses
MjcfRobotEnvwithROBOT_ASSET = menagerie_asset("Go2")(the model’s scene: robot, floor and light), with or without world objects. - They start standing. Episodes begin from the model’s standing keyframe (
home, orstandfor G1), and each position actuator’s range is re-centred on that keyframe, so a zero action holds the pose. The browser simulator uses the same start pose and controls. - All joints are position-controlled: an action is a joint target around the standing pose, not a torque. Panda’s eighth actuator is the gripper.
Classic robots (Gymnasium)
The MuJoCo models of the Gymnasium v5 suite. They are simplified bodies that train fast, which makes them ideal for learning the workflow and for quick experiments.
| Robot | Kind | Joints | Obs | Control | Tier | Learn it | Notes |
|---|---|---|---|---|---|---|---|
| InvertedPendulum | cart-pole | 1 | 4 | 25 Hz | easy | ~30K | Cart on a rail balancing a pole. The base task already ends when the pole tilts more than 0.2 rad. |
| Reacher | 2-link arm | 2 | 10 | 50 Hz | easy | ~100K | Planar two-link arm reaching a target. Fixed base: it cannot fall. |
| Hopper | one-legged hopper | 3 | 11 | 125 Hz | medium | ~300K | Single leg that must hop forward without falling. |
| Walker2d | planar biped | 6 | 17 | 125 Hz | medium | ~500K | The classic two-legged planar walker. |
| HalfCheetah | planar runner | 6 | 17 | 20 Hz | medium | ~300K | Cannot fall and never terminates on its own; pure speed and gait. |
| Ant | quadruped | 8 | 105 | 20 Hz | hard | ~1M | Four legs, contact-rich dynamics (observation includes contact forces). |
| Humanoid | 3D humanoid | 17 | 348 | 67 Hz | hard | ~2M | Full 3D biped. High-dimensional and unstable; needs long training. |
Choosing a first robot
Dynamixel2R, InvertedPendulum and Reacher give feedback within a single short run; SO101 and LowCostArm are the quickest real arms. Hopper, Walker2d and HalfCheetah are good for locomotion tricks once you know the workflow. Panda is the quickest of the realistic robots for reaching, pressing and turning. Ant, Humanoid, Go2, Spot, OP3 and G1 are powerful but need long, expensive runs: at $0.10 per 1,000 steps a 3M-step Go2 budget costs $300, and a 10K-step run on G1 will not produce a walking robot.Menagerie models and licenses
The realistic robots come from MuJoCo Menagerie by Google DeepMind, pinned to one commit, with the robots’ physics unchanged. Each model keeps its own license file and copyright notice: Go2 and G1 (Unitree Robotics) and Spot are BSD-3-Clause; OP3 and Panda are Apache-2.0.Bring your own robot (MJCF / URDF)
Import a robot from Robots → Import your robot (also reachable from the robot shelf on Teach a new trick). kualia loads it in MuJoCo, validates it and renders a preview. A validated robot appears on the shelf marked yours and can be used exactly like a built-in one.
| Requirement | Details |
|---|---|
| File | A .zip (model + meshes/textures), a MuJoCo .xml or a .urdf. Maximum 60 MB upload, 200 MB and 600 files after extraction. |
| Allowed files | .xml .urdf .stl .obj .msh .skn .png .jpg .jpeg .mtl plus text/metadata (.txt .md .json .yaml .yml). Other files are not extracted. |
| Model choice | In a zip, kualia prefers an MJCF whose root is <mujoco> (a MuJoCo Menagerie-style scene.xml is ideal), then a URDF. |
| Paths | Mesh and include paths must be relative to the upload. Absolute and .. paths are rejected; URDF package:// URIs are rewritten to relative paths. |
| Base | Auto (MJCF as declared, URDF fixed), Floating (legged or mobile robot that can fall; a free joint is added if missing) or Fixed (arm or mechanism bolted to the ground). |
| Actuators | MJCF is simulated as-is. URDFs carry no actuators, so kualia adds one position servo (kp = 20) per hinge/slide joint. A model with no actuated joints is rejected. |
| Floor | A ground plane is added when the model has none. |
Validation then builds the robot in the task runtime and runs two 400-step rollouts (holding the pose, and random actions). The report lists joints, actuators (position or torque control), total mass, timestep, observation size and control rate.
- Errors (robot is marked needs validation and cannot be selected): no actuators, non-finite state during a rollout, exploding state, or the simulation probe failing.
- Warnings: more than 64 actuators (slow on CPU), physics timestep above 0.01 s, total mass under 10 g or over 500 kg (check units, e.g. a URDF in millimetres), or the robot falling within 0.5 s while holding its pose.
Uploaded robots always use the kualia_sim runtime: the policy acts at 50 Hz by default (the task can set CONTROL_HZ), every actuator is normalised to [-1, 1], and the observation is the robot’s joint positions (without the world x/y of a floating base) and velocities. If your MJCF ships a keyframe (ideally named home or stand; otherwise the first one is used), episodes start from it and position actuators are centred on it, exactly as for the Menagerie robots.
Build a task
Describing a trick
The brief is the single biggest lever on whether training works. Describe one skill that the robot can physically do, with a result you could measure.
What makes a good brief
- One skill at a time. “Walk forward, turn around and walk back” is three skills. Teach the first, then extend it in later versions.
- Measurable. A distance, speed, height, angle or time: “travel 3 m within 10 s without falling”. If you leave the success criterion to kualia, it picks one of these.
- Reachable from the start pose. Every robot starts near the origin, in its default pose (the realistic robots: standing). A trick that needs a different starting state has to say so.
- Say what is in the world, in your own words. “Kick the ball”, “climb the stairs”, “tighten the screw”, “ring the doorbell”, in any language: the world planner maps them to the nine object types (a screw becomes a knob, a doorbell a button) and tells you what it cannot simulate.
- Fit the body. Reacher has no legs, HalfCheetah cannot fall over, the planar robots (Hopper, Walker2d, HalfCheetah) only move in a vertical plane, and Panda is an arm bolted to the floor: it reaches, pushes, presses and turns, but does not walk.
| Brief | Why it works (or not) |
|---|---|
| Walk forward at 1 m/s on flat ground. Success: 0.8–1.2 m/s for 3 s without falling. | good One skill, a measurable speed band, sensible for Walker2d. |
| Kick the ball into the goal. | good Names a ball and a goal, so both become real objects in the world. |
| Push the box onto the orange mark. | good Box plus a target marker; a clear end state for Ant. |
| Hop up the two steps. | good Two step objects for Hopper; progress is height and distance. |
| Turn the knob two full turns. | good A knob for Panda, and object_turns gives a number to reward and a clear success test. |
| Vidayı sık. (Turkish: tighten the screw) | good Understood in any language: the screw becomes a knob, and the Plan page says so. |
| Do something cool. | weak Nothing to measure, so nothing to reward. |
| Walk to the kitchen and open the fridge. | weak The world only contains the nine object types; there is no kitchen, fridge or door to open. |
| Jump rope. | partly Ropes cannot be simulated. The planner says so, and the robot learns to jump rhythmically in place instead. |
| Balance on one leg, then do a backflip. | split it Two very different skills; train them as separate versions. |
Training settings
| Setting | Options | What it changes |
|---|---|---|
| Success criteria | Let kualia pick (default) · I’ll define it… | Your criterion goes into the brief verbatim; otherwise kualia asks for one measurable criterion reachable from the reset pose. Either way it is implemented in info["is_success"]. |
| Safety level | Relaxed · Standard (default) · Strict | Adds an “Avoid:” line: unstable states only / falling, jerky motion, excessive torque / plus self-collision and joint-limit hits, preferring smooth, energy-efficient motion. |
| Reward style | Dense shaping (default) · Goal-based | Dense rewards progress every step and learns faster; goal-based gives a clear completion bonus plus light shaping. |
| Starting difficulty | Easy (default) · Medium · Hard | Easy means short episodes and forgiving thresholds; Hard means tighter tolerances and more variation. Also feeds the difficulty estimate on the Plan page. |
Tip
Your draft is saved in the tab while you type, so you can leave to import a robot and come back to it.Build a task
alia
alia writes the task from your brief and changes it when you chat with it. It works on the task layer only; the robot rules are injected into every request.
What it generates
For a robot task, the world planner first decides which objects the trick needs. Then one request returns both the training plan (a structured spec: the trick in one sentence, a 3–5 step success scenario, reward terms, success criteria, termination and truncation conditions, observation and action components, curriculum stages) and the complete task code. The code then runs through the 13 checks. If any fail, alia is shown the failures and repairs the code, up to four attempts, always continuing from the best-scoring version so a bad fix can never replace a better one.
The spec’s trick and success_scenario are what the Plan page shows as Your trick · v<n> and What success looks like. Every new version restates both, so they always describe the current task; when the trick has changed since your first brief, the card also shows “First asked: …”.
How it picks the route
There are two ways to build a task on a robot, and the choice is made before any code is written:
| Situation | Route | What the code looks like |
|---|---|---|
| You uploaded the robot | kualia_sim | A subclass of MjcfRobotEnv with ROBOT_ASSET pointing at your validated model. |
| Realistic robot (Go2, Spot, OP3, G1, Panda) | kualia_sim | MjcfRobotEnv with ROBOT_ASSET = menagerie_asset("Go2"), always, with or without a SCENE. |
| Classic robot, and the world plan has objects | kualia_sim | MjcfRobotEnv on the same robot model via gym_asset("Walker2d"), with a SCENE. Only this route is offered, so an object can never be faked in Python. |
| Classic robot, no objects | Gymnasium wrapper | A gym.Env that creates the robot with gym.make("Walker2d-v5") and adds reward, termination and success on top of its observation and info keys. |
Whether there are objects is what the world planner decides from the trick (the first paragraph of the brief). For chat changes, the objects route is used when the planner decides on objects, your message names one, or the task already has a SCENE; if a Gymnasium-route task gains objects, alia rewrites it on MjcfRobotEnv, keeping the reward idea and episode rules. For the Gymnasium route alia is given measured facts about each robot (observation indices, info keys, when the base environment already terminates) so that thresholds hold at the reset pose; for the kualia_sim route it gets where objects can go on that robot and, for the realistic robots, the start height and joint layout.
Changing the task by chat
Open alia from any Studio screen (Edit plan, Change the world, Change with alia). Each message is handled in one of two ways:
- Question: an answer, nothing changes, no new version.
- Change: the world planner re-plans the objects for the task after your message, then alia returns a change summary, the updated plan (with a restated trick and success scenario) and code, and any breaking changes (for example a different observation size). All 13 checks run again; if any fail, the same auto-fix loop as the first build repairs them (up to three attempts, keeping the best-scoring code). A new version is saved with the summary, which also carries the planner’s note on what stands in for what and what cannot be simulated, and the reply shows each check as a pass/fail chip.
If checks still fail after the automatic fixes, use Ask assistant to fix on the Plan page: it sends the failing checks with their details and asks for a fix that keeps everything else unchanged. Training cannot start until every check passes; the server refuses the run otherwise.
Versions are cheap and safe
Every change is a new version, and runs remember which version they trained on. You can always go back: Make current on the Runs & versions page restores an older version’s code and plan and re-runs its checks. After a rollback, the next change gets the next free version number, so nothing is overwritten.Good requests
Be specific and quantitative, and change one thing at a time so the next run tells you something:
- “Double the weight of the forward-velocity term and add a 0.1 penalty per step while the torso pitch exceeds 0.5 rad.”
- “Move the ball to x = 1.5 m and give it a jitter of 0.3 m in x and y.”
- “Add a goal 4 m ahead and reward the ball moving toward it instead of the ball’s speed.”
- “End the episode when the ball rolls behind the robot.”
- “Shorten episodes to 500 steps and make the success threshold 2 m instead of 3 m.”
- “Why do most episodes end after about 20 steps?” (a question: no new version)
After a run, the AI analysis writes a ready-made instruction; Create v<n> from the analysis or Apply the AI suggestions sends it to alia for you. alia panel can also propose suggestions of its own.
Build a task
The world planner
Before alia writes a robot task, and again on every chat change, a world planner decides which physical objects the trick needs. It reads meaning, not keywords, so you can describe the trick in your own words and language.
Your words
the trick or a chat message, in any language
World planner
one short AI call; keywords if it fails
Objects + note
types from the nine, what stands in for what, what can’t be simulated
Task code
SCENE must contain exactly these objects
Objects start clear
fails if a planned type is missing
SCENE must contain, and the checks enforce it.What it decides
- Which objects, from the nine types (ball, box, step, ramp, wall, goal, target, knob, button), one entry per object and at most 8. Tricks about the robot’s own body (walk, run, jump, balance, flip, dance, turn) get no objects: distances are measured from the robot itself, so no target is added just to mark one.
- A note on your words. Everyday things are mapped to the closest type: a screw, bolt, valve or tap is a knob, a doorbell or switch a button, a cup a small box, a table a raised step, stairs several steps of increasing height. The note says so plainly.
- What cannot be simulated. Liquids, cloth, ropes, other robots, people or fine finger dexterity are left out, with a short explanation of what the robot will learn instead.
- Where they go, in one sentence, using the robot’s placement facts.
| You write | Objects | Note shown to you |
|---|---|---|
| Walk forward without falling | none | — |
| Climb three stairs and come back down | step × 3 | The stairs are three steps of increasing height. |
| Tighten a screw · vida sıksın | knob | The screw is a knob; tightening it means turning its lever clockwise. |
| Ring the doorbell | button | The doorbell is a push button. |
| Carry the cup to the table | box, step | The cup is a small box and the table is a raised platform. |
| Jump rope · ipten atlasın | none | A rope can’t be simulated; the robot learns to jump rhythmically in place. |
Where you see it
The note and the “cannot be simulated” line appear under Your trick on the Plan page, and after a chat change they are added to the version’s change summary. The decision is stored with the task’s spec (kualia.objects, kualia.note, kualia.unsupported), and the Objects start clear check fails while the SCENE lacks a planned object type.
On a chat change the planner sees the current world and returns the full list of objects after the change, so a request like “add a second ball” or “remove the wall” is planned against what is already there. If the planner call fails, kualia falls back to keyword matching on the trick (English and Turkish words for ball, box, stairs/steps, ramp, wall and goal), keeping the objects already in the world on a chat change. The planner is part of the plan or change request and billed with its usage.
Build a task
Task code
A task is a Gymnasium environment in a single Python file. You never have to write one, but knowing the shape makes it easy to read the generated code and ask for precise changes.
The kualia_sim runtime (MjcfRobotEnv)
Tasks with world objects, tasks on the realistic robots and tasks on uploaded robots subclass kualia_sim.MjcfRobotEnv. ROBOT_ASSET names the model: gym_asset("Walker2d") for a classic robot, menagerie_asset("Go2") for a realistic one, or your uploaded model. The base class owns everything that could break the physics: loading the model, adding the SCENE objects, mapping actions to actuators, the control rate, assembling observations, rendering and seeding. The task overrides five hooks:
| Hook | Returns | Default |
|---|---|---|
compute_reward(self, action) | float, per step | forward velocity + ALIVE_BONUS (1.0) − CTRL_COST (0.001) × Σ action² |
is_terminated(self) | bool | floating base: base below FALL_HEIGHT_RATIO (0.5) × start height, or upside down (upright < 0). Fixed base: never. |
extra_observation(self) | array or None | None. Task features appended to the observation (a command, a phase…). It is also called once while the base measures the observation size, so it must only read robot and object state, never self.observation_space, and return the same length every time. |
is_success(self) | bool, read at episode end | moved more than 1 m forward without terminating |
on_reset(self) | None | nothing. Randomise targets or commands here with self.np_random. |
Robot state available inside the hooks:
| Attribute | Meaning |
|---|---|
base_position | world position of the robot’s root body (x, y, z), metres |
base_height | absolute height of the root body |
initial_base_height | root height at the start pose (read-only) |
x_position | root x (forward) |
forward_velocity | x velocity of the root, per control step |
base_velocity | linear velocity of the root body [vx, vy, vz], world frame, m/s |
base_angular_velocity | angular velocity of the root body [wx, wy, wz], world frame, rad/s |
upright | 1 = upright, 0 = on its side, −1 = upside down |
base_orientation | root quaternion (w, x, y, z) |
joint_positions / joint_velocities | the robot’s joints (objects excluded) |
max_steps, dt, np_random | episode cap, control period in seconds, seeded RNG |
Class attributes a task may tune: CONTROL_HZ (50), ALIVE_BONUS (1.0), CTRL_COST (0.001), FALL_HEIGHT_RATIO (0.5), RESET_NOISE (0.01, uniform noise on joint positions and velocities at reset, around the start pose: the model’s standing keyframe when it has one). Keyword arguments passed to __init__ become attributes, which is how curriculum knobs are expressed. The base class ignores attempts to reassign the observation space, the action space or the start height, and replaces a non-finite reward with −10 and ends the episode.
A complete task, using the object helpers from World objects:
Success only counts on a full episode
InMjcfRobotEnv, info["is_success"] is true only when the episode ended by reaching max_steps and is_success() holds. An episode that ends through is_terminated() is never a success, so do not terminate on success; let the robot hold the result until the time limit.The Gymnasium wrapper route
Tasks on a built-in robot without objects usually wrap the Gymnasium model directly. The rules alia follows: create the robot with gym.make inside __init__ and never replace it, keep its action space, start from its observation space (appending task features is allowed if the space is widened), keep the base environment’s fall detection, truncate at max_steps, set info["is_success"], pass the seed through on reset and delegate rendering.
What the task code may import is restricted; see the security scan. NumPy, Gymnasium, math and kualia_sim are what tasks normally need.
Build a task
World objects
Objects are real MuJoCo bodies declared in a SCENE list on the task class. The same list builds the world in the checks, in training and in the browser simulator. There are nine types.
SCENE below (not to scale vertically). z points up, units are metres.Types and defaults
| Type | Behaviour | Defaults (metres, kg) | In the observation |
|---|---|---|---|
ball | movable | radius 0.11, mass 0.45 | position + velocity |
box | movable | size [0.15, 0.15, 0.15], mass 2.0 | position + velocity |
step | fixed | size [0.4, 0.6, 0.08] | not observed |
ramp | fixed | length 1.5, width 1.0, height 0.2 | not observed |
wall | fixed | size [0.05, 1.0, 0.3] | not observed |
goal | fixed | width 1.2, height 0.6 | position |
target | fixed, no collision | radius 0.25 | position |
knob | fixed base, cap turns on a vertical hinge | radius 0.08, height 0.05, lever 0.12, damping 0.05 | position + angle + angular velocity |
button | fixed base, spring-loaded cap pushed down | size [0.08, 0.08, 0.03], travel 0.02, stiffness 60 | position + press position + velocity |
- Coordinates: x forward, y left, z up; the robot starts near the origin.
posis[x, y](the object rests on the floor; its height is computed), within 20 m of the origin. A ball or box may also be given[x, y, z]to start higher. - Fixed pieces always stand on the floor. For step, ramp, wall, goal, target, knob and button a z is ignored, so nothing floats: make a taller step with a bigger
size[2]. - Sizes:
sizeis half extents. Clamped ranges: radius 0.02–1.0, size 0.01–3.0, length/width/height 0.02–6.0, mass 0.01–50, lever 0–1.0, damping 0–10, travel 0.005–0.2, stiffness 0–2000. - Ramp rises along +x; its lower edge meets the floor at
pos.x − length/2. Goal is two posts and a crossbar; itsposis the centre of the goal mouth. Target is a flat marker without collision, a place to reach. - Stairs are several steps in a row along +x, each one taller than the last: for example steps at x = 1.0, 1.4 and 1.8 m with
size[0.2, 0.6, 0.05], [0.2, 0.6, 0.10] and [0.2, 0.6, 0.15] (10 cm risers, 40 cm treads). - Names must be unique (letters, digits,
_); the helpers use them. At most 8 objects. Optional fields:rgba,observe(override whether it is observed),mass. - Numbers: plain numbers are simplest, but a
SCENEmay also use class-level numeric constants and simple arithmetic (STEP_W = 0.2, then"pos": [1.0 + 2 * STEP_W, 0.0]). kualia evaluates them safely from the source; nothing is executed. - Jitter
[dx, dy]moves a movable object by a random offset at every reset, so the policy cannot memorise one position. Fixed objects ignore it.
Knobs and buttons
Two mechanisms are fixed in place and move in one degree of freedom, which makes them stand-ins for many everyday things:
- knob: a fixed grey base with a cap that turns freely on a vertical hinge (no limit, light damping), plus a lever that gives a leg, arm or gripper something to push. A screw, bolt, valve, dial, crank or tap.
- button: a spring-loaded, gravity-compensated push button. The cap rests fully up and only a push moves it down, by at most
travel; the spring pushes it back. A switch, doorbell or key.
Reading the world in the hooks
| Helper | Returns |
|---|---|
object_position("ball") | world position [x, y, z] |
object_velocity("ball") | linear velocity [vx, vy, vz] (zeros for fixed objects) |
object_offset("ball") | object position minus robot base position |
object_distance("ball") | horizontal distance between robot base and object |
robot_touches("ball") | True while any robot part touches the object |
objects_touch("ball", "goal") | True while the two objects touch |
object_initial_position("ball") | where it was placed this episode (after jitter) |
object_angle("knob") | knob angle in radians, 0 at reset, unbounded (2π per full turn) |
object_angular_velocity("knob") | knob angular velocity, rad/s |
object_turns("knob") | signed full turns since the start of the episode |
button_depth("button") | how far the button is pressed, 0 … travel metres |
button_pressed("button") | True while pressed at least 60 % of its travel |
The knob helpers only accept a knob and the button helpers only a button; calling them on another type raises an error.
Objects in the observation
Observed objects are appended to the policy’s observation automatically, in SCENE order: the object’s position relative to the robot base (3 values), plus its velocity for movable objects (3 values, clipped to ±20 m/s). A knob adds its angle and angular velocity, a button its slide position (negative while pressed) and velocity (1 value each). In the example, the ball adds 6 values and the goal 3; a knob or a button adds 5. The task must not add them again in extra_observation, and leaving extra_observation undefined keeps the policy runnable live in the browser.
The “Objects start clear” check
After three resets, objects must not start inside the robot (more than 5 mm deep), inside each other, below the floor, or right under the robot (a ball or box within 0.15 m of the base horizontally). A 60-step random rollout must keep every object physically sane (no speeds above 60 m/s, not falling through the floor). The check also fails when the task’s SCENE lacks an object type the world planner decided on (stored with the spec; for older tasks, the objects named in the brief). Keeping objects clear of the start pose, within the robot’s placement range below, avoids almost all failures.
Where objects go, per robot
Objects are only useful where the robot can reach them. alia and the world planner are given this guidance for each robot:
| Robot | Placement |
|---|---|
| InvertedPendulum | A cart on a rail; it cannot touch the floor. Objects are rarely useful, prefer none. |
| Reacher | Fixed base at the origin; the fingertip reaches 0.08–0.21 m and moves about 1 cm above the floor. Objects within 0.1–0.2 m of the origin and low (e.g. knob radius 0.03, height 0.02). |
| Hopper, Walker2d | Planar: objects on the line y = 0, 0.8–3 m ahead. Low steps (risers ≤ 0.1 m; Walker2d treads ≥ 0.4 m). |
| HalfCheetah | Planar: objects on y = 0, 1–4 m ahead. Obstacles lower than ~0.2 m can be jumped. |
| Ant | Moves in any direction. Objects 1–3 m away; buttons and knobs are pressed or turned with a leg. |
| Humanoid | Stairs: risers ≤ 0.1 m, treads ≥ 0.4 m, first step ≥ 0.8 m ahead. Objects to kick or push 1–2 m ahead. |
| Go2 | Objects 0.8–3 m away; risers ≤ 0.08 m; a ball to push ~0.1 m radius. |
| Spot | Objects 1–3 m away; risers ≤ 0.15 m. |
| OP3 | Objects 0.3–1.5 m ahead; steps ≤ 0.03 m high; a ball to kick ~0.05 m radius. |
| G1 | Objects 1–2 m ahead; stair risers ≤ 0.1 m. |
| Panda | Fixed base; the hand reaches about 0.3–0.8 m. Objects 0.4–0.6 m in front and within ±0.3 m sideways, small (box size ≤ 0.03, knob radius 0.04, button size [0.04, 0.04, 0.015]). |
Inspect the world before training
The World panel on Plan & world renders the exact composed scene. Press play for a zero-torque drop test: objects that jump or fly away are overlapping something at the start.Build a task
Rewards
The reward is the only thing the policy optimises. It is computed at every control step, and training maximises its sum over an episode.
Dense shaping vs goal-based
Dense shaping (the default) pays for progress every step: velocity toward a target, distance closed to a ball, height gained. The robot gets a useful signal from its very first attempts, which is why it learns faster. Goal-based gives a clear bonus for completing the goal plus light shaping; the behaviour is cleaner but learning is slower, because the bonus is rare early on.
A reward is normally a weighted sum of terms. An illustrative locomotion reward (your task’s terms and weights will differ):
| Term | Weight | Meaning |
|---|---|---|
| forward velocity | 1.0 | metres per second along +x |
| upright | 0.5 | 1 when upright, less when tilted |
| control cost | −0.001 | sum of squared actions (smooth, efficient motion) |
| fall penalty | −10 | once, when the episode terminates by falling |
Explain the reward on Plan & world lists the terms from the training plan. Weights, and the donut of their absolute sizes, are shown only when the plan states numeric weights; otherwise the exact scaling lives in the task code (open Generated task code).
How rewards are scaled during training
Training normalises rewards with a running estimate (and clips normalised values to ±10), so absolute scale matters less than the balance between terms. Per-step rewards should still stay roughly within [−10, 10]; the Reward is sane check warns when random actions produce values outside that range. The charts always show the raw episode return, in the task’s own units.
Common pitfalls
| Symptom | Likely cause | Fix |
|---|---|---|
| The robot stands still, reward looks fine | A survival / alive bonus that outweighs the progress terms: standing still collects it risk-free. | Lower the bonus or make it conditional on progress; raise the progress weight. |
| The robot falls on purpose | Net negative reward per step (penalties larger than rewards), so ending the episode early is optimal. | Make a normal, upright step slightly positive; keep penalties smaller. |
| Learnability check fails | The reward does not depend on anything the actions change. | Reward robot or object state that the actions influence. |
| Reward is sane check fails | NaN/inf (division by a quantity that can be zero) or a constant reward. | Guard divisions, clip velocities, make terms vary. |
| The ball flies sideways | Rewarding object speed in any direction (reward hacking). | Reward progress toward the goal instead, as in the task example. |
| No progress in a short run | Goal-based reward on a hard trick: the bonus is never seen. | Switch to dense shaping or add a curriculum stage. |
Tip
When a run disappoints, the AI analysis on the run’s results page reads the curve, the evaluation episodes and the code, and proposes concrete reward changes with current and proposed values.Build a task
Success & termination
An episode ends in one of two ways, and the difference matters for learning and for the success rate.
| Meaning | Examples | |
|---|---|---|
| terminated | The episode failed or hit a hard stop. | Fell over, flipped, left the allowed area. |
| truncated | Time ran out: max_steps control steps were reached. | The robot kept going until the episode length. |
Episode length (max_steps) is a task parameter; the checks measure the cap the code actually enforces and the Studio shows it on the Training screen (“steps / episode”). The default termination in the kualia_sim runtime ends the episode when a floating robot’s base drops below half its start height or turns upside down. Built-in robots on the Gymnasium route keep the base environment’s own fall detection (for example Hopper ends when the torso is too low or tilts too far).
The success criterion
Success is reported in info["is_success"] and is meaningful at the end of an episode. It drives the success rate on the Training chart (share of the last 50 training episodes) and in the results (share of the evaluation episodes).
- In the kualia_sim runtime, success requires reaching the time limit without terminating, and
is_success()returning true at that moment. - If a task never sets
is_success, kualia counts an episode with a positive total reward as a success. Treat the success rate of such a task with care, and ask alia to implement an explicit criterion.
Every threshold must hold at the reset pose
The most common broken task ends every episode at step one: a termination test on a quantity that is zero or out of range at the start. On Hopper and Walker2d,z_distance_from_origin is relative (≈ 0 at reset), not a height; on HalfCheetah the first observation value is a z offset, not a height. The Episodes survive the reset check catches this before training.Build a task
Observations & actions
Observations are what the policy sees every step; actions are what it sends to the actuators.
Observations
kualia_sim tasks (every task on a realistic or uploaded robot, and classic-robot tasks with objects) observe the robot’s joint positions (dropping the world x/y of a floating or planar base, so the policy does not depend on where it is on the floor), the joint velocities, then every observed object, then the optional extra_observation() values. A ball or box adds its relative position and velocity (6 values), a goal or target its relative position (3), a knob its relative position, angle and angular velocity (5), a button its relative position, slide position and velocity (5).
- qposjoint positions (world x/y of the base dropped)
- qveljoint velocities, clipped to ±50
- ballrel. position 3 + velocity 3
- goalrel. position 3
- extraextra_observation()
Gymnasium-route tasks start from the robot’s own observation (the Obs column in the robot table) and may append task features such as a target speed or a phase, widening the space accordingly.
The Plan page lists the observation signals from the training plan, including the objects (“position relative to the robot + velocity”). The Observations tab of the World panel shows live base values during the drop test: height, roll / pitch / yaw and velocity.
During training observations are normalised with a running mean and standard deviation (clipped to ±10). That normalisation is exported inside the ONNX file, so on the robot you feed raw values in the same order.
Actions
The action is one continuous value per actuator. In the kualia_sim runtime every actuator is normalised to [−1, 1] and mapped linearly onto its control range: −1 is the low end, +1 the high end. For position servos that is a joint target, for motors a torque. Gymnasium-route tasks use the robot’s own action space. Actions outside the bounds are clipped.
Robots that ship a standing keyframe (the realistic robots, and uploaded models with a keyframe) start every episode from it, and each position actuator’s range is shifted so that its centre is the keyframe’s command (the width stays the same). A zero action therefore holds the standing pose, and the policy learns offsets from it.
Build a task
Automated checks
Every task version runs 13 checks in an isolated sandbox. Training starts only when all 13 pass, so training steps are never spent on a task that breaks at step one.
| # | Check | Group | What it tests |
|---|---|---|---|
| 1 | Code parses syntax | setup | The file parses as Python. If it does not, every other check is skipped. |
| 2 | Security scan security | setup | Static scan before anything runs: blocked modules, eval / exec / compile / __import__, and .system / .popen / .spawn / .fork calls. A violation skips the runtime checks. |
| 3 | Environment loads import | setup | Finds the environment class (the most-derived gymnasium.Env in the file), instantiates it and confirms it has an observation and an action space. |
| 4 | Reset works reset | setup | reset(seed=42) returns a tuple (observation as a NumPy array, info dict). |
| 5 | Step works step | setup | One random action returns the five-tuple (obs, reward, terminated, truncated, info) with the right types. |
| 6 | Observation signals obs_space | physics | The first observation and ten more after random steps all lie inside the declared observation space. |
| 7 | Action space valid action_space | physics | 100 sampled actions lie inside the action space, and stepping with one works. |
| 8 | Reward is sane reward_sanity | learning | 100 random steps give numeric, finite rewards that are not all identical. Values outside [−10, 10] produce a warning. |
| 9 | Deterministic reset determinism | physics | Two 20-step rollouts with the same seed (and the same action seed) give identical observations and rewards. |
| 10 | Learnability estimate action_effect | learning | Learnability estimate: over five seeds, the 50-step return with random actions must differ from the return with zero actions. If actions cannot change the return, nothing can be learned. |
| 11 | No unstable physics stability | physics | Three rollouts of up to 300 steps, one with saturated bang-bang actions: finite observations and rewards, observations inside finite declared bounds, no explosion (|obs| ≤ 1e6), and episodes that actually end. |
| 12 | Episodes survive reset episode_length | learning | Five random-action episodes (up to 300 steps) must last more than two steps on average. Also reports the episode cap the code enforces. |
| 13 | Objects start clear scene | physics | World objects start clear of the robot and of each other, above the floor, stay physically sane for 60 random steps, and every object type the world planner decided on exists in SCENE. Passes on an open floor. |
- Runtime checks run in parallel, each in a separate subprocess with a 20-second limit and with server secrets removed from its environment.
- Blocked modules:
subprocess socket socketserver asyncio multiprocessing requests httpx urllib urllib2 urllib3 http ftplib smtplib telnetlib paramiko pickle cpickle marshal shelve ctypes cffi pty shutil pathlib glob sqlite3 importlib imp runpy webbrowser signal resource fcntl. - Failing checks are repaired automatically: up to four attempts when the plan is first built, up to three after every chat change, always keeping the best-scoring code.
- On Plan & world, click a check to read its detail message, Re-run to run them again, and Ask assistant to fix to send any remaining failures to alia. The Training readiness ring summarises them.
Passing checks do not guarantee learning
The checks prove the task is well-formed, stable and learnable in principle. Whether the reward describes the behaviour you want is something only training, the recordings and the analysis can tell you.Train & iterate
Training
Training runs on kualia’s servers with PPO (Proximal Policy Optimization) from Stable-Baselines3. You choose how many steps the robot practises; everything else is set up for you.
What happens in a run
- Algorithm: PPO with a multilayer-perceptron policy and Stable-Baselines3’s default hyperparameters. The Studio always trains with PPO.
- Normalisation: observations and rewards are normalised with running statistics (clipped to ±10). The chart and the evaluation still report raw rewards.
- Checkpoints: the untrained policy is recorded first, then at 25, 50 and 75 % of the budget, then the final policy.
- Evaluation: after training, the final policy plays 5 episodes deterministically (seeds 0–4, frozen normalisation). These are the numbers on the results page.
- Queue: when the training servers are busy the run shows Queued and starts automatically.
- 0 %untrained policy recorded
- 25 %first live checkpoint policy
- 50 %checkpoint
- 75 %checkpoint
- finalmodel saved · up to 30 evaluation episodes
Practice budgets
The Plan page, the Training page and Train again, as it is offer three budgets, each with its price and a time estimate (based on the throughput of this task’s earlier runs when there are any):
| Budget | Steps | Use it to |
|---|---|---|
| First try | 10K | Check that the robot moves sensibly and episodes do not end at once. |
| More practice | 50K | See early behaviour; enough for the easiest robots. |
| Learn it | robot-specific | A typical budget to actually learn a skill on this robot. |
| Family | Learn it budget per robot |
|---|---|
| Classic | InvertedPendulum 30K · Reacher 100K · Hopper 300K · HalfCheetah 300K · Walker2d 500K · Ant 1M · Humanoid 2M |
| Realistic | Panda 500K · Go2 3M · Spot 3M · OP3 5M · G1 10M |
| Uploaded | 300K |
These are rough orders of magnitude, not guarantees; steps come out of your plan’s monthly quota (Starter 300K, Pro 1M; see Plans & training steps), and a single run is capped per plan (Free 20K, Starter 500K, Pro 2M); Keep training continues a policy across several runs.
The Training screen
- Live simulation: a 3D replay of the latest checkpoint, the recorded video, the physics drop test, and the live policy (see below).
- Recent attempts: the checkpoints as a film strip. Each tile shows Full episode or Ended at n / max and the episode reward; the best one is outlined.
- Learning progress: average episode reward with a min/max band, plus success rate, episodes, elapsed and remaining time and throughput. A point is added about every 5 % of the run, averaged over the last 50 training episodes. The phase bar (Warm-up → Exploration → Stabilization → Convergence) simply tracks progress through the budget.
- Training log: readable events derived from the curve and checkpoints (reward improved, success rate reached, episodes last longer, most episodes still end early, checkpoint recorded).
- Run statistics: best and latest checkpoint reward, average episode length, early ends in evaluation, throughput and the previous best run.
Why the checkpoint reward is higher than the chart
Training episodes are played by the exploring policy, which adds random noise to every action; that is how PPO discovers better behaviour. Checkpoints and evaluation use the deterministic policy (its best guess, no noise), so their reward is usually higher than the average on the chart.Live policy during training
From the 25 % checkpoint on, the newest checkpoint policy is saved while training continues and exported to ONNX on request (GET /api/rlforge/train/{env_id}/onnx/live?run_id=…). In Live policy mode the simulator loads it and runs it in your browser; it refreshes as new checkpoints are recorded. This only works for tasks that the browser can simulate (see Browser simulator).
Stop, train again, keep training
- Stop training ends the process. A stopped run is not refunded.
- Train v<n> again starts a fresh policy on the same version with the same budget, useful to see how much results vary between runs.
- Keep training continues from the model of the most recent completed run and adds at least 50K steps. If that model cannot be loaded (for example the observation size changed in a later version), a fresh policy is trained instead.
Why short runs don’t teach complex robots
PPO learns from experience: each update uses a batch of steps, and a skill emerges over many updates. On InvertedPendulum 10K steps already shows progress. On Humanoid (17 actuators, a 348-value observation, an unstable body) 10K steps is only a few batches, and the policy is still close to random; a skill typically needs around 2M steps. The realistic robots are harder still: a first gait on Go2 or Spot is in the millions of steps, and G1 with 29 joints in the order of 10M. A short run on a big robot is still worth it: it shows whether episodes survive, whether the reward rises and whether the robot is heading the right way, before you pay for a long run.
Train & iterate
Results & iteration
Training is a loop: run, look, change one thing, run again. The Results stage keeps every run of every version side by side.
Runs & versions
- Design a new run drafts a message to alia for the next version: change the world, the reward, or how an episode starts and ends. If the last run was analysed, Apply the AI suggestions sends its instruction directly.
- Train again, as it is trains the current version with a chosen budget, or keeps training from its best run.
- The run list can be filtered by version and status and sorted by newest or best reward. Versions that were never trained appear too, with Review & train (current) or Make current.
- Compare: tick two completed runs to overlay their reward, success rate and episode length curves.
One run’s results
| Panel | What it shows |
|---|---|
| Best policy rollout | The run’s policy in the simulator, live in the browser when the task supports it, otherwise the 3D replay or the video. |
| Evaluation performance | Average reward and success rate over training. |
| Evaluation episodes | Up to 30 deterministic episodes (seeds 0–29; after the first 10, evaluation stops at a 90-second budget): success count with a 95% Wilson interval, one square per episode, then reward, length and outcome (success, no success or ended early) for each. |
| Best checkpoint | The highest-reward checkpoint with its step, reward and length. |
| Failure cases | Evaluation episodes that ended early, plus the analysis’ observations with a severity (low / medium / high). |
| Result summary | Success rate, mean reward, episode length, early ends, episodes trained, training time, each compared with the previous run. |
| Actions | Compare with other runs, export the policy, train again or keep training, create the next version from the analysis. |
The AI analysis
The first time you open a run’s results, an analysis runs automatically and is stored with the run, so later visits cost nothing. It reads the training curve, the evaluation numbers, the recorded episodes and the task code, and returns:
- a 2–3 sentence summary of what the robot does and the main problem,
- 2–4 observations with severity,
- 3–6 proposed changes, each tagged reward, termination, observation, curriculum or hyperparameters, with the current and proposed value and why,
- an optional curriculum and a ready-to-send instruction for alia.
Re-analyze runs it again (the button shows the estimated cost). Create v<n> from the analysis sends the instruction to alia, which creates the next version and re-runs the checks.
Rolling back
Make current restores an older version’s task code and plan and re-runs its checks. Runs are never deleted by a rollback, and a later change is saved under the next free version number.
A useful rhythm
- 10K-step run: does the behaviour point the right way?
- Read failure cases and the analysis; change one thing.
- Compare the two runs; keep the better version current.
- When the direction is right, spend the Learn it budget or keep training.
Train & iterate
The browser simulator
The Studio runs MuJoCo compiled to WebAssembly in your browser, so you can inspect the world and watch policies without downloading anything.
Modes
| Mode | What drives the robot |
|---|---|
| Live policy (in-browser) | The exported ONNX policy, evaluated with onnxruntime-web, acting in MuJoCo in real time. The status line shows episode, step, time, falls and inference time per step; episodes restart after a fall or at the end. |
| 3D replay (MuJoCo) | The recorded state of a checkpoint’s evaluation episode, played back in 3D. |
| Recorded video | The MP4 rendered on the server for that checkpoint. |
| Physics drop test | Zero torque: the robot and the world simply fall under gravity. Good for spotting objects that overlap at the start. |
It appears on Plan & world (the World panel, starting in drop-test mode), on Training, on each run’s results (starting in live-policy mode) and on Export (the exact ONNX file you download). The realistic robots are loaded with all their mesh files, so the first view of one takes a moment longer; they start in their standing pose, as in training.
Controls
- Drag to orbit, scroll to zoom; Follow robot keeps the camera on it, Recenter resets the view.
- Play / Pause, playback speed 0.25×–2×, Reset.
- Push shoves the robot sideways for 0.15 s: a quick robustness test for a live policy.
- In video mode: play, pause, reset and fullscreen.
Requirements
The simulator needs SharedArrayBuffer, which browsers only provide on cross-origin-isolated pages; kualia serves its app pages with the required headers. Use a current Chrome, Edge or Firefox. Where isolation is unavailable the simulator shows “3D simulator unavailable” and the recorded video still works.
When live policy is not available
To run a policy in the browser, kualia must rebuild the exact observation the task fed the policy in training. It derives a declarative recipe from the task, checks it step by step against the real environment on the server, and ships it only if they agree. Supported:
- kualia_sim tasks that do not add
extra_observation()features (world objects are included); - Gymnasium-route tasks that pass the robot’s observation through unchanged, apply actions directly and keep the robot’s control period.
Custom Python observation features, action remapping or a different control period make the task unsupported; the viewer then says “Live policy off for this task” with the reason and shows the recorded rollout. The Export page lists the same result under Browser simulation.
Deploy & account
Export & deployment
Export turns the best run of a task into a single ONNX file that runs anywhere onnxruntime runs, from a laptop to a Raspberry Pi or Jetson.
What you get
- The best completed run (highest mean return) is exported. The file is named
<task>_run<id>_PPO.onnx. - ONNX opset 17, input
obs, outputaction, dynamic batch dimension. - The deterministic policy: for PPO, the mean action, exactly what
model.predict(obs, deterministic=True)returns in Stable-Baselines3. - Observation normalisation baked in as the first layer (training mean and standard deviation, clip ±10). Feed raw values.
- Actions are clipped to the action-space bounds inside the graph.
- Verified: the model passes the ONNX checker and is compared with the original policy on 16 random observations; an export that differs by more than 0.001 is rejected.
- Metadata is embedded in the ONNX file (
metadata_props) and saved as JSON next to it; the Export page shows it, with the file size and SHA-256 checksum.
raw observation
float32 [1, obs_dim], same order as in simulation
normalise
(obs − mean) / std, clip ±10 · baked in
policy network
deterministic: the mean action
clip
to the action-space bounds
action
float32 [1, act_dim]
.onnx file (orange: part of the graph). No PyTorch or Stable-Baselines3 is needed on the robot.The Export page
- Try the exported policy: the same ONNX file, running live in the browser simulator. Push the robot to test robustness.
- Export summary: input observation schema, output joint command schema, normalisation, runtime target, control rate, package name and version (task version · run id).
- Deployment handoff: export completed, model validated, normalisation embedded, browser simulation supported, artifact packaged, plus the integrity hash.
- Download File, Copy Runtime Instructions and a minimal runtime snippet.
Running it on the robot
For kualia_sim tasks, each action value maps onto the actuator’s control range as low + 0.5 · (a + 1) · (high − low), the same as in simulation (for a position servo, a joint target). The action_space entry in the metadata gives the bounds of the policy output. On the realistic robots (and uploaded models with a keyframe) each position actuator’s range is centred on the standing keyframe, so a zero action holds the standing pose; use those same shifted ranges on the robot. When the task supports browser simulation, the metadata’s browser_sim recipe lists them exactly (ctrl.low, ctrl.high).
Sim-to-real
A policy trained in simulation can behave differently on hardware: motor latency, friction, battery voltage. Start at low gains and speeds and keep an emergency stop within reach. Match the observation layout exactly (joint order, radians and rad/s, the base-pose convention used in simulation). If the robot’s control loop runs at a different rate, retrain withCONTROL_HZ set to the real rate rather than resampling actions. Your runtime must support ONNX opset 17 (onnxruntime 1.16 or newer).Direct push to a robot runtime is on the roadmap; today the handoff is the ONNX file.
Deploy & account
Plans & training steps
A plan is two numbers: how many training steps your robot gets every month, and alia, the assistant that builds and edits tasks. Steps are counted per run and taken from your monthly quota when the run starts; there is nothing else to pay per run.
| Plan | Price | Training steps / month | alia | Trainings at a time | World Designer | Step packs |
|---|---|---|---|---|---|---|
| Free | $0 | 20K once, to try it (1 project) | builds your first task | 1 | no | no |
| Starter | $20 / month | 300K | included | 1 | no | no |
| Pro | $50 / month | 1M | included | 3 | yes | 250K for $10 · 500K for $20 |
| Lab | Let's talk | sized to your lab + GPU training | included | 6 | yes | yes |
When the steps run out, a run is refused with a clear message: Starter moves up to Pro, Pro adds a step pack (as often as needed; packs never expire). alia has a monthly allowance inside each plan; if a month is unusually heavy it pauses until the plan renews, and your work is saved.
| Budget | Steps |
|---|---|
| First try | 10K |
| More practice | 50K |
| Learn it · InvertedPendulum | 30K |
| Learn it · Reacher | 100K |
| Learn it · Hopper | 300K |
| Learn it · Walker2d | 500K |
| Learn it · HalfCheetah | 300K |
| Learn it · Ant | 1M |
| Learn it · Humanoid | 2M |
| Learn it · Dynamixel2R | 50K |
| Learn it · LowCostArm | 200K |
| Learn it · SO101 | 300K |
| Learn it · Crazyflie | 300K |
| Learn it · Duck | 2M |
| Learn it · Toddlerbot | 5M |
| Learn it · OP3 | 5M |
| Learn it · Panda | 500K |
| Learn it · Go2 | 3M |
| Learn it · Spot | 3M |
| Learn it · G1 | 10M |
Refunds
- A run that fails with an error gives its steps back automatically; the run statistics show it.
- A run you stop keeps its steps spent, and so does a run that completes but does not learn the trick.
See Pricing for the plan comparison. Buy step packs or change plan under Settings → Plan & steps.
Deploy & account
API reference
The Studio is built on a REST API. These are the endpoints it uses, for reference.
Authorisation
Send a personal API key (Authorization: Bearer kua_…, created under Settings → API keys) or your signed-in session token. Keys act as you — credits and plan limits apply — and never reach admin features. Endpoints may still evolve; the MCP server is the stable way for agents to drive kualia.| Method | Path | Purpose |
|---|---|---|
| GET | /api/rlforge/robots | Built-in robots and your uploads |
| POST | /api/rlforge/robots/upload | Upload and validate a robot model |
| POST | /api/rlforge/generate | Build a plan: { description, difficulty, robot_model } |
| GET | /api/rlforge/envs/{env_id} | A task: code, plan, checks, world |
| GET | /api/rlforge/envs/{env_id}/scene.xml | The composed world as MJCF |
| POST | /api/rlforge/envs/{env_id}/validate | Run the 13 checks again |
| GET | /api/rlforge/envs/{env_id}/versions | Task versions with change summaries |
| POST | /api/rlforge/builder/{env_id}/chat | Assistant message: { message } |
| GET | /api/rlforge/builder/{env_id}/history | Assistant conversation |
| POST | /api/rlforge/builder/{env_id}/rollback | Make a version current: { version } |
| POST | /api/rlforge/builder/{env_id}/analyze | AI analysis of the latest completed run |
| GET | /api/rlforge/pricing | Current prices and estimates |
| POST | /api/rlforge/generate | Build a task: { description, robot_model, difficulty, async: true } → { id, status: "generating" } |
| POST | /api/rlforge/train/{env_id} | Start a run: { total_timesteps, algorithm, continue_from } |
| GET | /api/rlforge/train/{env_id}/status | Latest run status |
| GET | /api/rlforge/train/{env_id}/curve | Training curve of the latest run |
| GET | /api/rlforge/train/{env_id}/report/{run_id} | Curve and results of one run |
| POST | /api/rlforge/train/run/{run_id}/stop | Stop a running or queued run |
| GET | /api/rlforge/train/{env_id}/onnx?run_id= | Download the ONNX policy |
| GET | /api/rlforge/train/{env_id}/onnx/meta?run_id= | Policy metadata |
| GET | /api/rlforge/train/{env_id}/onnx/live?run_id= | Newest checkpoint policy of a running run |
Starting a run returns 409 checks_failing when not all checks pass, 402 steps_exhausted when your plan has fewer training steps left than the run needs, 409 too_many_runs above your plan’s parallel runs and 403 plan_limit_exceeded above its steps per run. AI calls return 402 insufficient_credits when the plan’s monthly assistant allowance is used up.
Deploy & account
Coding agents (MCP)
Claude Code, Cursor, Codex and any other MCP client can drive kualia: pick a robot, build the task, train it and fetch the ONNX policy — without leaving your editor.
kualia is a remote MCP server (Streamable HTTP) at https://kualia.ai/api/mcp. Create a personal API key under Settings → API keys and add the server to your agent:
Tools
| Tool | What it does |
|---|---|
| list_robots | Built-in robots (tiny, classic, realistic) and your uploaded ones |
| create_task | robot + trick (+ optional success, difficulty) → a task built in the background; returns task_id |
| get_task | Status, plan (trick, success scenario, world objects, reward), check results, Studio link |
| start_training | task_id + steps (10,000 for a first try) → a PPO run |
| get_training | Latest run: status, progress, mean reward, success rate |
| get_policy | ONNX and metadata download URLs for the latest completed run |
Then just ask, for example: “Train my SO-101 to press a button with kualia, start with a 10K-step try and tell me the success rate.” The agent builds the task, waits for the checks, starts training and reports back; the Studio link lets you watch the robot and change the task with alia.
For agents reading this page
A machine-readable summary lives at /llms.txt and the full reference at /llms-full.txt.Help
Troubleshooting
The problems people hit most, and what to do about them.
“Episodes survive the reset” fails
Random-action episodes last two steps or fewer, so a termination (or success) condition already fires at the start pose. Typical causes: a height test on a relative quantity (z_distance_from_origin is ≈ 0 at reset), a threshold stricter than the start pose (a “stay above 1.3 m” test on a robot that starts at 1.25 m), a HalfCheetah task treating its first observation value as a height, or terminating on success. Click Ask assistant to fix; the check’s detail message tells it what went wrong.
“Learnability estimate” fails
Random and zero actions produce the same return: the reward does not depend on anything the robot’s actions change (a constant bonus only, or a term reading the wrong variable). Ask for a reward on robot or object state, such as forward velocity or distance to the target.
“Objects start clear” fails
An object starts inside the robot, inside another object, below the floor or right under the robot, behaves unphysically in the first 60 steps, or the SCENE lacks an object type the world planner decided on. Move objects clear of the start pose (see where objects go for your robot), reduce jitter, or ask alia to add the missing object. Chat changes already run up to three automatic fixes; if the check still fails, Ask assistant to fix sends the details.
The world has objects I didn’t want (or lacks one I did)
The world planner re-plans on every chat change, so say it plainly: “no objects, just walk forward”, “add a button 0.5 m in front”, “use two steps instead of three”. The note under Your trick on the Plan page shows how it read your words, including anything it could not simulate.
Other failing checks
| Check | Usual cause |
|---|---|
| Security scan | An import of a blocked module (os-level, network, pickle, importlib…) or eval/exec. |
| Reward is sane | NaN or infinite rewards (division by zero, exploding velocities) or a constant reward. |
| Deterministic reset | Randomness from np.random instead of self.np_random, or the seed not passed to the robot’s reset. |
| Observation signals | An observation outside the declared space, often after appending features without widening the space. |
| No unstable physics | Non-finite or exploding observations under saturated actions, or episodes that never end within 300 steps. |
“3D simulator unavailable”
The page is not cross-origin isolated, so SharedArrayBuffer is missing: often Safari, an in-app browser, or an extension that rewrites headers. Open the page in current Chrome, Edge or Firefox. Recorded videos keep working either way.
“Live policy off for this task”
The browser cannot rebuild this task’s observation, usually because it adds features in extra_observation(), remaps actions or changes the control period. The hover text gives the exact reason. Use 3D replay or video, or ask alia to express the extra features as SCENE objects (observed automatically). During training, live policy becomes available once the 25 % checkpoint exists.
The robot doesn’t learn
| What you see | What it usually means |
|---|---|
| Flat reward, episodes a few steps long | The robot fails the termination at once. Check the failure conditions and the drop test; soften thresholds or start on Easy. |
| Reward rises, success stays at 0 % | The reward and the success criterion disagree. Align them, or loosen the criterion in a new version. |
| High reward, the robot barely moves | A survival bonus dominates; see the reward pitfalls. |
| Everything looks right but slow | Not enough steps. Compare with the robot’s Learn it budget and keep training. |
| Behaviour exploits the reward | The reward pays for a shortcut (spinning, flinging an object). Reward the actual result. |
Open the run’s results: the failure cases and the AI analysis usually name the problem, and the proposed changes turn into the next version with one click.
Training won’t start or failed
- Start is disabled or refused: some checks still fail, the balance is below the run price, or the budget exceeds your plan’s steps per run.
- Keep training is disabled: the current version has no completed run yet.
- The run failed: the task raised an error during training; its training steps are returned automatically. Ask alia about the error and train the fixed version.
An uploaded robot “needs validation”
The validation report found an error: no actuators, a non-finite or exploding state in the rollouts, or a model MuJoCo could not load (often a missing mesh or an absolute path). Open the report on the Robots page, fix the model and upload it again.
Help
FAQ
Do I need to write code?+
Can I edit the task code by hand?+
Which RL algorithm is used?+
Do I need a GPU?+
Is the world in training the same as in the browser?+
SCENE is read from the code and composed onto the robot model in the checks, in training and in the simulator.What happens to my runs when I roll back?+
Can I use the policy on a real robot?+
Why does the success rate differ between the chart and the results?+
Can a trick use several objects?+
Which robots are realistic, and which are classics?+
Can the robot turn a screw or press a button?+
knob and a switch or doorbell a button. Rewards and success can use object_turns and button_pressed. Panda is the natural robot for it; legged robots press and turn with a leg.Can I describe the trick in another language?+
What are the licenses of the realistic robot models?+
Ready to teach a trick?
Start with InvertedPendulum or Reacher and a 10K-step run.