@framers/agentos-ext-voice-plivo 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,228 @@
1
+ "use strict";
2
+ // @ts-nocheck
3
+ /**
4
+ * @fileoverview Wrapper around the Plivo Voice API SDK.
5
+ *
6
+ * Handles Plivo client lifecycle, call control operations (create, hangup,
7
+ * speak), Plivo XML generation for notify/conversation modes, and webhook
8
+ * signature verification.
9
+ *
10
+ * @module @framers/agentos-ext-voice-plivo/PlivoVoiceService
11
+ */
12
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ var desc = Object.getOwnPropertyDescriptor(m, k);
15
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
16
+ desc = { enumerable: true, get: function() { return m[k]; } };
17
+ }
18
+ Object.defineProperty(o, k2, desc);
19
+ }) : (function(o, m, k, k2) {
20
+ if (k2 === undefined) k2 = k;
21
+ o[k2] = m[k];
22
+ }));
23
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
24
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
25
+ }) : function(o, v) {
26
+ o["default"] = v;
27
+ });
28
+ var __importStar = (this && this.__importStar) || (function () {
29
+ var ownKeys = function(o) {
30
+ ownKeys = Object.getOwnPropertyNames || function (o) {
31
+ var ar = [];
32
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
33
+ return ar;
34
+ };
35
+ return ownKeys(o);
36
+ };
37
+ return function (mod) {
38
+ if (mod && mod.__esModule) return mod;
39
+ var result = {};
40
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
41
+ __setModuleDefault(result, mod);
42
+ return result;
43
+ };
44
+ })();
45
+ Object.defineProperty(exports, "__esModule", { value: true });
46
+ exports.PlivoVoiceService = void 0;
47
+ const node_crypto_1 = require("node:crypto");
48
+ const agentos_1 = require("@framers/agentos");
49
+ /** Default Plivo TTS voice. */
50
+ const DEFAULT_VOICE = 'Polly.Joanna';
51
+ // ============================================================================
52
+ // Service
53
+ // ============================================================================
54
+ class PlivoVoiceService {
55
+ constructor(config) {
56
+ this.client = null;
57
+ this.config = config;
58
+ }
59
+ // ── Lifecycle ──
60
+ /**
61
+ * Initialize the Plivo SDK client via dynamic import.
62
+ * Plivo's Node SDK is CommonJS; dynamic import avoids bundling issues.
63
+ */
64
+ async initialize() {
65
+ if (this.client)
66
+ return;
67
+ try {
68
+ const plivoModule = await Promise.resolve().then(() => __importStar(require('plivo')));
69
+ const Plivo = plivoModule.default ?? plivoModule;
70
+ this.client = new Plivo.Client(this.config.authId, this.config.authToken);
71
+ }
72
+ catch (err) {
73
+ throw new Error(`Failed to initialize Plivo client. Ensure the "plivo" package is installed: ${err instanceof Error ? err.message : String(err)}`);
74
+ }
75
+ }
76
+ /**
77
+ * Gracefully shut down the service and release resources.
78
+ */
79
+ async shutdown() {
80
+ this.client = null;
81
+ }
82
+ /** Whether the service has been initialized. */
83
+ get isInitialized() {
84
+ return this.client !== null;
85
+ }
86
+ // ── Call Control ──
87
+ /**
88
+ * Create an outbound call via the Plivo Calls API.
89
+ *
90
+ * @param from - E.164 caller ID.
91
+ * @param to - E.164 destination number.
92
+ * @param answerUrl - URL Plivo fetches when the call is answered.
93
+ * @param answerMethod - HTTP method for the answer URL (GET or POST).
94
+ * @returns The Plivo API response containing `requestUuid` (call UUID).
95
+ */
96
+ async createCall(from, to, answerUrl, answerMethod = 'POST') {
97
+ this.ensureInitialized();
98
+ const response = await this.client.calls.create(from, to, answerUrl, {
99
+ answerMethod,
100
+ });
101
+ return {
102
+ requestUuid: response.requestUuid ?? response.request_uuid,
103
+ apiId: response.apiId ?? response.api_id,
104
+ message: response.message ?? '',
105
+ };
106
+ }
107
+ /**
108
+ * Hang up an active call by its UUID.
109
+ *
110
+ * @param callUuid - The Plivo call UUID to terminate.
111
+ */
112
+ async hangupCall(callUuid) {
113
+ this.ensureInitialized();
114
+ await this.client.calls.hangup(callUuid);
115
+ }
116
+ /**
117
+ * Play TTS speech into an active call via the Plivo Speak API.
118
+ *
119
+ * @param callUuid - The Plivo call UUID.
120
+ * @param text - Text to speak.
121
+ * @param voice - Plivo voice name (default: Polly.Joanna).
122
+ */
123
+ async speakText(callUuid, text, voice) {
124
+ this.ensureInitialized();
125
+ await this.client.calls.speak(callUuid, text, {
126
+ voice: voice ?? DEFAULT_VOICE,
127
+ });
128
+ }
129
+ // ── Plivo XML Generation ──
130
+ /**
131
+ * Generate Plivo XML for "notify" mode: speak a message then hang up.
132
+ *
133
+ * @param message - The message text to speak.
134
+ * @param voice - Plivo TTS voice (default: Polly.Joanna).
135
+ * @returns Plivo XML string.
136
+ *
137
+ * @example
138
+ * ```xml
139
+ * <?xml version="1.0" encoding="UTF-8"?>
140
+ * <Response>
141
+ * <Speak voice="Polly.Joanna">Hello, your appointment is confirmed.</Speak>
142
+ * <Hangup/>
143
+ * </Response>
144
+ * ```
145
+ */
146
+ generateNotifyXml(message, voice) {
147
+ const v = voice ?? DEFAULT_VOICE;
148
+ const escaped = (0, agentos_1.escapeXml)(message);
149
+ return [
150
+ '<?xml version="1.0" encoding="UTF-8"?>',
151
+ '<Response>',
152
+ ` <Speak voice="${v}">${escaped}</Speak>`,
153
+ ' <Hangup/>',
154
+ '</Response>',
155
+ ].join('\n');
156
+ }
157
+ /**
158
+ * Generate Plivo XML for "conversation" mode: speak a greeting,
159
+ * gather DTMF/speech input, then redirect back to the webhook URL
160
+ * for a multi-turn loop.
161
+ *
162
+ * @param webhookUrl - URL to redirect to after gathering input.
163
+ * @param greeting - Optional greeting to speak before gathering.
164
+ * @param voice - Plivo TTS voice (default: Polly.Joanna).
165
+ * @returns Plivo XML string.
166
+ *
167
+ * @example
168
+ * ```xml
169
+ * <?xml version="1.0" encoding="UTF-8"?>
170
+ * <Response>
171
+ * <Speak voice="Polly.Joanna">Hello, how can I help you?</Speak>
172
+ * <GetInput action="https://example.com/voice/webhook/plivo"
173
+ * method="POST" inputType="speech" executionTimeout="30">
174
+ * <Speak voice="Polly.Joanna">I am listening.</Speak>
175
+ * </GetInput>
176
+ * <Redirect method="POST">https://example.com/voice/webhook/plivo</Redirect>
177
+ * </Response>
178
+ * ```
179
+ */
180
+ generateConversationXml(webhookUrl, greeting, voice) {
181
+ const v = voice ?? DEFAULT_VOICE;
182
+ const escapedUrl = (0, agentos_1.escapeXml)(webhookUrl);
183
+ const lines = [
184
+ '<?xml version="1.0" encoding="UTF-8"?>',
185
+ '<Response>',
186
+ ];
187
+ if (greeting) {
188
+ lines.push(` <Speak voice="${v}">${(0, agentos_1.escapeXml)(greeting)}</Speak>`);
189
+ }
190
+ lines.push(` <GetInput action="${escapedUrl}" method="POST" inputType="speech" executionTimeout="30">`, ` <Speak voice="${v}">I am listening.</Speak>`, ' </GetInput>', ` <Redirect method="POST">${escapedUrl}</Redirect>`, '</Response>');
191
+ return lines.join('\n');
192
+ }
193
+ // ── Webhook Verification ──
194
+ /**
195
+ * Verify a Plivo webhook signature (V3 — HMAC-SHA256).
196
+ *
197
+ * Plivo V3 signatures are computed as:
198
+ * HMAC-SHA256(authToken, requestUrl + nonce)
199
+ * and sent via the `X-Plivo-Signature-V3` header.
200
+ *
201
+ * @param url - The full request URL (including query string).
202
+ * @param nonce - The nonce from `X-Plivo-Signature-V3-Nonce` header.
203
+ * @param signature - The signature from `X-Plivo-Signature-V3` header.
204
+ * @param authToken - The Plivo auth token used as the HMAC key.
205
+ * @returns Whether the signature is valid.
206
+ */
207
+ verifySignature(url, nonce, signature, authToken) {
208
+ const expected = (0, node_crypto_1.createHmac)('sha256', authToken)
209
+ .update(url + nonce)
210
+ .digest('base64');
211
+ // Constant-time comparison
212
+ if (expected.length !== signature.length)
213
+ return false;
214
+ let mismatch = 0;
215
+ for (let i = 0; i < expected.length; i++) {
216
+ mismatch |= expected.charCodeAt(i) ^ signature.charCodeAt(i);
217
+ }
218
+ return mismatch === 0;
219
+ }
220
+ // ── Internal ──
221
+ ensureInitialized() {
222
+ if (!this.client) {
223
+ throw new Error('PlivoVoiceService is not initialized. Call initialize() first.');
224
+ }
225
+ }
226
+ }
227
+ exports.PlivoVoiceService = PlivoVoiceService;
228
+ //# sourceMappingURL=PlivoVoiceService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PlivoVoiceService.js","sourceRoot":"","sources":["../src/PlivoVoiceService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * @fileoverview Plivo Voice Provider Extension for AgentOS.
3
+ *
4
+ * Provides an IVoiceCallProvider implementation backed by the Plivo Voice API,
5
+ * plus an ITool descriptor for programmatic voice call management.
6
+ *
7
+ * @module @framers/agentos-ext-voice-plivo
8
+ */
9
+ import type { ExtensionContext, ExtensionPack, CallManager } from '@framers/agentos';
10
+ export interface PlivoVoiceOptions {
11
+ /** Plivo Auth ID (overrides secrets/env). */
12
+ authId?: string;
13
+ /** Plivo Auth Token (overrides secrets/env). */
14
+ authToken?: string;
15
+ /** E.164 outbound caller ID (overrides secrets/env). */
16
+ fromNumber?: string;
17
+ /** Environment variable name for Auth ID (default: PLIVO_AUTH_ID). */
18
+ authIdEnv?: string;
19
+ /** Environment variable name for Auth Token (default: PLIVO_AUTH_TOKEN). */
20
+ authTokenEnv?: string;
21
+ /** Environment variable name for From Number (default: PLIVO_FROM_NUMBER). */
22
+ fromNumberEnv?: string;
23
+ /** Optional CallManager instance for the tool handler. */
24
+ callManager?: CallManager;
25
+ /** Extension priority (default: 50). */
26
+ priority?: number;
27
+ }
28
+ /**
29
+ * Create the Plivo Voice Provider extension pack.
30
+ *
31
+ * Resolves credentials from options, secrets map, or environment variables,
32
+ * then creates the PlivoVoiceService, PlivoVoiceProvider, and PlivoVoiceCallTool.
33
+ *
34
+ * @param context - Extension context with options, logger, and secrets.
35
+ * @returns An ExtensionPack with tool and voice-provider descriptors.
36
+ *
37
+ * @example
38
+ * ```typescript
39
+ * import { createExtensionPack } from '@framers/agentos-ext-voice-plivo';
40
+ *
41
+ * const pack = createExtensionPack({
42
+ * options: {
43
+ * authId: 'MAXXXXXXXXXX',
44
+ * authToken: 'your-auth-token',
45
+ * fromNumber: '+15551234567',
46
+ * callManager: myCallManager,
47
+ * },
48
+ * });
49
+ * ```
50
+ */
51
+ export declare function createExtensionPack(context: ExtensionContext): ExtensionPack;
52
+ export { PlivoVoiceService, type PlivoServiceConfig } from './PlivoVoiceService';
53
+ export { PlivoVoiceProvider, createPlivoVoiceProvider } from './PlivoVoiceProvider';
54
+ export { PlivoVoiceCallTool, type VoiceCallToolHandler } from './tools/voiceCall';
55
+ export default createExtensionPack;
56
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AASrF,MAAM,WAAW,iBAAiB;IAChC,6CAA6C;IAC7C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gDAAgD;IAChD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wDAAwD;IACxD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,sEAAsE;IACtE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4EAA4E;IAC5E,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,8EAA8E;IAC9E,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,0DAA0D;IAC1D,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,wCAAwC;IACxC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAoFD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,gBAAgB,GAAG,aAAa,CAqE5E;AAGD,OAAO,EAAE,iBAAiB,EAAE,KAAK,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACjF,OAAO,EAAE,kBAAkB,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AACpF,OAAO,EAAE,kBAAkB,EAAE,KAAK,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAClF,eAAe,mBAAmB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,151 @@
1
+ "use strict";
2
+ // @ts-nocheck
3
+ /**
4
+ * @fileoverview Plivo Voice Provider Extension for AgentOS.
5
+ *
6
+ * Provides an IVoiceCallProvider implementation backed by the Plivo Voice API,
7
+ * plus an ITool descriptor for programmatic voice call management.
8
+ *
9
+ * @module @framers/agentos-ext-voice-plivo
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.PlivoVoiceCallTool = exports.createPlivoVoiceProvider = exports.PlivoVoiceProvider = exports.PlivoVoiceService = void 0;
13
+ exports.createExtensionPack = createExtensionPack;
14
+ const PlivoVoiceService_1 = require("./PlivoVoiceService");
15
+ const PlivoVoiceProvider_1 = require("./PlivoVoiceProvider");
16
+ const voiceCall_1 = require("./tools/voiceCall");
17
+ // ============================================================================
18
+ // Secret/Env Resolution
19
+ // ============================================================================
20
+ function resolveSecret(key, optionsValue, secrets, secretKey, envName, ...envFallbacks) {
21
+ // 1. Direct option
22
+ if (optionsValue)
23
+ return optionsValue;
24
+ // 2. Secrets map
25
+ if (secrets?.[secretKey])
26
+ return secrets[secretKey];
27
+ // 3. Primary environment variable
28
+ if (process.env[envName])
29
+ return process.env[envName];
30
+ // 4. Fallback env vars
31
+ for (const fallback of envFallbacks) {
32
+ if (process.env[fallback])
33
+ return process.env[fallback];
34
+ }
35
+ throw new Error(`Plivo ${key} not found. Provide via options.${key}, secrets["${secretKey}"], or ${envName} env var.`);
36
+ }
37
+ // ============================================================================
38
+ // CallManager Tool Handler Adapter
39
+ // ============================================================================
40
+ /**
41
+ * Adapts a CallManager instance into the VoiceCallToolHandler interface
42
+ * expected by the PlivoVoiceCallTool.
43
+ */
44
+ function createCallManagerHandler(callManager) {
45
+ return {
46
+ async initiateCall(toNumber, message, mode) {
47
+ return callManager.initiateCall({ toNumber, message, mode });
48
+ },
49
+ speakText(callId, text) {
50
+ callManager.speakText(callId, text);
51
+ },
52
+ async hangupCall(callId) {
53
+ await callManager.hangupCall(callId);
54
+ },
55
+ getCallStatus(callId) {
56
+ return callManager.getCall(callId);
57
+ },
58
+ getActiveCalls() {
59
+ return callManager.getActiveCalls();
60
+ },
61
+ };
62
+ }
63
+ /**
64
+ * Stub handler used when no CallManager is provided.
65
+ * The tool will return errors explaining that a CallManager is required.
66
+ */
67
+ function createStubHandler() {
68
+ const err = () => {
69
+ throw new Error('No CallManager configured. Provide options.callManager to enable voice call operations.');
70
+ };
71
+ return {
72
+ initiateCall: err,
73
+ speakText: err,
74
+ hangupCall: err,
75
+ getCallStatus: () => undefined,
76
+ getActiveCalls: () => [],
77
+ };
78
+ }
79
+ // ============================================================================
80
+ // Extension Pack Factory
81
+ // ============================================================================
82
+ /**
83
+ * Create the Plivo Voice Provider extension pack.
84
+ *
85
+ * Resolves credentials from options, secrets map, or environment variables,
86
+ * then creates the PlivoVoiceService, PlivoVoiceProvider, and PlivoVoiceCallTool.
87
+ *
88
+ * @param context - Extension context with options, logger, and secrets.
89
+ * @returns An ExtensionPack with tool and voice-provider descriptors.
90
+ *
91
+ * @example
92
+ * ```typescript
93
+ * import { createExtensionPack } from '@framers/agentos-ext-voice-plivo';
94
+ *
95
+ * const pack = createExtensionPack({
96
+ * options: {
97
+ * authId: 'MAXXXXXXXXXX',
98
+ * authToken: 'your-auth-token',
99
+ * fromNumber: '+15551234567',
100
+ * callManager: myCallManager,
101
+ * },
102
+ * });
103
+ * ```
104
+ */
105
+ function createExtensionPack(context) {
106
+ const options = (context.options ?? {});
107
+ // Resolve credentials
108
+ const authId = resolveSecret('authId', options.authId, options.secrets, 'plivo.authId', options.authIdEnv ?? 'PLIVO_AUTH_ID', 'PLIVO_AUTH_ID');
109
+ const authToken = resolveSecret('authToken', options.authToken, options.secrets, 'plivo.authToken', options.authTokenEnv ?? 'PLIVO_AUTH_TOKEN', 'PLIVO_AUTH_TOKEN');
110
+ const fromNumber = resolveSecret('fromNumber', options.fromNumber, options.secrets, 'plivo.fromNumber', options.fromNumberEnv ?? 'PLIVO_FROM_NUMBER', 'PLIVO_FROM_NUMBER', 'PLIVO_PHONE_NUMBER');
111
+ // Create service and provider
112
+ const serviceConfig = { authId, authToken, fromNumber };
113
+ const service = new PlivoVoiceService_1.PlivoVoiceService(serviceConfig);
114
+ const provider = (0, PlivoVoiceProvider_1.createPlivoVoiceProvider)(service, authToken);
115
+ // Create tool with CallManager handler or stub
116
+ const handler = options.callManager
117
+ ? createCallManagerHandler(options.callManager)
118
+ : createStubHandler();
119
+ const voiceCallTool = new voiceCall_1.PlivoVoiceCallTool(handler);
120
+ const priority = options.priority ?? 50;
121
+ return {
122
+ name: '@framers/agentos-ext-voice-plivo',
123
+ version: '0.1.0',
124
+ descriptors: [
125
+ { id: 'plivoVoiceCall', kind: 'tool', priority, payload: voiceCallTool },
126
+ { id: 'plivoVoiceProvider', kind: 'voice-provider', priority, payload: provider },
127
+ ],
128
+ onActivate: async () => {
129
+ await service.initialize();
130
+ // If a CallManager was provided, register the provider
131
+ if (options.callManager) {
132
+ options.callManager.registerProvider(provider);
133
+ }
134
+ context.logger?.info('[PlivoVoice] Extension activated');
135
+ },
136
+ onDeactivate: async () => {
137
+ await service.shutdown();
138
+ context.logger?.info('[PlivoVoice] Extension deactivated');
139
+ },
140
+ };
141
+ }
142
+ // Re-export public API
143
+ var PlivoVoiceService_2 = require("./PlivoVoiceService");
144
+ Object.defineProperty(exports, "PlivoVoiceService", { enumerable: true, get: function () { return PlivoVoiceService_2.PlivoVoiceService; } });
145
+ var PlivoVoiceProvider_2 = require("./PlivoVoiceProvider");
146
+ Object.defineProperty(exports, "PlivoVoiceProvider", { enumerable: true, get: function () { return PlivoVoiceProvider_2.PlivoVoiceProvider; } });
147
+ Object.defineProperty(exports, "createPlivoVoiceProvider", { enumerable: true, get: function () { return PlivoVoiceProvider_2.createPlivoVoiceProvider; } });
148
+ var voiceCall_2 = require("./tools/voiceCall");
149
+ Object.defineProperty(exports, "PlivoVoiceCallTool", { enumerable: true, get: function () { return voiceCall_2.PlivoVoiceCallTool; } });
150
+ exports.default = createExtensionPack;
151
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,113 @@
1
+ /**
2
+ * @fileoverview ITool implementation for Plivo voice calls.
3
+ *
4
+ * Provides the `plivoVoiceCall` tool that agents can invoke to make
5
+ * outbound phone calls, speak text into active calls, hang up calls,
6
+ * and query call status.
7
+ *
8
+ * Follows the same VoiceCallTool pattern used by Twilio/Telnyx extensions.
9
+ *
10
+ * @module @framers/agentos-ext-voice-plivo/tools/voiceCall
11
+ */
12
+ import type { ITool, ToolExecutionContext, ToolExecutionResult } from '@framers/agentos';
13
+ import type { CallMode, CallRecord } from '@framers/agentos';
14
+ /**
15
+ * Abstraction over the CallManager's operations so the tool
16
+ * does not depend directly on CallManager internals.
17
+ */
18
+ export interface VoiceCallToolHandler {
19
+ /** Initiate an outbound call. */
20
+ initiateCall(toNumber: string, message?: string, mode?: CallMode): Promise<CallRecord>;
21
+ /** Speak text into an active call. */
22
+ speakText(callId: string, text: string): void;
23
+ /** Hang up an active call. */
24
+ hangupCall(callId: string): Promise<void>;
25
+ /** Get the status of a call by ID. */
26
+ getCallStatus(callId: string): CallRecord | undefined;
27
+ /** Get all active (non-terminal) calls. */
28
+ getActiveCalls(): CallRecord[];
29
+ }
30
+ type VoiceCallAction = 'call' | 'speak' | 'hangup' | 'status' | 'list';
31
+ interface VoiceCallArgs {
32
+ /** Action to perform. */
33
+ action: VoiceCallAction;
34
+ /** E.164 phone number to call (for 'call' action). */
35
+ toNumber?: string;
36
+ /** Call ID (for 'speak', 'hangup', 'status' actions). */
37
+ callId?: string;
38
+ /** Text message to speak (for 'call' in notify mode, or 'speak' action). */
39
+ message?: string;
40
+ /** Call mode: 'notify' or 'conversation' (for 'call' action). */
41
+ mode?: CallMode;
42
+ }
43
+ export declare class PlivoVoiceCallTool implements ITool<VoiceCallArgs> {
44
+ private readonly handler;
45
+ readonly id = "plivoVoiceCall";
46
+ readonly name = "plivoVoiceCall";
47
+ readonly displayName = "Plivo Voice Call";
48
+ readonly description: string;
49
+ readonly category = "telephony";
50
+ readonly version = "0.1.0";
51
+ readonly hasSideEffects = true;
52
+ readonly inputSchema: {
53
+ type: "object";
54
+ required: readonly ["action"];
55
+ properties: {
56
+ action: {
57
+ type: string;
58
+ enum: string[];
59
+ description: string;
60
+ };
61
+ toNumber: {
62
+ type: string;
63
+ description: string;
64
+ };
65
+ callId: {
66
+ type: string;
67
+ description: string;
68
+ };
69
+ message: {
70
+ type: string;
71
+ description: string;
72
+ };
73
+ mode: {
74
+ type: string;
75
+ enum: string[];
76
+ description: string;
77
+ };
78
+ };
79
+ };
80
+ readonly outputSchema: {
81
+ type: "object";
82
+ properties: {
83
+ callId: {
84
+ type: string;
85
+ description: string;
86
+ };
87
+ state: {
88
+ type: string;
89
+ description: string;
90
+ };
91
+ calls: {
92
+ type: string;
93
+ description: string;
94
+ items: {
95
+ type: string;
96
+ };
97
+ };
98
+ };
99
+ };
100
+ constructor(handler: VoiceCallToolHandler);
101
+ execute(args: VoiceCallArgs, _context: ToolExecutionContext): Promise<ToolExecutionResult>;
102
+ validateArgs(args: Record<string, any>): {
103
+ isValid: boolean;
104
+ errors?: string[];
105
+ };
106
+ private handleCall;
107
+ private handleSpeak;
108
+ private handleHangup;
109
+ private handleStatus;
110
+ private handleList;
111
+ }
112
+ export {};
113
+ //# sourceMappingURL=voiceCall.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"voiceCall.d.ts","sourceRoot":"","sources":["../../src/tools/voiceCall.ts"],"names":[],"mappings":"AACA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EACV,KAAK,EACL,oBAAoB,EACpB,mBAAmB,EACpB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EACV,QAAQ,EACR,UAAU,EACX,MAAM,kBAAkB,CAAC;AAM1B;;;GAGG;AACH,MAAM,WAAW,oBAAoB;IACnC,iCAAiC;IACjC,YAAY,CACV,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,MAAM,EAChB,IAAI,CAAC,EAAE,QAAQ,GACd,OAAO,CAAC,UAAU,CAAC,CAAC;IACvB,sCAAsC;IACtC,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9C,8BAA8B;IAC9B,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,sCAAsC;IACtC,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAAC;IACtD,2CAA2C;IAC3C,cAAc,IAAI,UAAU,EAAE,CAAC;CAChC;AAMD,KAAK,eAAe,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC;AAEvE,UAAU,aAAa;IACrB,yBAAyB;IACzB,MAAM,EAAE,eAAe,CAAC;IACxB,sDAAsD;IACtD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,yDAAyD;IACzD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4EAA4E;IAC5E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iEAAiE;IACjE,IAAI,CAAC,EAAE,QAAQ,CAAC;CACjB;AAMD,qBAAa,kBAAmB,YAAW,KAAK,CAAC,aAAa,CAAC;IAuDjD,OAAO,CAAC,QAAQ,CAAC,OAAO;IAtDpC,SAAgB,EAAE,oBAAoB;IACtC,SAAgB,IAAI,oBAAoB;IACxC,SAAgB,WAAW,sBAAsB;IACjD,SAAgB,WAAW,SAG6D;IACxF,SAAgB,QAAQ,eAAe;IACvC,SAAgB,OAAO,WAAW;IAClC,SAAgB,cAAc,QAAQ;IAEtC,SAAgB,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;MA4BzB;IAEF,SAAgB,YAAY;;;;;;;;;;;;;;;;;;;MAW1B;gBAE2B,OAAO,EAAE,oBAAoB;IAEpD,OAAO,CACX,IAAI,EAAE,aAAa,EACnB,QAAQ,EAAE,oBAAoB,GAC7B,OAAO,CAAC,mBAAmB,CAAC;IAwB/B,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE;YA2BlE,UAAU;IAyBxB,OAAO,CAAC,WAAW;YAgBL,YAAY;IAa1B,OAAO,CAAC,YAAY;IA4BpB,OAAO,CAAC,UAAU;CAmBnB"}