@openvole/paw-tts 0.1.0

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.
package/README.md ADDED
@@ -0,0 +1,61 @@
1
+ # @openvole/paw-tts
2
+
3
+ [![npm version](https://img.shields.io/npm/v/@openvole/paw-tts.svg)](https://www.npmjs.com/package/@openvole/paw-tts)
4
+
5
+ Text-to-speech tool Paw for OpenVole with multi-provider support (ElevenLabs and OpenAI TTS).
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install @openvole/paw-tts
11
+ ```
12
+
13
+ ## Configuration
14
+
15
+ ### ElevenLabs (default)
16
+
17
+ ```bash
18
+ export VOLE_TTS_PROVIDER=elevenlabs
19
+ export ELEVENLABS_API_KEY=your-api-key
20
+ export ELEVENLABS_VOICE_ID=21m00Tcm4TlvDq8ikWAM # optional, defaults to Rachel
21
+ ```
22
+
23
+ ### OpenAI
24
+
25
+ ```bash
26
+ export VOLE_TTS_PROVIDER=openai
27
+ export OPENAI_API_KEY=your-api-key
28
+ export OPENAI_TTS_MODEL=tts-1 # optional, defaults to tts-1
29
+ export OPENAI_TTS_VOICE=alloy # optional, defaults to alloy
30
+ ```
31
+
32
+ ## Environment Variables
33
+
34
+ | Variable | Required | Default | Description |
35
+ |---|---|---|---|
36
+ | `VOLE_TTS_PROVIDER` | No | `elevenlabs` | TTS provider to use (`elevenlabs` or `openai`) |
37
+ | `ELEVENLABS_API_KEY` | Yes (ElevenLabs) | — | ElevenLabs API key |
38
+ | `ELEVENLABS_VOICE_ID` | No | `21m00Tcm4TlvDq8ikWAM` | Default ElevenLabs voice ID |
39
+ | `OPENAI_API_KEY` | Yes (OpenAI) | — | OpenAI API key |
40
+ | `OPENAI_TTS_MODEL` | No | `tts-1` | OpenAI TTS model (`tts-1` or `tts-1-hd`) |
41
+ | `OPENAI_TTS_VOICE` | No | `alloy` | Default OpenAI voice |
42
+
43
+ ## Tools
44
+
45
+ ### `tts_speak`
46
+
47
+ Convert text to speech and save as an audio file.
48
+
49
+ - **text** (string, required) — The text to convert to speech
50
+ - **voice** (string, optional) — Voice ID (provider-specific)
51
+ - **output_format** (enum: `mp3` | `wav` | `pcm`, default: `mp3`) — Audio format
52
+
53
+ Audio files are saved to `.openvole/workspace/audio/`.
54
+
55
+ ### `tts_list_voices`
56
+
57
+ List available voices for the active TTS provider.
58
+
59
+ ## License
60
+
61
+ MIT
@@ -0,0 +1,5 @@
1
+ import * as _openvole_paw_sdk from '@openvole/paw-sdk';
2
+
3
+ declare const _default: _openvole_paw_sdk.PawDefinition;
4
+
5
+ export { _default as default };
package/dist/index.js ADDED
@@ -0,0 +1,202 @@
1
+ // src/index.ts
2
+ import { definePaw } from "@openvole/paw-sdk";
3
+
4
+ // src/paw.ts
5
+ import { z } from "@openvole/paw-sdk";
6
+ import * as fs from "fs/promises";
7
+ import * as path from "path";
8
+
9
+ // src/providers/elevenlabs.ts
10
+ var FORMAT_MAP = {
11
+ mp3: "mp3_44100_128",
12
+ wav: "pcm_44100",
13
+ pcm: "pcm_44100"
14
+ };
15
+ var ElevenLabsProvider = class {
16
+ apiKey;
17
+ defaultVoiceId;
18
+ constructor(apiKey, defaultVoiceId) {
19
+ this.apiKey = apiKey;
20
+ this.defaultVoiceId = defaultVoiceId;
21
+ }
22
+ async synthesize(text, voice, format) {
23
+ const voiceId = voice ?? this.defaultVoiceId;
24
+ const outputFormat = FORMAT_MAP[format] ?? "mp3_44100_128";
25
+ const response = await fetch(
26
+ `https://api.elevenlabs.io/v1/text-to-speech/${voiceId}`,
27
+ {
28
+ method: "POST",
29
+ headers: {
30
+ "xi-api-key": this.apiKey,
31
+ "Content-Type": "application/json"
32
+ },
33
+ body: JSON.stringify({
34
+ text,
35
+ model_id: "eleven_multilingual_v2",
36
+ output_format: outputFormat
37
+ })
38
+ }
39
+ );
40
+ if (!response.ok) {
41
+ const body = await response.text();
42
+ throw new Error(
43
+ `ElevenLabs API error (${response.status}): ${body}`
44
+ );
45
+ }
46
+ return Buffer.from(await response.arrayBuffer());
47
+ }
48
+ async listVoices() {
49
+ const response = await fetch("https://api.elevenlabs.io/v1/voices", {
50
+ headers: { "xi-api-key": this.apiKey }
51
+ });
52
+ if (!response.ok) {
53
+ const body = await response.text();
54
+ throw new Error(
55
+ `ElevenLabs API error (${response.status}): ${body}`
56
+ );
57
+ }
58
+ const data = await response.json();
59
+ return data.voices.map((v) => ({ id: v.voice_id, name: v.name }));
60
+ }
61
+ };
62
+
63
+ // src/providers/openai.ts
64
+ var OpenAIProvider = class {
65
+ apiKey;
66
+ model;
67
+ defaultVoice;
68
+ constructor(apiKey, model = "tts-1", defaultVoice = "alloy") {
69
+ this.apiKey = apiKey;
70
+ this.model = model;
71
+ this.defaultVoice = defaultVoice;
72
+ }
73
+ async synthesize(text, voice, format) {
74
+ const response = await fetch(
75
+ "https://api.openai.com/v1/audio/speech",
76
+ {
77
+ method: "POST",
78
+ headers: {
79
+ Authorization: `Bearer ${this.apiKey}`,
80
+ "Content-Type": "application/json"
81
+ },
82
+ body: JSON.stringify({
83
+ model: this.model,
84
+ voice: voice ?? this.defaultVoice,
85
+ input: text,
86
+ response_format: format
87
+ })
88
+ }
89
+ );
90
+ if (!response.ok) {
91
+ const body = await response.text();
92
+ throw new Error(`OpenAI TTS API error (${response.status}): ${body}`);
93
+ }
94
+ return Buffer.from(await response.arrayBuffer());
95
+ }
96
+ listVoices() {
97
+ return [
98
+ { id: "alloy", name: "Alloy" },
99
+ { id: "echo", name: "Echo" },
100
+ { id: "fable", name: "Fable" },
101
+ { id: "onyx", name: "Onyx" },
102
+ { id: "nova", name: "Nova" },
103
+ { id: "shimmer", name: "Shimmer" }
104
+ ];
105
+ }
106
+ };
107
+
108
+ // src/paw.ts
109
+ var provider;
110
+ var providerName = "elevenlabs";
111
+ function getProvider() {
112
+ if (!provider) {
113
+ throw new Error("TTS provider not initialized \u2014 onLoad has not been called");
114
+ }
115
+ return provider;
116
+ }
117
+ var paw = {
118
+ name: "@openvole/paw-tts",
119
+ version: "0.1.0",
120
+ description: "Text-to-speech tool supporting ElevenLabs and OpenAI TTS",
121
+ brain: false,
122
+ tools: [
123
+ {
124
+ name: "tts_speak",
125
+ description: "Convert text to speech and save as audio file",
126
+ parameters: z.object({
127
+ text: z.string().describe("The text to convert to speech"),
128
+ voice: z.string().optional().describe("Voice ID to use (provider-specific). Uses default if omitted."),
129
+ output_format: z.enum(["mp3", "wav", "pcm"]).default("mp3").describe("Audio output format")
130
+ }),
131
+ async execute(params) {
132
+ const { text, voice, output_format } = params;
133
+ const p = getProvider();
134
+ const audio = await p.synthesize(text, voice, output_format);
135
+ const ext = output_format === "pcm" ? "pcm" : output_format;
136
+ const filename = `tts_${Date.now()}.${ext}`;
137
+ const audioDir = path.join(process.cwd(), ".openvole", "workspace", "audio");
138
+ await fs.mkdir(audioDir, { recursive: true });
139
+ const filePath = path.join(audioDir, filename);
140
+ await fs.writeFile(filePath, audio);
141
+ return {
142
+ ok: true,
143
+ file_path: filePath,
144
+ format: output_format,
145
+ size_bytes: audio.length
146
+ };
147
+ }
148
+ },
149
+ {
150
+ name: "tts_list_voices",
151
+ description: "List available voices for the active TTS provider",
152
+ parameters: z.object({}),
153
+ async execute() {
154
+ const p = getProvider();
155
+ const voices = await p.listVoices();
156
+ return {
157
+ provider: providerName,
158
+ voices
159
+ };
160
+ }
161
+ }
162
+ ],
163
+ async onLoad() {
164
+ providerName = (process.env.VOLE_TTS_PROVIDER ?? "elevenlabs").toLowerCase();
165
+ if (providerName === "elevenlabs") {
166
+ const apiKey = process.env.ELEVENLABS_API_KEY;
167
+ if (!apiKey) {
168
+ throw new Error(
169
+ "[paw-tts] ELEVENLABS_API_KEY is required when using the ElevenLabs provider"
170
+ );
171
+ }
172
+ const voiceId = process.env.ELEVENLABS_VOICE_ID ?? "21m00Tcm4TlvDq8ikWAM";
173
+ provider = new ElevenLabsProvider(apiKey, voiceId);
174
+ } else if (providerName === "openai") {
175
+ const apiKey = process.env.OPENAI_API_KEY;
176
+ if (!apiKey) {
177
+ throw new Error(
178
+ "[paw-tts] OPENAI_API_KEY is required when using the OpenAI provider"
179
+ );
180
+ }
181
+ const model = process.env.OPENAI_TTS_MODEL ?? "tts-1";
182
+ const voice = process.env.OPENAI_TTS_VOICE ?? "alloy";
183
+ provider = new OpenAIProvider(apiKey, model, voice);
184
+ } else {
185
+ throw new Error(
186
+ `[paw-tts] Unknown TTS provider: ${providerName}. Supported: elevenlabs, openai`
187
+ );
188
+ }
189
+ console.log(`[paw-tts] loaded \u2014 provider: ${providerName}`);
190
+ },
191
+ async onUnload() {
192
+ provider = void 0;
193
+ console.log("[paw-tts] unloaded");
194
+ }
195
+ };
196
+
197
+ // src/index.ts
198
+ var index_default = definePaw(paw);
199
+ export {
200
+ index_default as default
201
+ };
202
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/paw.ts","../src/providers/elevenlabs.ts","../src/providers/openai.ts"],"sourcesContent":["import { definePaw } from '@openvole/paw-sdk'\nimport { paw } from './paw.js'\n\nexport default definePaw(paw)\n","import { z, type PawDefinition } from '@openvole/paw-sdk'\nimport * as fs from 'node:fs/promises'\nimport * as path from 'node:path'\nimport type { TTSProvider } from './providers/types.js'\nimport { ElevenLabsProvider } from './providers/elevenlabs.js'\nimport { OpenAIProvider } from './providers/openai.js'\n\nlet provider: (TTSProvider & { listVoices: () => Promise<{ id: string; name: string }[]> | { id: string; name: string }[] }) | undefined\nlet providerName: string = 'elevenlabs'\n\nfunction getProvider() {\n\tif (!provider) {\n\t\tthrow new Error('TTS provider not initialized — onLoad has not been called')\n\t}\n\treturn provider\n}\n\nexport const paw: PawDefinition = {\n\tname: '@openvole/paw-tts',\n\tversion: '0.1.0',\n\tdescription: 'Text-to-speech tool supporting ElevenLabs and OpenAI TTS',\n\tbrain: false,\n\n\ttools: [\n\t\t{\n\t\t\tname: 'tts_speak',\n\t\t\tdescription: 'Convert text to speech and save as audio file',\n\t\t\tparameters: z.object({\n\t\t\t\ttext: z.string().describe('The text to convert to speech'),\n\t\t\t\tvoice: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe('Voice ID to use (provider-specific). Uses default if omitted.'),\n\t\t\t\toutput_format: z\n\t\t\t\t\t.enum(['mp3', 'wav', 'pcm'])\n\t\t\t\t\t.default('mp3')\n\t\t\t\t\t.describe('Audio output format'),\n\t\t\t}),\n\t\t\tasync execute(params: unknown) {\n\t\t\t\tconst { text, voice, output_format } = params as {\n\t\t\t\t\ttext: string\n\t\t\t\t\tvoice?: string\n\t\t\t\t\toutput_format: 'mp3' | 'wav' | 'pcm'\n\t\t\t\t}\n\n\t\t\t\tconst p = getProvider()\n\t\t\t\tconst audio = await p.synthesize(text, voice, output_format)\n\n\t\t\t\tconst ext = output_format === 'pcm' ? 'pcm' : output_format\n\t\t\t\tconst filename = `tts_${Date.now()}.${ext}`\n\t\t\t\tconst audioDir = path.join(process.cwd(), '.openvole', 'workspace', 'audio')\n\t\t\t\tawait fs.mkdir(audioDir, { recursive: true })\n\n\t\t\t\tconst filePath = path.join(audioDir, filename)\n\t\t\t\tawait fs.writeFile(filePath, audio)\n\n\t\t\t\treturn {\n\t\t\t\t\tok: true,\n\t\t\t\t\tfile_path: filePath,\n\t\t\t\t\tformat: output_format,\n\t\t\t\t\tsize_bytes: audio.length,\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: 'tts_list_voices',\n\t\t\tdescription: 'List available voices for the active TTS provider',\n\t\t\tparameters: z.object({}),\n\t\t\tasync execute() {\n\t\t\t\tconst p = getProvider()\n\t\t\t\tconst voices = await p.listVoices()\n\t\t\t\treturn {\n\t\t\t\t\tprovider: providerName,\n\t\t\t\t\tvoices,\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t],\n\n\tasync onLoad() {\n\t\tproviderName = (process.env.VOLE_TTS_PROVIDER ?? 'elevenlabs').toLowerCase()\n\n\t\tif (providerName === 'elevenlabs') {\n\t\t\tconst apiKey = process.env.ELEVENLABS_API_KEY\n\t\t\tif (!apiKey) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t'[paw-tts] ELEVENLABS_API_KEY is required when using the ElevenLabs provider',\n\t\t\t\t)\n\t\t\t}\n\t\t\tconst voiceId = process.env.ELEVENLABS_VOICE_ID ?? '21m00Tcm4TlvDq8ikWAM'\n\t\t\tprovider = new ElevenLabsProvider(apiKey, voiceId)\n\t\t} else if (providerName === 'openai') {\n\t\t\tconst apiKey = process.env.OPENAI_API_KEY\n\t\t\tif (!apiKey) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t'[paw-tts] OPENAI_API_KEY is required when using the OpenAI provider',\n\t\t\t\t)\n\t\t\t}\n\t\t\tconst model = process.env.OPENAI_TTS_MODEL ?? 'tts-1'\n\t\t\tconst voice = process.env.OPENAI_TTS_VOICE ?? 'alloy'\n\t\t\tprovider = new OpenAIProvider(apiKey, model, voice)\n\t\t} else {\n\t\t\tthrow new Error(\n\t\t\t\t`[paw-tts] Unknown TTS provider: ${providerName}. Supported: elevenlabs, openai`,\n\t\t\t)\n\t\t}\n\n\t\tconsole.log(`[paw-tts] loaded — provider: ${providerName}`)\n\t},\n\n\tasync onUnload() {\n\t\tprovider = undefined\n\t\tconsole.log('[paw-tts] unloaded')\n\t},\n}\n","import type { TTSProvider } from './types.js'\n\nconst FORMAT_MAP: Record<string, string> = {\n\tmp3: 'mp3_44100_128',\n\twav: 'pcm_44100',\n\tpcm: 'pcm_44100',\n}\n\nexport class ElevenLabsProvider implements TTSProvider {\n\tprivate apiKey: string\n\tprivate defaultVoiceId: string\n\n\tconstructor(apiKey: string, defaultVoiceId: string) {\n\t\tthis.apiKey = apiKey\n\t\tthis.defaultVoiceId = defaultVoiceId\n\t}\n\n\tasync synthesize(\n\t\ttext: string,\n\t\tvoice: string | undefined,\n\t\tformat: 'mp3' | 'wav' | 'pcm',\n\t): Promise<Buffer> {\n\t\tconst voiceId = voice ?? this.defaultVoiceId\n\t\tconst outputFormat = FORMAT_MAP[format] ?? 'mp3_44100_128'\n\n\t\tconst response = await fetch(\n\t\t\t`https://api.elevenlabs.io/v1/text-to-speech/${voiceId}`,\n\t\t\t{\n\t\t\t\tmethod: 'POST',\n\t\t\t\theaders: {\n\t\t\t\t\t'xi-api-key': this.apiKey,\n\t\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\t},\n\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\ttext,\n\t\t\t\t\tmodel_id: 'eleven_multilingual_v2',\n\t\t\t\t\toutput_format: outputFormat,\n\t\t\t\t}),\n\t\t\t},\n\t\t)\n\n\t\tif (!response.ok) {\n\t\t\tconst body = await response.text()\n\t\t\tthrow new Error(\n\t\t\t\t`ElevenLabs API error (${response.status}): ${body}`,\n\t\t\t)\n\t\t}\n\n\t\treturn Buffer.from(await response.arrayBuffer())\n\t}\n\n\tasync listVoices(): Promise<{ id: string; name: string }[]> {\n\t\tconst response = await fetch('https://api.elevenlabs.io/v1/voices', {\n\t\t\theaders: { 'xi-api-key': this.apiKey },\n\t\t})\n\n\t\tif (!response.ok) {\n\t\t\tconst body = await response.text()\n\t\t\tthrow new Error(\n\t\t\t\t`ElevenLabs API error (${response.status}): ${body}`,\n\t\t\t)\n\t\t}\n\n\t\tconst data = (await response.json()) as {\n\t\t\tvoices: { voice_id: string; name: string }[]\n\t\t}\n\t\treturn data.voices.map((v) => ({ id: v.voice_id, name: v.name }))\n\t}\n}\n","import type { TTSProvider } from './types.js'\n\nexport class OpenAIProvider implements TTSProvider {\n\tprivate apiKey: string\n\tprivate model: string\n\tprivate defaultVoice: string\n\n\tconstructor(\n\t\tapiKey: string,\n\t\tmodel: string = 'tts-1',\n\t\tdefaultVoice: string = 'alloy',\n\t) {\n\t\tthis.apiKey = apiKey\n\t\tthis.model = model\n\t\tthis.defaultVoice = defaultVoice\n\t}\n\n\tasync synthesize(\n\t\ttext: string,\n\t\tvoice: string | undefined,\n\t\tformat: 'mp3' | 'wav' | 'pcm',\n\t): Promise<Buffer> {\n\t\tconst response = await fetch(\n\t\t\t'https://api.openai.com/v1/audio/speech',\n\t\t\t{\n\t\t\t\tmethod: 'POST',\n\t\t\t\theaders: {\n\t\t\t\t\tAuthorization: `Bearer ${this.apiKey}`,\n\t\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\t},\n\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\tmodel: this.model,\n\t\t\t\t\tvoice: voice ?? this.defaultVoice,\n\t\t\t\t\tinput: text,\n\t\t\t\t\tresponse_format: format,\n\t\t\t\t}),\n\t\t\t},\n\t\t)\n\n\t\tif (!response.ok) {\n\t\t\tconst body = await response.text()\n\t\t\tthrow new Error(`OpenAI TTS API error (${response.status}): ${body}`)\n\t\t}\n\n\t\treturn Buffer.from(await response.arrayBuffer())\n\t}\n\n\tlistVoices(): { id: string; name: string }[] {\n\t\treturn [\n\t\t\t{ id: 'alloy', name: 'Alloy' },\n\t\t\t{ id: 'echo', name: 'Echo' },\n\t\t\t{ id: 'fable', name: 'Fable' },\n\t\t\t{ id: 'onyx', name: 'Onyx' },\n\t\t\t{ id: 'nova', name: 'Nova' },\n\t\t\t{ id: 'shimmer', name: 'Shimmer' },\n\t\t]\n\t}\n}\n"],"mappings":"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","names":[]}
package/package.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "@openvole/paw-tts",
3
+ "version": "0.1.0",
4
+ "description": "Text-to-speech tool Paw for OpenVole — ElevenLabs and OpenAI TTS providers",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "scripts": {
8
+ "build": "tsup",
9
+ "typecheck": "tsc --noEmit"
10
+ },
11
+ "devDependencies": {
12
+ "@types/node": "^22.0.0",
13
+ "tsup": "^8.3.0",
14
+ "typescript": "^5.6.0",
15
+ "@openvole/paw-sdk": "^0.3.0"
16
+ },
17
+ "engines": {
18
+ "node": ">=20.0.0"
19
+ },
20
+ "files": [
21
+ "dist",
22
+ "vole-paw.json",
23
+ "README.md"
24
+ ],
25
+ "license": "MIT",
26
+ "peerDependencies": {
27
+ "@openvole/paw-sdk": "^0.3.0"
28
+ }
29
+ }
package/vole-paw.json ADDED
@@ -0,0 +1,19 @@
1
+ {
2
+ "name": "@openvole/paw-tts",
3
+ "version": "0.1.0",
4
+ "description": "Text-to-speech tool Paw supporting ElevenLabs and OpenAI TTS",
5
+ "entry": "./dist/index.js",
6
+ "brain": false,
7
+ "inProcess": false,
8
+ "transport": "ipc",
9
+ "tools": [
10
+ { "name": "tts_speak", "description": "Convert text to speech and save as audio file" },
11
+ { "name": "tts_list_voices", "description": "List available voices for the active TTS provider" }
12
+ ],
13
+ "permissions": {
14
+ "network": ["api.elevenlabs.io", "api.openai.com"],
15
+ "listen": [],
16
+ "filesystem": [],
17
+ "env": ["VOLE_TTS_PROVIDER", "ELEVENLABS_API_KEY", "ELEVENLABS_VOICE_ID", "OPENAI_API_KEY", "OPENAI_TTS_MODEL", "OPENAI_TTS_VOICE"]
18
+ }
19
+ }