SkillBase

View as MarkdownOpen in Claude

SkillBase is the abstract base class for all agent skills. Skills are modular, reusable capabilities — such as weather lookup, web search, or calendar access — that can be added to any AgentBase agent with a single call to agent.addSkill().

Extend SkillBase to create custom skills. Metadata (name, description, version, required packages, required environment variables, multi-instance support) is declared as static class constants on the subclass — the SkillRegistry and SkillManager read these constants directly. You override getTools() to expose SWAIG tools and optionally override lifecycle and prompt methods.

For the catalog of built-in skills and their configuration parameters, see the Skills page.

Static Class Constants

Subclasses declare their identity and requirements by overriding these static members. The SkillRegistry reads them directly — no manifest object is exchanged.

SKILL_NAME
stringRequired

Unique skill name used for registration. Subclasses must override with a non-empty string; the constructor throws otherwise.

SKILL_DESCRIPTION
stringRequired

Human-readable description. Subclasses must override with a non-empty string; the constructor throws otherwise.

SKILL_VERSION
stringDefaults to 1.0.0

Semantic version string.

REQUIRED_PACKAGES
readonly string[]Defaults to []

NPM packages the skill depends on. Checked at load time by validatePackages().

REQUIRED_ENV_VARS
readonly string[]Defaults to []

Environment variables the skill requires. Checked at load time by validateEnvVars().

SUPPORTS_MULTIPLE_INSTANCES
booleanDefaults to false

When true, the same skill can be added to an agent multiple times with different configurations (distinguished by tool_name).

getParameterSchema()
static method

Returns metadata about all parameters the skill accepts. See getParameterSchema.

Constructor

1constructor(config?: SkillConfig)

The skill name, description, and version come from the subclass’s static constants — not from constructor arguments.

config
SkillConfig

Optional configuration key-value pairs for the skill instance. Any swaig_fields entry is extracted and automatically merged into tool definitions.

Instance Properties

skillName
string

The registered name for this skill instance, copied from SKILL_NAME (readonly).

instanceId
string

Unique identifier for this skill instance (readonly).

config
SkillConfig

Configuration parameters passed to the constructor (protected).

swaigFields
Record<string, unknown>

SWAIG metadata extracted from config, automatically merged into tool definitions (readonly).

Methods

defineTool (protected)

1protected defineTool(toolDef: SkillToolDefinition): void

Imperatively register a tool. Use from setup() when the tool shape depends on config evaluated at runtime. The method merges this.swaigFields into the definition and pushes it onto the internal dynamic-tools list; the default getTools() returns that list. Skills with a static tool list should override getTools() directly instead.

getConfig

1getConfig<T = unknown>(key: string, defaultValue?: T): T

Read a configuration value by key, with an optional fallback default.

key
stringRequired

The configuration key to look up.

defaultValue
T

Value to return if the key is not present in the config.

hasAllEnvVars / hasAllPackages

1hasAllEnvVars(): boolean
2async hasAllPackages(): Promise<boolean>

Boolean wrappers around validateEnvVars() and validatePackages().

Examples

Custom skill

1import { SkillBase, type SkillToolDefinition } from '@signalwire/sdk';
2
3class MyWeatherSkill extends SkillBase {
4 static override SKILL_NAME = 'my_weather';
5 static override SKILL_DESCRIPTION = 'Look up weather';
6 static override SKILL_VERSION = '1.0.0';
7
8 override getTools(): SkillToolDefinition[] {
9 return [{
10 name: 'get_weather',
11 description: 'Get current weather for a city',
12 parameters: { city: { type: 'string', description: 'City name' } },
13 handler: async (args) => ({ response: 'Sunny, 72F' }),
14 }];
15 }
16}

Using a skill

1import { AgentBase } from '@signalwire/sdk';
2
3const agent = new AgentBase({ name: 'weather-agent' });
4agent.setPromptText("You are a helpful assistant.");
5agent.addSkill("weather");
6
7// Or with custom configuration
8agent.addSkill("weather", { units: "celsius" });
9
10agent.run();