Skill Base
SkillBase API
Summary: API reference for SkillBase, the abstract base class for creating custom agent skills.
Class Definition
from signalwire_agents.core.skill_base import SkillBase
class SkillBase(ABC):
"""Abstract base class for all agent skills."""
Overview
Skills are modular, reusable capabilities that can be added to agents.
Features:
- Auto-discovered from skill directories
- Automatic dependency validation
- Configuration via parameters
- Can add tools, prompts, hints, and global data
Class Attributes
class MySkill(SkillBase):
# Required attributes
SKILL_NAME: str = "my_skill" # Unique identifier
SKILL_DESCRIPTION: str = "Description" # Human-readable description
# Optional attributes
SKILL_VERSION: str = "1.0.0" # Semantic version
REQUIRED_PACKAGES: List[str] = [] # Python packages needed
REQUIRED_ENV_VARS: List[str] = [] # Environment variables needed
SUPPORTS_MULTIPLE_INSTANCES: bool = False # Allow multiple instances
Class Attributes Reference
| Attribute | Type | Required | Description |
|---|---|---|---|
SKILL_NAME | str | Yes | Unique identifier |
SKILL_DESCRIPTION | str | Yes | Description |
SKILL_VERSION | str | No | Version string |
REQUIRED_PACKAGES | List[str] | No | Package dependencies |
REQUIRED_ENV_VARS | List[str] | No | Required env vars |
SUPPORTS_MULTIPLE_INSTANCES | bool | No | Multiple instances |
Constructor
def __init__(
self,
agent: 'AgentBase', # Parent agent
params: Optional[Dict[str, Any]] = None # Skill configuration
)
Instance Attributes
self.agent # Reference to parent AgentBase
self.params # Configuration parameters dict
self.logger # Skill-specific logger
self.swaig_fields # SWAIG metadata to merge into tools
Abstract Methods (Must Implement)
setup
@abstractmethod
def setup(self) -> bool:
"""
Setup the skill.
Returns:
True if setup successful, False otherwise
"""
pass
Validate environment, initialize APIs, prepare resources.
register_tools
@abstractmethod
def register_tools(self) -> None:
"""Register SWAIG tools with the agent."""
pass
Register functions that the skill provides.
Helper Methods
define_tool
def define_tool(self, **kwargs) -> None
Register a tool with automatic swaig_fields merging.
def register_tools(self):
self.define_tool(
name="my_search",
description="Search functionality",
handler=self._handle_search,
parameters={
"type": "object",
"properties": {
"query": {"type": "string", "description": "Search query"}
},
"required": ["query"]
}
)
validate_env_vars
def validate_env_vars(self) -> bool
Check if all required environment variables are set.
validate_packages
def validate_packages(self) -> bool
Check if all required Python packages are available.
Optional Override Methods
get_hints
def get_hints(self) -> List[str]:
"""Return speech recognition hints for this skill."""
return []
get_global_data
def get_global_data(self) -> Dict[str, Any]:
"""Return data to add to agent's global context."""
return {}
get_prompt_sections
def get_prompt_sections(self) -> List[Dict[str, Any]]:
"""Return prompt sections to add to agent."""
return []
cleanup
def cleanup(self) -> None:
"""Cleanup when skill is removed or agent shuts down."""
pass
get_instance_key
def get_instance_key(self) -> str:
"""Get unique key for this skill instance."""
pass
Parameter Schema
get_parameter_schema
@classmethod
def get_parameter_schema(cls) -> Dict[str, Dict[str, Any]]:
"""Get parameter schema for this skill."""
pass
Define configuration parameters:
@classmethod
def get_parameter_schema(cls):
schema = super().get_parameter_schema()
schema.update({
"api_key": {
"type": "string",
"description": "API key for service",
"required": True,
"hidden": True,
"env_var": "MY_API_KEY"
},
"max_results": {
"type": "integer",
"description": "Maximum results to return",
"default": 10,
"min": 1,
"max": 100
}
})
return schema
Parameter Schema Fields
| Field | Type | Description |
|---|---|---|
type | string | Parameter type (string, integer, number, etc.) |
description | string | Human-readable description |
default | any | Default value if not provided |
required | bool | Whether parameter is required |
env_var | string | Environment variable alternative |
enum | list | List of allowed values |
min/max | number | Min/max for numeric types |
Complete Skill Example
from signalwire_agents.core.skill_base import SkillBase
from signalwire_agents.core.function_result import SwaigFunctionResult
from typing import Dict, Any, List
import os
class WeatherSkill(SkillBase):
"""Skill for weather lookups."""
SKILL_NAME = "weather"
SKILL_DESCRIPTION = "Provides weather information"
SKILL_VERSION = "1.0.0"
REQUIRED_PACKAGES = ["requests"]
REQUIRED_ENV_VARS = ["WEATHER_API_KEY"]
def setup(self) -> bool:
"""Initialize the weather skill."""
# Validate dependencies
if not self.validate_packages():
return False
if not self.validate_env_vars():
return False
# Store API key
self.api_key = os.getenv("WEATHER_API_KEY")
return True
def register_tools(self) -> None:
"""Register weather tools."""
self.define_tool(
name="get_weather",
description="Get current weather for a location",
handler=self._get_weather,
parameters={
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "City name or zip code"
}
},
"required": ["location"]
}
)
def _get_weather(self, args: Dict, raw_data: Dict) -> SwaigFunctionResult:
"""Handle weather lookup."""
import requests
location = args.get("location")
url = f"https://api.weather.com/v1/current?q={location}&key={self.api_key}"
try:
response = requests.get(url)
data = response.json()
return SwaigFunctionResult(
f"Weather in {location}: {data['condition']}, {data['temp']}°F"
)
except Exception as e:
return SwaigFunctionResult(f"Unable to get weather: {str(e)}")
def get_hints(self) -> List[str]:
"""Speech recognition hints."""
return ["weather", "temperature", "forecast", "sunny", "rainy"]
def get_prompt_sections(self) -> List[Dict[str, Any]]:
"""Add weather instructions to prompt."""
return [{
"title": "Weather Information",
"body": "You can check weather for any location using the get_weather function."
}]
@classmethod
def get_parameter_schema(cls):
schema = super().get_parameter_schema()
schema.update({
"units": {
"type": "string",
"description": "Temperature units",
"default": "fahrenheit",
"enum": ["fahrenheit", "celsius"]
}
})
return schema
Using Skills
from signalwire_agents import AgentBase
agent = AgentBase(name="weather-agent")
## Add skill with default configuration
agent.add_skill("weather")
## Add skill with custom configuration
agent.add_skill("weather", {
"units": "celsius"
})
## List available skills
print(agent.list_available_skills())
Skill Directory Structure
signalwire_agents/skills/
weather/
__init__.py
skill.py # WeatherSkill class
requirements.txt # Skill-specific dependencies
calendar/
__init__.py
skill.py
requirements.txt
...