Skill Base

View as Markdown

SkillBase API

API reference for SkillBase, the abstract base class for creating custom agent skills.

Class Definition

1from signalwire_agents.core.skill_base import SkillBase
2
3class SkillBase(ABC):
4 """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

1class MySkill(SkillBase):
2 # Required attributes
3 SKILL_NAME: str = "my_skill" # Unique identifier
4 SKILL_DESCRIPTION: str = "Description" # Human-readable description
5
6 # Optional attributes
7 SKILL_VERSION: str = "1.0.0" # Semantic version
8 REQUIRED_PACKAGES: List[str] = [] # Python packages needed
9 REQUIRED_ENV_VARS: List[str] = [] # Environment variables needed
10 SUPPORTS_MULTIPLE_INSTANCES: bool = False # Allow multiple instances

Class Attributes Reference

AttributeTypeRequiredDescription
SKILL_NAMEstrYesUnique identifier
SKILL_DESCRIPTIONstrYesDescription
SKILL_VERSIONstrNoVersion string
REQUIRED_PACKAGESList[str]NoPackage dependencies
REQUIRED_ENV_VARSList[str]NoRequired env vars
SUPPORTS_MULTIPLE_INSTANCESboolNoMultiple instances

Constructor

1def __init__(
2 self,
3 agent: 'AgentBase', # Parent agent
4 params: Optional[Dict[str, Any]] = None # Skill configuration
5)

Instance Attributes

1self.agent # Reference to parent AgentBase
2self.params # Configuration parameters dict
3self.logger # Skill-specific logger
4self.swaig_fields # SWAIG metadata to merge into tools

Abstract Methods (Must Implement)

setup

1@abstractmethod
2def setup(self) -> bool:
3 """
4 Setup the skill.
5
6 Returns:
7 True if setup successful, False otherwise
8 """
9 pass

Validate environment, initialize APIs, prepare resources.

register_tools

1@abstractmethod
2def register_tools(self) -> None:
3 """Register SWAIG tools with the agent."""
4 pass

Register functions that the skill provides.

Helper Methods

define_tool

1def define_tool(self, **kwargs) -> None

Register a tool with automatic swaig_fields merging.

1def register_tools(self):
2 self.define_tool(
3 name="my_search",
4 description="Search functionality",
5 handler=self._handle_search,
6 parameters={
7 "type": "object",
8 "properties": {
9 "query": {"type": "string", "description": "Search query"}
10 },
11 "required": ["query"]
12 }
13 )

validate_env_vars

1def validate_env_vars(self) -> bool

Check if all required environment variables are set.

validate_packages

1def validate_packages(self) -> bool

Check if all required Python packages are available.

Optional Override Methods

get_hints

1def get_hints(self) -> List[str]:
2 """Return speech recognition hints for this skill."""
3 return []

get_global_data

1def get_global_data(self) -> Dict[str, Any]:
2 """Return data to add to agent's global context."""
3 return {}

get_prompt_sections

1def get_prompt_sections(self) -> List[Dict[str, Any]]:
2 """Return prompt sections to add to agent."""
3 return []

cleanup

1def cleanup(self) -> None:
2 """Cleanup when skill is removed or agent shuts down."""
3 pass

get_instance_key

1def get_instance_key(self) -> str:
2 """Get unique key for this skill instance."""
3 pass

Parameter Schema

get_parameter_schema

1@classmethod
2def get_parameter_schema(cls) -> Dict[str, Dict[str, Any]]:
3 """Get parameter schema for this skill."""
4 pass

Define configuration parameters:

1@classmethod
2def get_parameter_schema(cls):
3 schema = super().get_parameter_schema()
4 schema.update({
5 "api_key": {
6 "type": "string",
7 "description": "API key for service",
8 "required": True,
9 "hidden": True,
10 "env_var": "MY_API_KEY"
11 },
12 "max_results": {
13 "type": "integer",
14 "description": "Maximum results to return",
15 "default": 10,
16 "min": 1,
17 "max": 100
18 }
19 })
20 return schema

Parameter Schema Fields

FieldTypeDescription
typestringParameter type (string, integer, number, etc.)
descriptionstringHuman-readable description
defaultanyDefault value if not provided
requiredboolWhether parameter is required
hiddenboolHide in UIs (for secrets)
env_varstringEnvironment variable alternative
enumlistList of allowed values
min/maxnumberMin/max for numeric types

Complete Skill Example

1from signalwire_agents.core.skill_base import SkillBase
2from signalwire_agents.core.function_result import SwaigFunctionResult
3from typing import Dict, Any, List
4import os
5
6
7class WeatherSkill(SkillBase):
8 """Skill for weather lookups."""
9
10 SKILL_NAME = "weather"
11 SKILL_DESCRIPTION = "Provides weather information"
12 SKILL_VERSION = "1.0.0"
13 REQUIRED_PACKAGES = ["requests"]
14 REQUIRED_ENV_VARS = ["WEATHER_API_KEY"]
15
16 def setup(self) -> bool:
17 """Initialize the weather skill."""
18 # Validate dependencies
19 if not self.validate_packages():
20 return False
21 if not self.validate_env_vars():
22 return False
23
24 # Store API key
25 self.api_key = os.getenv("WEATHER_API_KEY")
26 return True
27
28 def register_tools(self) -> None:
29 """Register weather tools."""
30 self.define_tool(
31 name="get_weather",
32 description="Get current weather for a location",
33 handler=self._get_weather,
34 parameters={
35 "type": "object",
36 "properties": {
37 "location": {
38 "type": "string",
39 "description": "City name or zip code"
40 }
41 },
42 "required": ["location"]
43 }
44 )
45
46 def _get_weather(self, args: Dict, raw_data: Dict) -> SwaigFunctionResult:
47 """Handle weather lookup."""
48 import requests
49
50 location = args.get("location")
51 url = f"https://api.weather.com/v1/current?q={location}&key={self.api_key}"
52
53 try:
54 response = requests.get(url)
55 data = response.json()
56 return SwaigFunctionResult(
57 f"Weather in {location}: {data['condition']}, {data['temp']}°F"
58 )
59 except Exception as e:
60 return SwaigFunctionResult(f"Unable to get weather: {str(e)}")
61
62 def get_hints(self) -> List[str]:
63 """Speech recognition hints."""
64 return ["weather", "temperature", "forecast", "sunny", "rainy"]
65
66 def get_prompt_sections(self) -> List[Dict[str, Any]]:
67 """Add weather instructions to prompt."""
68 return [{
69 "title": "Weather Information",
70 "body": "You can check weather for any location using the get_weather function."
71 }]
72
73 @classmethod
74 def get_parameter_schema(cls):
75 schema = super().get_parameter_schema()
76 schema.update({
77 "units": {
78 "type": "string",
79 "description": "Temperature units",
80 "default": "fahrenheit",
81 "enum": ["fahrenheit", "celsius"]
82 }
83 })
84 return schema

Using Skills

1from signalwire_agents import AgentBase
2
3agent = AgentBase(name="weather-agent")
4
5## Add skill with default configuration
6agent.add_skill("weather")
7
8## Add skill with custom configuration
9agent.add_skill("weather", {
10 "units": "celsius"
11})
12
13## List available skills
14print(agent.list_available_skills())

Skill Directory Structure

signalwire_agents/skills
weather
__init__.py
skill.py# WeatherSkill class
requirements.txt# Skill-specific dependencies
calendar