Skip to main content
Skills are atomic robot capabilities that the Innate agent chains together to accomplish complex, long-horizon behaviors. Each skill encodes a single capability—physical (manipulation, navigation) or digital (emails, API calls)—that can be combined with others to form coherent action sequences. When the Innate agent receives a request like “check on grandma,” it decomposes this into a skill chain: navigate to bedroom → look around → send picture via email → speak reassurance. Four skills, one coherent behavior.

Two Types of Skills

Skills are defined in one of two ways.

Code-Defined Skills

Code-defined skills are Python classes with explicit logic. The runtime injects declared interfaces, and the Innate agent reads your signature/docstrings to call the skill correctly.
import math
from brain_client.skill_types import Skill, SkillResult, Interface, InterfaceType

class LookAround(Skill):
    mobility = Interface(InterfaceType.MOBILITY)
    head = Interface(InterfaceType.HEAD)

    @property
    def name(self):
        return "look_around"

    def execute(self, num_directions: int = 4):
        """Rotate and scan the environment."""
        if self.mobility is None or self.head is None:
            return "Required interfaces not available", SkillResult.FAILURE

        num_directions = max(1, num_directions)
        self.head.set_position(-15)
        self.mobility.rotate((2 * math.pi) / num_directions)
        return "Scan complete", SkillResult.SUCCESS

    def cancel(self):
        return "Cancelled"
Use this style when you want deterministic physical control, digital/API operations, explicit sequencing, or custom sensor processing.
Policy-defined skills are learned policies trained from demonstrations. For manipulation, the current workflow uses ACT (Action Chunking with Transformers).
{
  "name": "pick_cup",
  "type": "learned",
  "guidelines": "Use when you need to pick up a cup",
  "execution": {
    "model_type": "act_policy",
    "checkpoint": "policy_step_50000.pth"
  }
}
Use this style when behavior is easier to learn from data than encode by hand, especially for visuomotor manipulation.

Where to Put Your Skills

Your skills go in ~/innate-os/workspace/custom_skills/ on the robot. This is the directory the system scans for your skills — files placed anywhere else will not load. Getting this path right is the single most common stumbling block when a skill “doesn’t appear”.
  • Code-defined skill → a single Python file: ~/innate-os/workspace/custom_skills/my_skill.py
  • Policy-defined (physical) skill → a directory with its metadata and checkpoint: ~/innate-os/workspace/custom_skills/my_skill/metadata.json
No registration required. Drop the file in place and it hot-reloads within seconds — the directory is watched while the robot runs, for new files and edits alike.

Skill IDs: local/ vs innate-os/

Skill IDs are namespaced by origin, and agents must use the full ID:
  • local/<name>your skills (anything in custom_skills/)
  • innate-os/<name> — shipped skills (in innate_skills/)
So in an agent, write "local/my_skill", not "my_skill":
def get_skills(self) -> List[str]:
    return [
        "local/my_skill",              # your skill
        "innate-os/navigate_to_position",  # shipped skill
    ]
A bare name without the prefix won’t resolve — this is the second most common reason a skill “doesn’t work” after putting the file in the wrong directory.
DirectoryPurposeSkill ID prefix
~/innate-os/workspace/custom_skills/Your skills (gitignored, survives OS updates)local/<name>
~/innate-os/workspace/innate_skills/Shipped skills (tracked in git, updated by git pull)innate-os/<name>
Legacy locations (~/skills/, ~/innate-os/skills/) from releases before the workspace layout are still scanned, and you can add extra directories with extra_skill_dirs under the script_paths section of config/settings.yaml. Skills from any of these also get the local/ prefix — only innate_skills/ produces innate-os/ IDs.