Skills

View as MarkdownOpen in Claude

Skills are pluggable capabilities that add tools to your agent. Import a skill class, instantiate it with optional configuration, and pass the instance to addSkill(). Each skill registers one or more SWAIG functions automatically and injects prompt sections, hints, and global data.

1import { AgentBase, DateTimeSkill, WebSearchSkill } from '@signalwire/sdk';
2
3const agent = new AgentBase({ name: 'my-agent', route: '/' });
4
5agent.setPromptText('You are a helpful assistant.');
6
7// No-config skill
8await agent.addSkill(new DateTimeSkill());
9
10// Skill with parameters
11await agent.addSkill(new WebSearchSkill({
12 max_results: 5,
13 safe_search: 'high',
14}));
15
16agent.run();

Skills Summary

SkillClassToolsEnv Vars RequiredMulti-Instance
datetimeDateTimeSkill1NoNo
mathMathSkill1NoNo
jokeJokeSkill1NoNo
weather_apiWeatherApiSkill1YesNo
web_searchWebSearchSkill1YesNo
wikipedia_searchWikipediaSearchSkill1NoNo
google_mapsGoogleMapsSkill2YesNo
play_background_filePlayBackgroundFileSkill2NoNo
swml_transferSwmlTransferSkill1-2NoNo
datasphereDataSphereSkill1YesYes
datasphere_serverlessDataSphereServerlessSkill1YesYes
native_vector_searchNativeVectorSearchSkill1NoYes
info_gathererInfoGathererSkill2NoNo
api_ninjas_triviaApiNinjasTriviaSkill1YesNo
spiderSpiderSkill1YesNo
ask_claudeAskClaudeSkill1YesNo
claude_skillsClaudeSkillsSkillDynamicNoYes
custom_skillsCustomSkillsSkillDynamicNoNo
mcp_gatewayMcpGatewaySkill1NoNo

Configuration

All skills accept configuration via a config object passed to the skill constructor. Skills with an env_var fallback on a parameter read from process.env when the parameter is not provided directly.

1import { WebSearchSkill } from '@signalwire/sdk';
2
3// Direct configuration
4const skill = new WebSearchSkill({ max_results: 5, safe_search: 'high' });
5
6// Environment variable fallback (api_key falls back to GOOGLE_SEARCH_API_KEY,
7// search_engine_id falls back to GOOGLE_SEARCH_CX)
8process.env.GOOGLE_SEARCH_API_KEY = 'YOUR_KEY';
9process.env.GOOGLE_SEARCH_CX = 'YOUR_ENGINE_ID';
10const skillWithEnv = new WebSearchSkill({ max_results: 5 });

SWAIG Field Overrides

Override SWAIG function metadata for any skill by including a swaig_fields key:

1import { AgentBase, DateTimeSkill } from '@signalwire/sdk';
2
3const agent = new AgentBase({ name: 'assistant', route: '/assistant' });
4agent.setPromptText('You are a helpful assistant.');
5
6await agent.addSkill(new DateTimeSkill({
7 swaig_fields: {
8 fillers: { 'en-US': ['Let me check the time...', 'One moment...'] },
9 secure: false,
10 },
11}));
12
13agent.run();

Multi-Instance Skills

Skills that support multiple instances (SUPPORTS_MULTIPLE_INSTANCES = true) can be added to the same agent more than once with different tool_name values:

1import { AgentBase, DataSphereSkill } from '@signalwire/sdk';
2
3const agent = new AgentBase({ name: 'assistant', route: '/assistant' });
4agent.setPromptText('You are a helpful assistant.');
5
6await agent.addSkill(new DataSphereSkill({
7 tool_name: 'search_products',
8 max_results: 3,
9}));
10await agent.addSkill(new DataSphereSkill({
11 tool_name: 'search_policies',
12 max_results: 5,
13}));
14
15agent.run();

Base Parameters

Every skill inherits these parameters from SkillBase:

swaig_fields
object

Additional SWAIG fields to merge into each tool definition provided by this skill (e.g., fillers, secure).

skip_prompt
booleanDefaults to false

When true, suppress all prompt sections from this skill.


Extending SkillBase

Create custom skills by extending SkillBase and registering them with the SkillRegistry.

Defining a Custom Skill

1import { SkillBase, FunctionResult } from '@signalwire/sdk';
2import type {
3 SkillManifest,
4 SkillToolDefinition,
5 SkillPromptSection,
6 SkillConfig,
7 ParameterSchemaEntry,
8} from '@signalwire/sdk';
9
10export class StockPriceSkill extends SkillBase {
11 constructor(config?: SkillConfig) {
12 super('stock_price', config);
13 }
14
15 static override getParameterSchema(): Record<string, ParameterSchemaEntry> {
16 return {
17 ...super.getParameterSchema(),
18 api_key: {
19 type: 'string',
20 description: 'Stock API key.',
21 hidden: true,
22 env_var: 'STOCK_API_KEY',
23 required: true,
24 },
25 };
26 }
27
28 getManifest(): SkillManifest {
29 return {
30 name: 'stock_price',
31 description: 'Look up current stock prices.',
32 version: '1.0.0',
33 requiredEnvVars: ['STOCK_API_KEY'],
34 };
35 }
36
37 getTools(): SkillToolDefinition[] {
38 return [
39 {
40 name: 'get_stock_price',
41 description: 'Get the current price of a stock by ticker symbol.',
42 parameters: {
43 symbol: {
44 type: 'string',
45 description: 'Stock ticker symbol (e.g., "AAPL", "GOOG").',
46 },
47 },
48 required: ['symbol'],
49 handler: async (args: Record<string, unknown>) => {
50 const symbol = args.symbol as string;
51 // Your implementation here
52 return new FunctionResult(
53 'The current price of ' + symbol + ' is $150.00.',
54 );
55 },
56 },
57 ];
58 }
59
60 protected override _getPromptSections(): SkillPromptSection[] {
61 return [
62 {
63 title: 'Stock Prices',
64 body: 'You can look up current stock prices.',
65 bullets: [
66 'Use the get_stock_price tool when the user asks about a stock price.',
67 'Provide the stock ticker symbol (e.g., AAPL for Apple).',
68 ],
69 },
70 ];
71 }
72}

Registering with SkillRegistry

1import { SkillRegistry } from '@signalwire/sdk';
2import { StockPriceSkill } from './stock-price-skill.js';
3
4const registry = SkillRegistry.getInstance();
5registry.register('stock_price', (config) => new StockPriceSkill(config));

Using a Custom Skill

1import { AgentBase } from '@signalwire/sdk';
2import { StockPriceSkill } from './stock-price-skill.js';
3
4const agent = new AgentBase({ name: 'finance-bot', route: '/' });
5agent.setPromptText('You are a financial assistant.');
6
7await agent.addSkill(new StockPriceSkill());
8
9agent.run();

For more details on the skill base class, see SkillBase.


All Skills