Skip to main content
A code-defined skill is a Python class. The agent reads your guidelines() to decide when to call it, and your execute() signature to know how.
Save it in ~/innate-os/workspace/custom_skills/ and it’s live as look_around. Type hints and the docstring are what the agent sees, so write them carefully. guidelines() is a prompt: tune it when the robot calls your skill at the wrong time.

Declare what you need

Annotate a class attribute and the runtime provides it. A plain annotation is required: the run fails before starting if it’s unavailable, so you never check for None. Add | None to make it optional.

Return a result

To return more than a message, use SkillOutput:

Cancellation

A Stop can come at any time, and the framework handles it. Follow one rule: use self.sleep(), never time.sleep(). Every blocking framework call raises on Stop, the base brakes, and the arm halts. You don’t catch anything. Put cleanup in try/finally. Using time.time() to measure durations is fine.

Other helpers

Call other skills

Declare another skill like any dependency, then call it like a method. The call blocks until it finishes, shows up as its own step in the app, and returns a SkillOutput. Trained policies work the same way.
A failing sub-skill raises SkillFailed. Catch that, not bare Exception, or Stop won’t work.

Ask a model

Declare llm: Llm and ask it about a camera frame. You get the robot’s model, with its keys already set up.

Call external services

Skills can call any API. Read secrets from the environment, set timeouts, and turn errors into self.fail():
A network call can’t be interrupted halfway. Say so in guidelines() so the agent plans for it.
The best examples are the shipped skills in workspace/innate_skills/. pick_any_object.py combines vision, driving, and grasping.