Skill Development Guide¶
This section describes how to create a Skill using the standard development structure in Pyraya. Following this structure ensures maintainability, compatibility, and clear integration with the application layer.
1. Standard Skill Structure¶
A typical Skill is organized within its own directory inside the skills/ folder. The standard layout is as follows:
skills/
└── skill_name/
├── __init__.py
├── main.py
├── controllers.yaml
├── controllers.pyi
Description of each file:
__init__.py: Imports and exposes the main Skill class (usually extendingRayaSkillorRayaFSMSkill) so it can be discovered by the system.main.py: Contains the core logic of the Skill, including the lifecycle methods (setup, main, finish) and any helper functions.controllers.yaml: Declares the list of controllers or services the Skill depends on. Pyraya uses this to inject the appropriate instances at runtime.controllers.pyi: (Optional) Provides type hints and autocompletion support for IDEs and static analyzers.
Following this layout is essential for the proper detection, loading, and execution of Skills within the Pyraya runtime environment.
FSM Skill Structure:
In the case of a FSM-based Skill, the same structure applies, including all the standard files, and adding the following files:
├── actions.py
├── helpers.py
├── states.py
├── transitions.py
These additional files define the logic and behavior of the finite state machine:
actions.py: Defines specific actions executed during state transitions.helpers.py: Contains auxiliary functions used within states or actions.states.py: Declares all the states used in the FSM.transitions.py: Describes the allowed transitions and their conditions.
To better understand how FSMs are modeled and executed in Pyraya, Finite States Machines section.
2. Defining the Skill Class¶
Setup and Execute Arguments Definition¶
Each Skill must define a main class that inherits from either
RayaSkill or RayaFSMSkill, depending on the desired behavior.
Inside this class, the developer must declare two inner classes to define the arguments expected by the Skill:
SetupArgsModelExecuteArgsModel
These classes must inherit from RayaSkillArgsModel, which can be
imported from raya.skills.raya_skill_argument. This allows the
developer to define structured, typed argument schemas for both
the setup() and main() methods.
Argument models provide:
Type validation: Ensures that the provided arguments match the declared types.
Field requirements: Developers can specify which fields are required and which are optional.
Default values: Optional fields may include default values to simplify usage.
Note
The fields declared in these models are automatically parsed and validated at runtime, and made available through self.setup_args and self.execute_args within the Skill methods.
Skill Lifecycle Methods Definition¶
Every skill in Pyraya must define the following asynchronous methods:
setup, main, and finish. These represent the three key phases in
the lifecycle of a skill and ensure consistent behavior and integration with
the application layer that uses them.
setup()¶
This method is called once, at the beginning of the skill’s lifecycle, when the application initializes the skill. Its purpose is to prepare everything the skill will need during execution.
It is recommended to configure all necessary controllers here, using the ones declared in the
controllers.yamlfile.It’s also advised to define the
setup_argsattribute in this method like so:self.setup_args: SkillName.SetupArgsModel
This provides autocompletion and type checking thanks to
pydantic.
main()¶
This method defines the core logic of the skill. It is the main loop or entry point of the task the skill is meant to perform.
As with setup, you should define:
self.execute_args: SkillName.ExecuteArgsModel
to gain full typing and autocompletion support.
The logic should be encapsulated in an asynchronous structure so it can run efficiently within the event loop of Pyraya.
finish()¶
This method is also called once, when the application requests the skill to stop. It is a good place to:
Clean up resources,
Stop ongoing processes, and
Ensure the skill exits gracefully.
FSM Skills – Additional Setup¶
If the skill is an FSM-based skill (i.e., it inherits from RayaFSMSkill),
the same lifecycle applies, with one key addition in the setup() method:
self.init_fsm(verbose=True)
This line initializes the FSM engine using the files defined in the standard FSM structure.
In this case, it is recommended to define the main() method as follows:
async def main(self):
while not self.has_finished():
await self.tick()
await self.sleep(0.1)
return self.has_finished()
This loop ensures the FSM is ticked regularly and functions correctly according to the definitions provided in the state machine configuration files.