Jido.Skill behaviour (Jido v1.1.0-rc.2)
View SourceDefines the core behavior and structure for Jido Skills, the fundamental building blocks of agent capabilities in the Jido framework.
Overview
Skills encapsulate discrete sets of functionality that agents can use to accomplish tasks. Think of them as feature packs that give agents new abilities - similar to how a person might learn skills like "cooking" or "programming". Each Skill provides:
- Signal routing and handling patterns
- Isolated state management
- Process supervision
- Configuration validation
- Runtime adaptation
Core Concepts
State Isolation
Skills use schema-based state isolation to prevent different capabilities from interfering with each other. Each skill defines:
- A unique
opts_key
for namespace isolation - Validation rules for configuration
Signal Patterns
Skills define what signals they can handle through pattern matching:
use Jido.Skill,
name: "weather_monitor",
signal_patterns: [
"weather.data.*",
"weather.alert.**"
]
Pattern rules:
- Exact matches: "user.created"
- Single wildcards: "user.*.updated"
- Multi-wildcards: "audit.**"
Configuration Management
Skills provide schema-based config validation:
config: [
api_key: [
type: :string,
required: true,
doc: "API key for weather service"
],
update_interval: [
type: :pos_integer,
default: 60_000,
doc: "Update interval in milliseconds"
]
]
Process Supervision
Skills can define child processes through the child_spec/1
callback:
def child_spec(config) do
[
{WeatherAPI.Client, config.api_key},
{MetricsCollector, name: config.metrics_name}
]
end
Usage Example
Here's a complete skill example:
defmodule MyApp.WeatherSkill do
use Jido.Skill,
name: "weather_monitor",
description: "Monitors weather conditions and generates alerts",
category: "monitoring",
tags: ["weather", "alerts"],
vsn: "1.0.0",
opts_key: :weather,
signal_patterns: [
"weather.data.*",
"weather.alert.**"
],
config: [
api_key: [type: :string, required: true]
]
def child_spec(config) do
[
{WeatherAPI.Client, config.api_key}
]
end
def handle_signal(%Signal{type: "weather.data.updated"} = signal, _skill) do
# Handle weather updates
{:ok, signal}
end
def transform_result(%Signal{} = signal, result, _skill) do
# Transform the result
{:ok, result}
end
end
Callbacks
Skills implement these callbacks:
child_spec/1
- Returns child process specificationsrouter/0
- Returns signal routing ruleshandle_signal/2
- Processes incoming signalstransform_result/3
- Post-processes signal handling resultsmount/2
- Mounts the skill to an agent
Behavior
The Skill behavior enforces a consistent interface:
@callback child_spec(config :: map()) :: Supervisor.child_spec() | [Supervisor.child_spec()]
@callback router() :: [map()]
@callback handle_signal(signal :: Signal.t(), skill :: t()) :: {:ok, Signal.t()} | {:error, term()}
@callback transform_result(signal :: Signal.t(), result :: term(), skill :: t()) ::
{:ok, term()} | {:error, term()}
@callback mount(agent :: Jido.Agent.t(), opts :: keyword()) :: Jido.Agent.t()
Configuration
Skills validate their configuration at compile time using these fields:
name
- Unique identifier (required)description
- Human-readable explanationcategory
- Broad classificationtags
- List of searchable tagsvsn
- Version stringopts_key
- State namespace keysignal_patterns
- Input/output patternsopts_schema
- Configuration schema
Best Practices
State Isolation
- Use meaningful opts_key names
- Keep state focused and minimal
- Document state structure
Signal Design
- Use consistent naming patterns
- Document signal formats
- Consider routing efficiency
Configuration
- Validate thoroughly
- Provide good defaults
- Document all options
Process Management
- Supervise child processes
- Handle crashes gracefully
- Monitor resource usage
See Also
Jido.Signal
- Signal structure and validationJido.Error
- Error handlingJido.Agent
- Agent integration
Summary
Functions
Implements the skill behavior and configuration validation.
Gets a skill's configuration schema.
Skills must be defined at compile time, not runtime.
Validates a skill's configuration against its schema.
Types
@type t() :: %Jido.Skill{ category: String.t() | nil, description: String.t() | nil, name: String.t(), opts_key: atom() | nil, opts_schema: map() | nil, signal_patterns: [String.t()], tags: [String.t()], vsn: String.t() | nil }
Represents a skill's core structure and metadata.
Fields:
name
: Unique identifier for the skilldescription
: Human-readable explanation of purposecategory
: Broad classification for organizationtags
: List of searchable tagsvsn
: Version string for compatibilityopts_key
: Atom key for state namespacesignal_patterns
: Input/output signal patternsopts_schema
: Configuration schema
Callbacks
@callback child_spec(config :: map()) :: Supervisor.child_spec() | [Supervisor.child_spec()]
@callback handle_signal(signal :: Jido.Signal.t(), skill :: t()) :: {:ok, Jido.Signal.t()} | {:error, term()}
@callback mount(agent :: Jido.Agent.t(), opts :: keyword()) :: {:ok, Jido.Agent.t()} | {:error, Jido.Error.t()}
@callback router(skill_opts :: keyword()) :: [Route.t()]
@callback transform_result(signal :: Jido.Signal.t(), result :: term(), skill :: t()) :: {:ok, term()} | {:error, any()}
Functions
Implements the skill behavior and configuration validation.
This macro:
- Validates configuration at compile time
- Defines metadata accessors
- Provides JSON serialization
- Sets up default implementations
Example
defmodule MySkill do
use Jido.Skill,
name: "my_skill",
opts_key: :my_skill,
signals: [
input: ["my.event.*"],
output: ["my.result.*"]
]
end
@spec get_opts_schema(module()) :: {:ok, map()} | {:error, Jido.Error.t()}
Gets a skill's configuration schema.
Parameters
skill_module
: The skill module to inspect
Returns
{:ok, schema}
: The skill's config schema{:error, reason}
: Schema not found
Example
Skill.get_config_schema(WeatherSkill)
@spec new() :: {:error, Jido.Error.t()}
Skills must be defined at compile time, not runtime.
This function always returns an error to enforce compile-time definition.
@spec validate_opts(module(), map()) :: {:ok, map()} | {:error, Jido.Error.t()}
Validates a skill's configuration against its schema.
Parameters
skill_module
: The skill module to validateconfig
: Configuration map to validate
Returns
{:ok, validated_config}
: Successfully validated config{:error, reason}
: Validation failed
Example
Skill.validate_opts(WeatherSkill, %{
api_key: "abc123",
interval: 1000
})