@framers/agentos-ext-voice-synthesis 1.0.0 → 2.0.1

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.
@@ -1,7 +1,11 @@
1
1
  /**
2
- * ElevenLabs TTS Tool — text-to-speech synthesis.
2
+ * Multi-provider TTS Tool — text-to-speech synthesis.
3
+ *
4
+ * Supports: OpenAI TTS, ElevenLabs, Ollama (local), any OpenAI-compatible TTS API.
5
+ * Auto-detects available provider from API keys in environment.
3
6
  */
4
- const VOICES = {
7
+ // ── ElevenLabs voice name → ID mapping ──
8
+ const ELEVENLABS_VOICES = {
5
9
  rachel: '21m00Tcm4TlvDq8ikWAM',
6
10
  domi: 'AZnzlk1XvdvUeBnXmlld',
7
11
  bella: 'EXAVITQu4vr4xnSDxMaL',
@@ -11,62 +15,208 @@ const VOICES = {
11
15
  adam: 'pNInz6obpgDQGcFmaJgB',
12
16
  sam: 'yoZ06aMxZJJ28mfd3POQ',
13
17
  };
18
+ // ── OpenAI voice options ──
19
+ const OPENAI_VOICES = ['alloy', 'echo', 'fable', 'onyx', 'nova', 'shimmer'];
14
20
  export class TextToSpeechTool {
15
- id = 'elevenlabs-tts-v1';
21
+ id = 'tts-multi-provider-v1';
16
22
  name = 'text_to_speech';
17
23
  displayName = 'Text to Speech';
18
- description = 'Convert text to speech using ElevenLabs. Returns base64-encoded MP3 audio. ' +
19
- 'Voices: rachel, domi, bella, antoni, josh, arnold, adam, sam.';
24
+ description = 'Convert text to speech audio. Supports multiple providers: OpenAI TTS (alloy/echo/fable/onyx/nova/shimmer), ' +
25
+ 'ElevenLabs (rachel/domi/bella/antoni/josh/arnold/adam/sam), or local Ollama TTS. ' +
26
+ 'Auto-detects available provider from API keys. Returns base64-encoded audio.';
20
27
  category = 'media';
21
- version = '1.0.0';
28
+ version = '2.0.0';
22
29
  hasSideEffects = false;
23
30
  inputSchema = {
24
31
  type: 'object',
25
32
  properties: {
26
- text: { type: 'string', description: 'Text to convert. Max 5000 chars.' },
27
- voice: { type: 'string', default: 'rachel', description: 'Voice name or ID.' },
28
- model: { type: 'string', default: 'eleven_monolingual_v1' },
29
- stability: { type: 'number', minimum: 0, maximum: 1, default: 0.5 },
30
- similarity_boost: { type: 'number', minimum: 0, maximum: 1, default: 0.75 },
33
+ text: { type: 'string', description: 'Text to convert to speech. Max 5000 chars.' },
34
+ voice: {
35
+ type: 'string',
36
+ description: 'Voice name. OpenAI: alloy, echo, fable, onyx, nova (default), shimmer. ' +
37
+ 'ElevenLabs: rachel (default), domi, bella, antoni, josh, arnold, adam, sam. ' +
38
+ 'Or a custom voice ID.',
39
+ },
40
+ model: {
41
+ type: 'string',
42
+ description: 'TTS model. OpenAI: tts-1 (default), tts-1-hd. ElevenLabs: eleven_monolingual_v1 (default), eleven_multilingual_v2.',
43
+ },
44
+ provider: {
45
+ type: 'string',
46
+ enum: ['openai', 'elevenlabs', 'ollama', 'auto'],
47
+ description: 'TTS provider. Default: auto (detects from available API keys).',
48
+ },
49
+ speed: { type: 'number', minimum: 0.25, maximum: 4.0, description: 'OpenAI speed multiplier (0.25-4.0).' },
50
+ stability: { type: 'number', minimum: 0, maximum: 1, description: 'ElevenLabs voice stability (0-1).' },
51
+ similarity_boost: { type: 'number', minimum: 0, maximum: 1, description: 'ElevenLabs similarity boost (0-1).' },
52
+ format: { type: 'string', enum: ['mp3', 'opus', 'aac', 'flac', 'wav'], description: 'Output audio format.' },
31
53
  },
32
54
  required: ['text'],
33
55
  };
34
56
  requiredCapabilities = ['capability:tts'];
35
- apiKey;
36
- constructor(apiKey) {
37
- this.apiKey = apiKey || process.env.ELEVENLABS_API_KEY || '';
57
+ config;
58
+ constructor(config) {
59
+ this.config = {
60
+ openaiApiKey: config?.openaiApiKey || process.env.OPENAI_API_KEY || '',
61
+ openaiBaseUrl: config?.openaiBaseUrl || process.env.OPENAI_BASE_URL || 'https://api.openai.com/v1',
62
+ elevenLabsApiKey: config?.elevenLabsApiKey || process.env.ELEVENLABS_API_KEY || '',
63
+ ollamaBaseUrl: config?.ollamaBaseUrl || process.env.OLLAMA_BASE_URL || 'http://localhost:11434',
64
+ defaultProvider: config?.defaultProvider || process.env.TTS_PROVIDER || 'auto',
65
+ };
66
+ }
67
+ resolveProvider(requested) {
68
+ const pref = requested || this.config.defaultProvider || 'auto';
69
+ if (pref !== 'auto') {
70
+ // Verify the requested provider has credentials
71
+ if (pref === 'openai' && this.config.openaiApiKey)
72
+ return 'openai';
73
+ if (pref === 'elevenlabs' && this.config.elevenLabsApiKey)
74
+ return 'elevenlabs';
75
+ if (pref === 'ollama')
76
+ return 'ollama';
77
+ // Fall through to auto if requested provider isn't configured
78
+ }
79
+ // Auto-detect: prefer OpenAI (cheaper, faster), then ElevenLabs, then Ollama
80
+ if (this.config.openaiApiKey)
81
+ return 'openai';
82
+ if (this.config.elevenLabsApiKey)
83
+ return 'elevenlabs';
84
+ return 'ollama'; // Local fallback — may or may not have TTS model
38
85
  }
39
86
  async execute(args, _context) {
40
- if (!this.apiKey)
41
- return { success: false, error: 'ELEVENLABS_API_KEY not configured.' };
42
87
  const text = args.text.slice(0, 5000);
43
- const voiceId = VOICES[(args.voice || 'rachel').toLowerCase()] || args.voice || VOICES.rachel;
88
+ const provider = this.resolveProvider(args.provider);
89
+ if (!provider) {
90
+ return {
91
+ success: false,
92
+ error: 'No TTS provider available. Set one of: OPENAI_API_KEY, ELEVENLABS_API_KEY, or configure Ollama with a TTS model. ' +
93
+ 'Get an OpenAI key at https://platform.openai.com/api-keys or ElevenLabs at https://elevenlabs.io',
94
+ };
95
+ }
96
+ try {
97
+ switch (provider) {
98
+ case 'openai':
99
+ return await this.synthesizeOpenAI(text, args);
100
+ case 'elevenlabs':
101
+ return await this.synthesizeElevenLabs(text, args);
102
+ case 'ollama':
103
+ return await this.synthesizeOllama(text, args);
104
+ default:
105
+ return { success: false, error: `Unknown TTS provider: ${provider}` };
106
+ }
107
+ }
108
+ catch (err) {
109
+ return { success: false, error: `TTS failed (${provider}): ${err.message}` };
110
+ }
111
+ }
112
+ // ── OpenAI TTS ──
113
+ async synthesizeOpenAI(text, args) {
114
+ const voice = args.voice && OPENAI_VOICES.includes(args.voice) ? args.voice : 'nova';
115
+ const model = args.model || 'tts-1';
116
+ const format = args.format || 'mp3';
117
+ const response = await fetch(`${this.config.openaiBaseUrl}/audio/speech`, {
118
+ method: 'POST',
119
+ headers: {
120
+ Authorization: `Bearer ${this.config.openaiApiKey}`,
121
+ 'Content-Type': 'application/json',
122
+ },
123
+ body: JSON.stringify({
124
+ model,
125
+ voice,
126
+ input: text,
127
+ response_format: format,
128
+ speed: args.speed,
129
+ }),
130
+ });
131
+ if (!response.ok) {
132
+ const err = await response.text();
133
+ return { success: false, error: `OpenAI TTS error (${response.status}): ${err.slice(0, 300)}` };
134
+ }
135
+ const buf = await response.arrayBuffer();
136
+ const audioBase64 = Buffer.from(buf).toString('base64');
137
+ const contentType = format === 'opus' ? 'audio/opus' : format === 'wav' ? 'audio/wav' : 'audio/mpeg';
138
+ const durationEstimateMs = Math.round((text.split(/\s+/).length / 150) * 60 * 1000);
139
+ return {
140
+ success: true,
141
+ output: { text, voice, model, provider: 'openai', audioBase64, contentType, durationEstimateMs },
142
+ contentType,
143
+ };
144
+ }
145
+ // ── ElevenLabs TTS ──
146
+ async synthesizeElevenLabs(text, args) {
147
+ const voiceId = ELEVENLABS_VOICES[(args.voice || 'rachel').toLowerCase()] || args.voice || ELEVENLABS_VOICES.rachel;
44
148
  const model = args.model || 'eleven_monolingual_v1';
149
+ const response = await fetch(`https://api.elevenlabs.io/v1/text-to-speech/${voiceId}`, {
150
+ method: 'POST',
151
+ headers: {
152
+ 'xi-api-key': this.config.elevenLabsApiKey,
153
+ 'Content-Type': 'application/json',
154
+ Accept: 'audio/mpeg',
155
+ },
156
+ body: JSON.stringify({
157
+ text,
158
+ model_id: model,
159
+ voice_settings: {
160
+ stability: args.stability ?? 0.5,
161
+ similarity_boost: args.similarity_boost ?? 0.75,
162
+ },
163
+ }),
164
+ });
165
+ if (!response.ok) {
166
+ const err = await response.text();
167
+ return { success: false, error: `ElevenLabs error (${response.status}): ${err.slice(0, 300)}` };
168
+ }
169
+ const buf = await response.arrayBuffer();
170
+ const audioBase64 = Buffer.from(buf).toString('base64');
171
+ const durationEstimateMs = Math.round((text.split(/\s+/).length / 150) * 60 * 1000);
172
+ return {
173
+ success: true,
174
+ output: {
175
+ text,
176
+ voice: args.voice || 'rachel',
177
+ model,
178
+ provider: 'elevenlabs',
179
+ audioBase64,
180
+ contentType: 'audio/mpeg',
181
+ durationEstimateMs,
182
+ },
183
+ contentType: 'audio/mpeg',
184
+ };
185
+ }
186
+ // ── Ollama TTS (local, experimental) ──
187
+ async synthesizeOllama(text, args) {
188
+ // Ollama doesn't natively support TTS yet, but some models (e.g., bark, piper)
189
+ // can be served via OpenAI-compatible endpoints. Try the OpenAI-compat path.
190
+ const voice = args.voice || 'default';
191
+ const model = args.model || 'tts'; // User must have a TTS model loaded
45
192
  try {
46
- const response = await fetch(`https://api.elevenlabs.io/v1/text-to-speech/${voiceId}`, {
193
+ const response = await fetch(`${this.config.ollamaBaseUrl}/v1/audio/speech`, {
47
194
  method: 'POST',
48
- headers: { 'xi-api-key': this.apiKey, 'Content-Type': 'application/json', Accept: 'audio/mpeg' },
49
- body: JSON.stringify({
50
- text,
51
- model_id: model,
52
- voice_settings: { stability: args.stability ?? 0.5, similarity_boost: args.similarity_boost ?? 0.75 },
53
- }),
195
+ headers: { 'Content-Type': 'application/json' },
196
+ body: JSON.stringify({ model, voice, input: text }),
54
197
  });
55
198
  if (!response.ok) {
56
- const err = await response.text();
57
- return { success: false, error: `ElevenLabs error (${response.status}): ${err}` };
199
+ return {
200
+ success: false,
201
+ error: `Ollama TTS not available (${response.status}). Ollama doesn't natively support TTS yet. ` +
202
+ 'Set OPENAI_API_KEY or ELEVENLABS_API_KEY for cloud TTS, or use a dedicated local TTS server.',
203
+ };
58
204
  }
59
205
  const buf = await response.arrayBuffer();
60
206
  const audioBase64 = Buffer.from(buf).toString('base64');
61
207
  const durationEstimateMs = Math.round((text.split(/\s+/).length / 150) * 60 * 1000);
62
208
  return {
63
209
  success: true,
64
- output: { text, voice: args.voice || 'rachel', model, audioBase64, contentType: 'audio/mpeg', durationEstimateMs },
210
+ output: { text, voice, model, provider: 'ollama', audioBase64, contentType: 'audio/mpeg', durationEstimateMs },
65
211
  contentType: 'audio/mpeg',
66
212
  };
67
213
  }
68
- catch (err) {
69
- return { success: false, error: `TTS failed: ${err.message}` };
214
+ catch {
215
+ return {
216
+ success: false,
217
+ error: 'Ollama TTS endpoint not reachable. Ollama doesn\'t natively support TTS yet. ' +
218
+ 'Set OPENAI_API_KEY or ELEVENLABS_API_KEY for cloud TTS.',
219
+ };
70
220
  }
71
221
  }
72
222
  }
@@ -1 +1 @@
1
- {"version":3,"file":"textToSpeech.js","sourceRoot":"","sources":["../../src/tools/textToSpeech.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"textToSpeech.js","sourceRoot":"","sources":["../../src/tools/textToSpeech.ts"],"names":[],"mappings":"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"}
package/manifest.json CHANGED
@@ -2,19 +2,34 @@
2
2
  "$schema": "https://agentos.sh/schemas/extension-manifest-v1.json",
3
3
  "id": "com.framers.media.voice-synthesis",
4
4
  "name": "Voice Synthesis Extension",
5
- "version": "1.0.0",
6
- "description": "Text-to-speech synthesis via ElevenLabs for generating agent voice audio",
5
+ "version": "2.0.0",
6
+ "description": "Voice synthesis and transcription tools via OpenAI, ElevenLabs, Deepgram, and local Ollama/Whisper-compatible runtimes",
7
7
  "author": { "name": "Frame.dev" },
8
8
  "license": "MIT",
9
- "keywords": ["tts", "voice", "speech", "elevenlabs", "audio"],
9
+ "keywords": ["tts", "stt", "voice", "speech", "transcription", "openai", "elevenlabs", "deepgram", "ollama", "whisper", "audio"],
10
10
  "agentosVersion": "^2.0.0",
11
11
  "categories": ["media", "communication"],
12
12
  "extensions": [
13
- { "kind": "tool", "id": "textToSpeech", "displayName": "Text to Speech", "entry": "./src/tools/textToSpeech.ts" }
13
+ { "kind": "tool", "id": "text_to_speech", "displayName": "Text to Speech", "entry": "./dist/tools/textToSpeech.js" },
14
+ { "kind": "tool", "id": "speech_to_text", "displayName": "Speech to Text", "entry": "./dist/tools/speechToText.js" }
14
15
  ],
15
16
  "configuration": {
16
17
  "properties": {
17
- "elevenlabs.apiKey": { "type": "string", "secret": true }
18
+ "openai.apiKey": { "type": "string", "secret": true },
19
+ "openai.baseUrl": { "type": "string" },
20
+ "deepgram.apiKey": { "type": "string", "secret": true },
21
+ "deepgram.baseUrl": { "type": "string" },
22
+ "elevenlabs.apiKey": { "type": "string", "secret": true },
23
+ "ollama.baseUrl": { "type": "string" },
24
+ "whisperLocal.baseUrl": { "type": "string" },
25
+ "tts.defaultProvider": {
26
+ "type": "string",
27
+ "enum": ["auto", "openai", "elevenlabs", "ollama"]
28
+ },
29
+ "stt.defaultProvider": {
30
+ "type": "string",
31
+ "enum": ["auto", "openai", "deepgram", "whisper-local"]
32
+ }
18
33
  }
19
34
  }
20
35
  }
package/package.json CHANGED
@@ -1,32 +1,58 @@
1
1
  {
2
2
  "name": "@framers/agentos-ext-voice-synthesis",
3
- "version": "1.0.0",
4
- "description": "ElevenLabs text-to-speech synthesis tool for AgentOS",
3
+ "version": "2.0.1",
4
+ "description": "Voice synthesis and transcription tools for AgentOS via OpenAI, ElevenLabs, Deepgram, and local Ollama/Whisper-compatible runtimes",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "type": "module",
8
8
  "sideEffects": false,
9
9
  "exports": {
10
- ".": { "import": "./dist/index.js", "types": "./dist/index.d.ts" },
10
+ ".": {
11
+ "import": "./dist/index.js",
12
+ "types": "./dist/index.d.ts"
13
+ },
11
14
  "./manifest.json": "./manifest.json",
12
15
  "./package.json": "./package.json"
13
16
  },
14
- "scripts": {
15
- "build": "tsc",
16
- "test": "vitest run",
17
- "test:watch": "vitest",
18
- "test:coverage": "vitest run --coverage",
19
- "lint": "eslint src --ext .ts",
20
- "typecheck": "tsc --noEmit",
21
- "clean": "rimraf dist"
17
+ "keywords": [
18
+ "agentos",
19
+ "extension",
20
+ "tts",
21
+ "stt",
22
+ "voice",
23
+ "transcription",
24
+ "openai",
25
+ "elevenlabs",
26
+ "deepgram",
27
+ "ollama",
28
+ "whisper",
29
+ "speech",
30
+ "media"
31
+ ],
32
+ "author": {
33
+ "name": "Framers AI",
34
+ "email": "team@frame.dev",
35
+ "url": "https://frame.dev"
22
36
  },
23
- "keywords": ["agentos", "extension", "tts", "voice", "elevenlabs", "speech", "media"],
24
- "author": { "name": "Framers AI", "email": "team@frame.dev", "url": "https://frame.dev" },
25
- "contributors": [{ "name": "Johnny Dunn", "email": "johnnyfived@protonmail.com", "url": "https://github.com/jddunn" }],
37
+ "contributors": [
38
+ {
39
+ "name": "Johnny Dunn",
40
+ "email": "johnnyfived@protonmail.com",
41
+ "url": "https://github.com/jddunn"
42
+ }
43
+ ],
26
44
  "license": "MIT",
27
- "repository": { "type": "git", "url": "https://github.com/framersai/agentos-extensions.git", "directory": "registry/curated/media/voice-synthesis" },
28
- "publishConfig": { "access": "public" },
29
- "peerDependencies": { "@framers/agentos": "^0.1.0" },
45
+ "repository": {
46
+ "type": "git",
47
+ "url": "https://github.com/framersai/agentos-extensions.git",
48
+ "directory": "registry/curated/media/voice-synthesis"
49
+ },
50
+ "publishConfig": {
51
+ "access": "public"
52
+ },
53
+ "peerDependencies": {
54
+ "@framers/agentos": "^0.1.0"
55
+ },
30
56
  "devDependencies": {
31
57
  "@framers/agentos": "^0.1.0",
32
58
  "@types/node": "^20.12.12",
@@ -34,5 +60,14 @@
34
60
  "rimraf": "^5.0.7",
35
61
  "typescript": "^5.4.5",
36
62
  "vitest": "^1.6.0"
63
+ },
64
+ "scripts": {
65
+ "build": "tsc",
66
+ "test": "vitest run",
67
+ "test:watch": "vitest",
68
+ "test:coverage": "vitest run --coverage",
69
+ "lint": "eslint src --ext .ts",
70
+ "typecheck": "tsc --noEmit",
71
+ "clean": "rimraf dist"
37
72
  }
38
- }
73
+ }
package/src/index.ts CHANGED
@@ -1,30 +1,92 @@
1
1
  /**
2
- * Voice Synthesis Extension Pack — ElevenLabs TTS for agents.
2
+ * Voice Synthesis Extension Pack — TTS + STT voice tools for agents.
3
+ *
4
+ * Supports: OpenAI TTS/STT, ElevenLabs TTS, Ollama (local TTS).
5
+ * Auto-detects available provider from API keys.
3
6
  */
4
7
 
5
- import { TextToSpeechTool } from './tools/textToSpeech.js';
8
+ import { TextToSpeechTool, type TTSConfig, type TTSProvider } from './tools/textToSpeech.js';
9
+ import { SpeechToTextTool, type STTConfig, type STTProvider } from './tools/speechToText.js';
6
10
 
7
11
  export interface VoiceSynthesisExtensionOptions {
8
12
  elevenLabsApiKey?: string;
13
+ openaiApiKey?: string;
14
+ openaiBaseUrl?: string;
15
+ deepgramApiKey?: string;
16
+ deepgramBaseUrl?: string;
17
+ ollamaBaseUrl?: string;
18
+ whisperLocalBaseUrl?: string;
19
+ defaultProvider?: TTSProvider;
20
+ defaultSttProvider?: STTProvider;
9
21
  priority?: number;
10
22
  }
11
23
 
12
24
  export function createExtensionPack(context: any) {
13
25
  const options = (context.options || {}) as VoiceSynthesisExtensionOptions;
14
- const apiKey = options.elevenLabsApiKey || context.getSecret?.('elevenlabs.apiKey') || process.env.ELEVENLABS_API_KEY;
15
- const tool = new TextToSpeechTool(apiKey);
26
+
27
+ const config: TTSConfig = {
28
+ openaiApiKey: options.openaiApiKey || context.getSecret?.('openai.apiKey') || process.env.OPENAI_API_KEY,
29
+ openaiBaseUrl: options.openaiBaseUrl || process.env.OPENAI_BASE_URL,
30
+ elevenLabsApiKey: options.elevenLabsApiKey || context.getSecret?.('elevenlabs.apiKey') || process.env.ELEVENLABS_API_KEY,
31
+ ollamaBaseUrl: options.ollamaBaseUrl || process.env.OLLAMA_BASE_URL,
32
+ defaultProvider: options.defaultProvider || (process.env.TTS_PROVIDER as TTSProvider) || 'auto',
33
+ };
34
+ const sttConfig: STTConfig = {
35
+ openaiApiKey: options.openaiApiKey || context.getSecret?.('openai.apiKey') || process.env.OPENAI_API_KEY,
36
+ openaiBaseUrl: options.openaiBaseUrl || process.env.OPENAI_BASE_URL,
37
+ deepgramApiKey: options.deepgramApiKey || context.getSecret?.('deepgram.apiKey') || process.env.DEEPGRAM_API_KEY,
38
+ deepgramBaseUrl: options.deepgramBaseUrl || process.env.DEEPGRAM_BASE_URL,
39
+ whisperLocalBaseUrl: options.whisperLocalBaseUrl || process.env.WHISPER_LOCAL_BASE_URL,
40
+ defaultProvider: options.defaultSttProvider || (process.env.STT_PROVIDER as STTProvider) || 'auto',
41
+ };
42
+
43
+ const ttsTool = new TextToSpeechTool(config);
44
+ const sttTool = new SpeechToTextTool(sttConfig);
45
+
46
+ const providers: string[] = [];
47
+ if (config.openaiApiKey) providers.push('OpenAI');
48
+ if (config.elevenLabsApiKey) providers.push('ElevenLabs');
49
+ providers.push('Ollama (local fallback)');
50
+ const sttProviders: string[] = [];
51
+ if (sttConfig.openaiApiKey) sttProviders.push('OpenAI Whisper');
52
+ if (sttConfig.deepgramApiKey) sttProviders.push('Deepgram');
53
+ if (sttConfig.whisperLocalBaseUrl) sttProviders.push('Whisper-local');
54
+
55
+ const features: string[] = [
56
+ `TTS: ${providers.join(', ')}`,
57
+ `STT: ${sttProviders.length > 0 ? sttProviders.join(', ') : 'not configured'}`,
58
+ ];
16
59
 
17
60
  return {
18
61
  name: '@framers/agentos-ext-voice-synthesis',
19
- version: '1.0.0',
62
+ version: '2.0.0',
20
63
  descriptors: [
21
- { id: 'textToSpeech', kind: 'tool' as const, priority: options.priority || 50, payload: tool, requiredSecrets: [{ id: 'elevenlabs.apiKey' }] },
64
+ {
65
+ id: ttsTool.name,
66
+ kind: 'tool' as const,
67
+ priority: options.priority || 50,
68
+ payload: ttsTool,
69
+ requiredSecrets: [],
70
+ },
71
+ {
72
+ id: sttTool.name,
73
+ kind: 'tool' as const,
74
+ priority: options.priority || 50,
75
+ payload: sttTool,
76
+ requiredSecrets: [],
77
+ },
22
78
  ],
23
- onActivate: async () => context.logger?.info('Voice Synthesis Extension activated'),
24
- onDeactivate: async () => context.logger?.info('Voice Synthesis Extension deactivated'),
79
+ onActivate: async () => {
80
+ context.logger?.info?.(`Voice Synthesis activated — ${features.join(' | ')}`);
81
+ },
82
+ onDeactivate: async () => {
83
+ context.logger?.info?.('Voice Synthesis deactivated');
84
+ },
25
85
  };
26
86
  }
27
87
 
28
88
  export { TextToSpeechTool };
29
- export type { TTSInput, TTSOutput } from './tools/textToSpeech.js';
89
+ export { SpeechToTextTool };
90
+ export type { TTSInput, TTSOutput, TTSConfig, TTSProvider } from './tools/textToSpeech.js';
91
+ export type { STTInput, STTOutput, STTConfig, STTProvider } from './tools/speechToText.js';
30
92
  export default createExtensionPack;