contextual-agent-sdk
Version:
SDK for building AI agents with seamless voice-text context switching
307 lines • 11.4 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.TwilioToolProvider = void 0;
const ToolProvider_1 = require("../ToolProvider");
class TwilioToolProvider extends ToolProvider_1.BaseToolProvider {
id = 'twilio';
name = 'Twilio';
description = 'SMS and voice communication tools powered by Twilio';
category = 'communication';
version = '1.0.0';
capabilities = [
{ id: 'send_message', name: 'Send Message', description: 'Send SMS/text messages', available: true },
{ id: 'voice_call', name: 'Voice Call', description: 'Make voice calls with TTS', available: true }
];
minimumTier = 'BASIC';
isPremium = false;
isEnterprise = false;
getAvailableTools() {
return [
{
id: 'send_sms',
name: 'Send SMS',
description: 'Send SMS messages to phone numbers',
category: 'communication',
minimumTier: 'BASIC',
rateLimits: {
requestsPerHour: 100
},
requiresAuth: true,
isPremium: false,
version: '1.0.0',
parameters: [
{
name: 'to',
type: 'string',
description: 'Recipient phone number (E.164 format)',
required: true,
schema: {
pattern: '^\\+[1-9]\\d{1,14}$'
}
},
{
name: 'message',
type: 'string',
description: 'SMS message content',
required: true,
schema: {
maxLength: 1600
}
},
{
name: 'mediaUrl',
type: 'string',
description: 'Optional media URL for MMS',
required: false,
schema: {
pattern: '^https?:\\/\\/.+'
}
}
],
returnType: {
type: 'object',
description: 'SMS sending result',
schema: {
type: 'object',
properties: {
messageSid: { type: 'string', description: 'Twilio message SID' },
status: { type: 'string', description: 'Message status' },
to: { type: 'string', description: 'Recipient phone number' },
from: { type: 'string', description: 'Sender phone number' },
body: { type: 'string', description: 'Message content' },
cost: { type: 'string', description: 'Message cost (optional)' }
},
required: ['messageSid', 'status', 'to', 'from', 'body']
}
}
},
{
id: 'make_call',
name: 'Make Voice Call',
description: 'Make voice calls with text-to-speech',
category: 'communication',
minimumTier: 'PRO',
rateLimits: {
requestsPerHour: 20
},
requiresAuth: true,
isPremium: false,
version: '1.0.0',
parameters: [
{
name: 'to',
type: 'string',
description: 'Recipient phone number (E.164 format)',
required: true,
schema: {
pattern: '^\\+[1-9]\\d{1,14}$'
}
},
{
name: 'message',
type: 'string',
description: 'Text-to-speech message',
required: true,
schema: {
maxLength: 4000
}
},
{
name: 'voice',
type: 'string',
description: 'Voice type for TTS',
required: false,
schema: {
enum: ['man', 'woman', 'alice']
}
}
],
returnType: {
type: 'object',
description: 'Voice call result',
schema: {
type: 'object',
properties: {
callSid: { type: 'string', description: 'Twilio call SID' },
status: { type: 'string', description: 'Call status' },
to: { type: 'string', description: 'Recipient phone number' },
from: { type: 'string', description: 'Caller phone number' },
duration: { type: 'string', description: 'Call duration (optional)' }
},
required: ['callSid', 'status', 'to', 'from']
}
}
}
];
}
getTool(toolId) {
return this.getAvailableTools().find(tool => tool.id === toolId);
}
async authenticate(credentials) {
return this.validateCredentials(credentials);
}
async execute(toolId, params, context) {
if (!context) {
throw new Error('Execution context is required');
}
const credentials = context.metadata?.credentials;
if (!credentials) {
throw new Error('Twilio credentials not provided in context');
}
return this.executeTool(toolId, params, credentials, context);
}
validateConfig(toolId, config) {
const tool = this.getTool(toolId);
if (!tool) {
return {
isValid: false,
errors: [`Unknown tool: ${toolId}`]
};
}
const errors = [];
if (config && typeof config === 'object') {
}
else {
errors.push('Configuration must be an object');
}
return {
isValid: errors.length === 0,
errors: errors.length > 0 ? errors : []
};
}
getConfigSchema(toolId) {
const tool = this.getTool(toolId);
if (!tool) {
return undefined;
}
return {
type: 'object',
properties: {
enabled: {
type: 'boolean',
title: 'Enable Tool',
description: `Enable ${tool.name}`,
default: true
}
},
required: ['enabled']
};
}
async validateCredentials(credentials) {
try {
if (!credentials.accountSid || !credentials.authToken || !credentials.fromPhoneNumber) {
return false;
}
const phoneRegex = /^\+[1-9]\d{1,14}$/;
if (!phoneRegex.test(credentials.fromPhoneNumber)) {
return false;
}
return credentials.accountSid.startsWith('AC') &&
credentials.authToken.length >= 32;
}
catch (error) {
console.error('[TwilioProvider] Credential validation failed:', error);
return false;
}
}
async executeTool(toolId, params, credentials, context) {
try {
switch (toolId) {
case 'send_sms':
return await this.sendSMS(params, credentials, context);
case 'make_call':
return await this.makeCall(params, credentials, context);
default:
throw new Error(`Unknown tool: ${toolId}`);
}
}
catch (error) {
console.error(`[TwilioProvider] Tool execution failed for ${toolId}:`, error);
throw error;
}
}
async sendSMS(params, credentials, context) {
try {
const mockResponse = {
messageSid: `SM${Date.now()}${Math.random().toString(36).substr(2, 9)}`,
status: 'sent',
to: params.to,
from: credentials.fromPhoneNumber,
body: params.message,
cost: '0.0075'
};
console.log(`[TwilioProvider] SMS sent:`, {
to: params.to,
from: credentials.fromPhoneNumber,
messageLength: params.message.length,
hasMedia: !!params.mediaUrl,
organizationId: context.organizationId,
agentId: context.agentId
});
return {
success: true,
data: mockResponse,
...mockResponse
};
}
catch (error) {
console.error('[TwilioProvider] SMS sending failed:', error);
return {
success: false,
error: error instanceof Error ? error.message : 'Failed to send SMS',
data: null,
messageSid: '',
status: 'failed',
to: params.to,
from: credentials.fromPhoneNumber,
body: params.message
};
}
}
async makeCall(params, credentials, context) {
try {
const mockResponse = {
callSid: `CA${Date.now()}${Math.random().toString(36).substr(2, 9)}`,
status: 'in-progress',
to: params.to,
from: credentials.fromPhoneNumber,
duration: '0'
};
console.log(`[TwilioProvider] Call initiated:`, {
to: params.to,
from: credentials.fromPhoneNumber,
messageLength: params.message.length,
voice: params.voice || 'default',
organizationId: context.organizationId,
agentId: context.agentId
});
return {
success: true,
data: mockResponse,
...mockResponse
};
}
catch (error) {
console.error('[TwilioProvider] Call initiation failed:', error);
return {
success: false,
error: error instanceof Error ? error.message : 'Failed to initiate call',
data: null,
callSid: '',
status: 'failed',
to: params.to,
from: credentials.fromPhoneNumber
};
}
}
async getUsageStats(organizationId, period = 'month') {
return {
sms_sent: 0,
calls_made: 0,
total_cost: 0,
period
};
}
}
exports.TwilioToolProvider = TwilioToolProvider;
//# sourceMappingURL=TwilioToolProvider.js.map