@mcptoolshop/voice-soundboard-core 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.
Files changed (158) hide show
  1. package/LICENSE +21 -0
  2. package/dist/ambient/emitter.d.ts +34 -0
  3. package/dist/ambient/emitter.d.ts.map +1 -0
  4. package/dist/ambient/emitter.js +125 -0
  5. package/dist/ambient/emitter.js.map +1 -0
  6. package/dist/ambient/index.d.ts +5 -0
  7. package/dist/ambient/index.d.ts.map +1 -0
  8. package/dist/ambient/index.js +5 -0
  9. package/dist/ambient/index.js.map +1 -0
  10. package/dist/ambient/redact.d.ts +11 -0
  11. package/dist/ambient/redact.d.ts.map +1 -0
  12. package/dist/ambient/redact.js +40 -0
  13. package/dist/ambient/redact.js.map +1 -0
  14. package/dist/ambient/types.d.ts +38 -0
  15. package/dist/ambient/types.d.ts.map +1 -0
  16. package/dist/ambient/types.js +8 -0
  17. package/dist/ambient/types.js.map +1 -0
  18. package/dist/artifact.d.ts +37 -0
  19. package/dist/artifact.d.ts.map +1 -0
  20. package/dist/artifact.js +61 -0
  21. package/dist/artifact.js.map +1 -0
  22. package/dist/chunking/chunker.d.ts +15 -0
  23. package/dist/chunking/chunker.d.ts.map +1 -0
  24. package/dist/chunking/chunker.js +156 -0
  25. package/dist/chunking/chunker.js.map +1 -0
  26. package/dist/chunking/index.d.ts +5 -0
  27. package/dist/chunking/index.d.ts.map +1 -0
  28. package/dist/chunking/index.js +4 -0
  29. package/dist/chunking/index.js.map +1 -0
  30. package/dist/chunking/limits.d.ts +12 -0
  31. package/dist/chunking/limits.d.ts.map +1 -0
  32. package/dist/chunking/limits.js +12 -0
  33. package/dist/chunking/limits.js.map +1 -0
  34. package/dist/chunking/types.d.ts +26 -0
  35. package/dist/chunking/types.d.ts.map +1 -0
  36. package/dist/chunking/types.js +3 -0
  37. package/dist/chunking/types.js.map +1 -0
  38. package/dist/dialogue/index.d.ts +4 -0
  39. package/dist/dialogue/index.d.ts.map +1 -0
  40. package/dist/dialogue/index.js +3 -0
  41. package/dist/dialogue/index.js.map +1 -0
  42. package/dist/dialogue/parser.d.ts +33 -0
  43. package/dist/dialogue/parser.d.ts.map +1 -0
  44. package/dist/dialogue/parser.js +182 -0
  45. package/dist/dialogue/parser.js.map +1 -0
  46. package/dist/dialogue/types.d.ts +29 -0
  47. package/dist/dialogue/types.d.ts.map +1 -0
  48. package/dist/dialogue/types.js +3 -0
  49. package/dist/dialogue/types.js.map +1 -0
  50. package/dist/emotion/index.d.ts +5 -0
  51. package/dist/emotion/index.d.ts.map +1 -0
  52. package/dist/emotion/index.js +5 -0
  53. package/dist/emotion/index.js.map +1 -0
  54. package/dist/emotion/map.d.ts +17 -0
  55. package/dist/emotion/map.d.ts.map +1 -0
  56. package/dist/emotion/map.js +27 -0
  57. package/dist/emotion/map.js.map +1 -0
  58. package/dist/emotion/parser.d.ts +14 -0
  59. package/dist/emotion/parser.d.ts.map +1 -0
  60. package/dist/emotion/parser.js +96 -0
  61. package/dist/emotion/parser.js.map +1 -0
  62. package/dist/emotion/types.d.ts +26 -0
  63. package/dist/emotion/types.d.ts.map +1 -0
  64. package/dist/emotion/types.js +12 -0
  65. package/dist/emotion/types.js.map +1 -0
  66. package/dist/index.d.ts +16 -0
  67. package/dist/index.d.ts.map +1 -0
  68. package/dist/index.js +17 -0
  69. package/dist/index.js.map +1 -0
  70. package/dist/limits.d.ts +44 -0
  71. package/dist/limits.d.ts.map +1 -0
  72. package/dist/limits.js +65 -0
  73. package/dist/limits.js.map +1 -0
  74. package/dist/orchestrator/concat.d.ts +20 -0
  75. package/dist/orchestrator/concat.d.ts.map +1 -0
  76. package/dist/orchestrator/concat.js +139 -0
  77. package/dist/orchestrator/concat.js.map +1 -0
  78. package/dist/orchestrator/emotionRunner.d.ts +38 -0
  79. package/dist/orchestrator/emotionRunner.d.ts.map +1 -0
  80. package/dist/orchestrator/emotionRunner.js +115 -0
  81. package/dist/orchestrator/emotionRunner.js.map +1 -0
  82. package/dist/orchestrator/index.d.ts +6 -0
  83. package/dist/orchestrator/index.d.ts.map +1 -0
  84. package/dist/orchestrator/index.js +5 -0
  85. package/dist/orchestrator/index.js.map +1 -0
  86. package/dist/orchestrator/runner.d.ts +31 -0
  87. package/dist/orchestrator/runner.d.ts.map +1 -0
  88. package/dist/orchestrator/runner.js +106 -0
  89. package/dist/orchestrator/runner.js.map +1 -0
  90. package/dist/orchestrator/types.d.ts +47 -0
  91. package/dist/orchestrator/types.d.ts.map +1 -0
  92. package/dist/orchestrator/types.js +3 -0
  93. package/dist/orchestrator/types.js.map +1 -0
  94. package/dist/presets.d.ts +20 -0
  95. package/dist/presets.d.ts.map +1 -0
  96. package/dist/presets.js +22 -0
  97. package/dist/presets.js.map +1 -0
  98. package/dist/request.d.ts +26 -0
  99. package/dist/request.d.ts.map +1 -0
  100. package/dist/request.js +33 -0
  101. package/dist/request.js.map +1 -0
  102. package/dist/sandbox.d.ts +15 -0
  103. package/dist/sandbox.d.ts.map +1 -0
  104. package/dist/sandbox.js +27 -0
  105. package/dist/sandbox.js.map +1 -0
  106. package/dist/schemas.d.ts +49 -0
  107. package/dist/schemas.d.ts.map +1 -0
  108. package/dist/schemas.js +3 -0
  109. package/dist/schemas.js.map +1 -0
  110. package/dist/sfx/generator.d.ts +15 -0
  111. package/dist/sfx/generator.d.ts.map +1 -0
  112. package/dist/sfx/generator.js +114 -0
  113. package/dist/sfx/generator.js.map +1 -0
  114. package/dist/sfx/index.d.ts +7 -0
  115. package/dist/sfx/index.d.ts.map +1 -0
  116. package/dist/sfx/index.js +7 -0
  117. package/dist/sfx/index.js.map +1 -0
  118. package/dist/sfx/parser.d.ts +16 -0
  119. package/dist/sfx/parser.d.ts.map +1 -0
  120. package/dist/sfx/parser.js +100 -0
  121. package/dist/sfx/parser.js.map +1 -0
  122. package/dist/sfx/registry.d.ts +17 -0
  123. package/dist/sfx/registry.d.ts.map +1 -0
  124. package/dist/sfx/registry.js +13 -0
  125. package/dist/sfx/registry.js.map +1 -0
  126. package/dist/sfx/stitcher.d.ts +29 -0
  127. package/dist/sfx/stitcher.d.ts.map +1 -0
  128. package/dist/sfx/stitcher.js +44 -0
  129. package/dist/sfx/stitcher.js.map +1 -0
  130. package/dist/sfx/types.d.ts +22 -0
  131. package/dist/sfx/types.d.ts.map +1 -0
  132. package/dist/sfx/types.js +10 -0
  133. package/dist/sfx/types.js.map +1 -0
  134. package/dist/ssml/index.d.ts +5 -0
  135. package/dist/ssml/index.d.ts.map +1 -0
  136. package/dist/ssml/index.js +4 -0
  137. package/dist/ssml/index.js.map +1 -0
  138. package/dist/ssml/limits.d.ts +14 -0
  139. package/dist/ssml/limits.d.ts.map +1 -0
  140. package/dist/ssml/limits.js +14 -0
  141. package/dist/ssml/limits.js.map +1 -0
  142. package/dist/ssml/parser.d.ts +28 -0
  143. package/dist/ssml/parser.d.ts.map +1 -0
  144. package/dist/ssml/parser.js +348 -0
  145. package/dist/ssml/parser.js.map +1 -0
  146. package/dist/ssml/types.d.ts +46 -0
  147. package/dist/ssml/types.d.ts.map +1 -0
  148. package/dist/ssml/types.js +3 -0
  149. package/dist/ssml/types.js.map +1 -0
  150. package/dist/validate.d.ts +29 -0
  151. package/dist/validate.d.ts.map +1 -0
  152. package/dist/validate.js +60 -0
  153. package/dist/validate.js.map +1 -0
  154. package/dist/voices.d.ts +22 -0
  155. package/dist/voices.d.ts.map +1 -0
  156. package/dist/voices.js +31 -0
  157. package/dist/voices.js.map +1 -0
  158. package/package.json +46 -0
@@ -0,0 +1,348 @@
1
+ /**
2
+ * SSML-lite parser — converts a subset of SSML into a SpeechPlan.
3
+ *
4
+ * Tag allowlist:
5
+ * <speak> — root wrapper (optional)
6
+ * <break> — pause (time="250ms" or strength="medium")
7
+ * <prosody> — rate modifier (rate="slow"|"fast"|"x-slow"|"x-fast"|"1.2")
8
+ * <emphasis> — emphasis level (level="strong"|"moderate"|"reduced"|"none")
9
+ * <sub> — substitution (alias="replacement text")
10
+ * <say-as> — interpret-as hint (stripped; text passed through)
11
+ *
12
+ * Everything else is stripped with a warning. The parser produces a flat
13
+ * list of text/event segments plus a fallback plain-text string.
14
+ */
15
+ import { SSML_LIMITS } from "./limits.js";
16
+ // ── Public API ──
17
+ export class SsmlParseError extends Error {
18
+ code;
19
+ constructor(message, code = "SSML_PARSE_FAILED") {
20
+ super(message);
21
+ this.code = code;
22
+ this.name = "SsmlParseError";
23
+ }
24
+ }
25
+ /**
26
+ * Parse SSML-lite input into a SpeechPlan.
27
+ * If input doesn't look like SSML, wraps it as plain text.
28
+ * On parse errors, falls back to plain text with an SSML_PARSE_FAILED warning.
29
+ */
30
+ export function parseSsmlLite(input) {
31
+ const trimmed = input.trim();
32
+ if (!looksLikeSsml(trimmed)) {
33
+ return plainTextPlan(trimmed);
34
+ }
35
+ try {
36
+ return doParse(trimmed);
37
+ }
38
+ catch (err) {
39
+ const message = err instanceof Error ? err.message : String(err);
40
+ return plainTextFallback(trimmed, message);
41
+ }
42
+ }
43
+ /** Check if input looks like it might be SSML. */
44
+ export function looksLikeSsml(input) {
45
+ return /<\s*(speak|break|prosody|emphasis|sub|say-as)\b/i.test(input);
46
+ }
47
+ // ── Allowed tags ──
48
+ const ALLOWED_TAGS = new Set(["speak", "break", "prosody", "emphasis", "sub", "say-as"]);
49
+ // ── Core parser ──
50
+ /**
51
+ * Regex that matches SSML tags (open, close, self-closing).
52
+ * Groups: 1=closing-slash, 2=tag-name, 3=attributes, 4=self-closing-slash
53
+ */
54
+ const TAG_RE = /<(\/?)(\w[\w-]*)((?:\s+[^>]*?)?)(\/?)\s*>/g;
55
+ function doParse(input) {
56
+ let body = input;
57
+ const speakMatch = body.match(/^\s*<speak\b[^>]*>([\s\S]*)<\/speak>\s*$/i);
58
+ if (speakMatch) {
59
+ body = speakMatch[1];
60
+ }
61
+ const state = {
62
+ body,
63
+ segments: [],
64
+ warnings: [],
65
+ nodeCount: 0,
66
+ totalChars: 0,
67
+ openStack: [],
68
+ };
69
+ const re = new RegExp(TAG_RE.source, TAG_RE.flags);
70
+ let lastIndex = 0;
71
+ let match;
72
+ while ((match = re.exec(body)) !== null) {
73
+ const textBefore = body.slice(lastIndex, match.index);
74
+ if (textBefore) {
75
+ addText(state, textBefore);
76
+ }
77
+ lastIndex = match.index + match[0].length;
78
+ const isClosing = match[1] === "/";
79
+ const tagName = match[2].toLowerCase();
80
+ const attrsStr = match[3];
81
+ const isSelfClosing = match[4] === "/";
82
+ state.nodeCount++;
83
+ if (state.nodeCount > SSML_LIMITS.maxNodes) {
84
+ throw new SsmlParseError(`Too many SSML nodes (max ${SSML_LIMITS.maxNodes})`);
85
+ }
86
+ if (!ALLOWED_TAGS.has(tagName)) {
87
+ state.warnings.push({
88
+ code: "SSML_TAG_STRIPPED",
89
+ message: `Unsupported tag <${tagName}> stripped`,
90
+ });
91
+ continue;
92
+ }
93
+ if (tagName === "speak") {
94
+ continue;
95
+ }
96
+ if (isClosing) {
97
+ handleClosingTag(state, tagName);
98
+ }
99
+ else if (isSelfClosing) {
100
+ handleSelfClosingTag(state, tagName, attrsStr);
101
+ }
102
+ else {
103
+ const skip = handleOpeningTag(state, tagName, attrsStr, re);
104
+ if (skip !== undefined) {
105
+ lastIndex = skip;
106
+ re.lastIndex = skip;
107
+ }
108
+ }
109
+ }
110
+ const tail = body.slice(lastIndex);
111
+ if (tail) {
112
+ addText(state, tail);
113
+ }
114
+ // Auto-close unclosed tags
115
+ while (state.openStack.length > 0) {
116
+ const unclosed = state.openStack.pop();
117
+ if (unclosed === "prosody") {
118
+ pushEvent(state, { type: "prosody_end" });
119
+ }
120
+ else if (unclosed === "emphasis") {
121
+ pushEvent(state, { type: "emphasis_end" });
122
+ }
123
+ state.warnings.push({
124
+ code: "SSML_UNCLOSED_TAG",
125
+ message: `Unclosed <${unclosed}> auto-closed`,
126
+ });
127
+ }
128
+ const plainText = extractPlainText(state.segments);
129
+ return {
130
+ segments: state.segments,
131
+ plainText,
132
+ wasSSML: true,
133
+ warnings: state.warnings,
134
+ };
135
+ }
136
+ // ── Tag handlers ──
137
+ function handleSelfClosingTag(state, tagName, attrsStr) {
138
+ if (tagName === "break") {
139
+ const timeMs = parseBreakTime(attrsStr);
140
+ pushEvent(state, { type: "break", timeMs });
141
+ }
142
+ }
143
+ /**
144
+ * Handle an opening tag. Returns a new lastIndex if content was consumed
145
+ * (for <sub> alias replacement), or undefined otherwise.
146
+ */
147
+ function handleOpeningTag(state, tagName, attrsStr, re) {
148
+ switch (tagName) {
149
+ case "break": {
150
+ const timeMs = parseBreakTime(attrsStr);
151
+ pushEvent(state, { type: "break", timeMs });
152
+ return undefined;
153
+ }
154
+ case "prosody": {
155
+ const rate = parseProsodyRate(attrsStr);
156
+ if (rate !== undefined) {
157
+ pushEvent(state, { type: "prosody", rate });
158
+ state.openStack.push("prosody");
159
+ }
160
+ return undefined;
161
+ }
162
+ case "emphasis": {
163
+ const level = parseEmphasisLevel(attrsStr);
164
+ pushEvent(state, { type: "emphasis", level });
165
+ state.openStack.push("emphasis");
166
+ return undefined;
167
+ }
168
+ case "sub": {
169
+ const alias = parseAttr(attrsStr, "alias");
170
+ if (alias) {
171
+ const closeEnd = findCloseTagEnd(state.body, "sub", re.lastIndex);
172
+ if (closeEnd !== -1) {
173
+ addText(state, alias);
174
+ return closeEnd;
175
+ }
176
+ }
177
+ return undefined;
178
+ }
179
+ case "say-as": {
180
+ // Passthrough — inner text is handled naturally
181
+ return undefined;
182
+ }
183
+ default:
184
+ return undefined;
185
+ }
186
+ }
187
+ function handleClosingTag(state, tagName) {
188
+ if (tagName === "prosody") {
189
+ const idx = state.openStack.lastIndexOf("prosody");
190
+ if (idx !== -1) {
191
+ state.openStack.splice(idx, 1);
192
+ pushEvent(state, { type: "prosody_end" });
193
+ }
194
+ }
195
+ else if (tagName === "emphasis") {
196
+ const idx = state.openStack.lastIndexOf("emphasis");
197
+ if (idx !== -1) {
198
+ state.openStack.splice(idx, 1);
199
+ pushEvent(state, { type: "emphasis_end" });
200
+ }
201
+ }
202
+ }
203
+ // ── Attribute parsers ──
204
+ function parseBreakTime(attrsStr) {
205
+ const timeVal = parseAttr(attrsStr, "time");
206
+ if (timeVal) {
207
+ const ms = parseDurationMs(timeVal);
208
+ return Math.min(ms, SSML_LIMITS.maxBreakMs);
209
+ }
210
+ const strength = parseAttr(attrsStr, "strength");
211
+ if (strength) {
212
+ return strengthToMs(strength);
213
+ }
214
+ return 250;
215
+ }
216
+ function parseProsodyRate(attrsStr) {
217
+ const rate = parseAttr(attrsStr, "rate");
218
+ if (!rate)
219
+ return undefined;
220
+ const numeric = parseFloat(rate);
221
+ if (!isNaN(numeric)) {
222
+ return clampRate(numeric);
223
+ }
224
+ switch (rate.toLowerCase()) {
225
+ case "x-slow": return clampRate(0.5);
226
+ case "slow": return clampRate(0.75);
227
+ case "medium": return 1.0;
228
+ case "fast": return clampRate(1.25);
229
+ case "x-fast": return clampRate(1.5);
230
+ default: return undefined;
231
+ }
232
+ }
233
+ function parseEmphasisLevel(attrsStr) {
234
+ const level = parseAttr(attrsStr, "level");
235
+ if (!level)
236
+ return "moderate";
237
+ switch (level.toLowerCase()) {
238
+ case "strong": return "strong";
239
+ case "moderate": return "moderate";
240
+ case "reduced": return "reduced";
241
+ case "none": return "none";
242
+ default: return "moderate";
243
+ }
244
+ }
245
+ // ── Utility ──
246
+ function parseAttr(attrsStr, name) {
247
+ const re = new RegExp(`${name}\\s*=\\s*(?:"([^"]*)"|'([^']*)')`, "i");
248
+ const m = attrsStr.match(re);
249
+ return m ? (m[1] ?? m[2]) : undefined;
250
+ }
251
+ function parseDurationMs(value) {
252
+ const trimmed = value.trim().toLowerCase();
253
+ if (trimmed.endsWith("ms")) {
254
+ return Math.max(0, parseInt(trimmed, 10));
255
+ }
256
+ if (trimmed.endsWith("s")) {
257
+ return Math.max(0, parseFloat(trimmed) * 1000);
258
+ }
259
+ const num = parseInt(trimmed, 10);
260
+ return isNaN(num) ? 250 : Math.max(0, num);
261
+ }
262
+ function strengthToMs(strength) {
263
+ switch (strength.toLowerCase()) {
264
+ case "none": return 0;
265
+ case "x-weak": return 100;
266
+ case "weak": return 200;
267
+ case "medium": return 400;
268
+ case "strong": return 750;
269
+ case "x-strong": return 1000;
270
+ default: return 250;
271
+ }
272
+ }
273
+ function clampRate(rate) {
274
+ return Math.max(SSML_LIMITS.minProsodyRate, Math.min(SSML_LIMITS.maxProsodyRate, rate));
275
+ }
276
+ function addText(state, raw) {
277
+ const text = decodeEntities(raw);
278
+ if (!text.trim())
279
+ return;
280
+ state.totalChars += text.length;
281
+ if (state.totalChars > SSML_LIMITS.maxTotalChars) {
282
+ throw new SsmlParseError(`SSML text content exceeds ${SSML_LIMITS.maxTotalChars} characters`);
283
+ }
284
+ const last = state.segments[state.segments.length - 1];
285
+ if (last && last.type === "text") {
286
+ state.segments[state.segments.length - 1] = { type: "text", value: last.value + text };
287
+ }
288
+ else {
289
+ state.segments.push({ type: "text", value: text });
290
+ }
291
+ }
292
+ function pushEvent(state, event) {
293
+ state.segments.push({ type: "event", event });
294
+ }
295
+ function decodeEntities(text) {
296
+ return text
297
+ .replace(/&amp;/g, "&")
298
+ .replace(/&lt;/g, "<")
299
+ .replace(/&gt;/g, ">")
300
+ .replace(/&quot;/g, '"')
301
+ .replace(/&apos;/g, "'");
302
+ }
303
+ function extractPlainText(segments) {
304
+ return segments
305
+ .filter((s) => s.type === "text")
306
+ .map((s) => s.value)
307
+ .join(" ")
308
+ .replace(/\s+/g, " ")
309
+ .trim();
310
+ }
311
+ /** Find the end index (past the closing tag) of </tagName> starting from fromIndex. */
312
+ function findCloseTagEnd(body, tagName, fromIndex) {
313
+ const closeTag = `</${tagName}>`;
314
+ const idx = body.toLowerCase().indexOf(closeTag.toLowerCase(), fromIndex);
315
+ if (idx === -1)
316
+ return -1;
317
+ return idx + closeTag.length;
318
+ }
319
+ // ── Plain text plans ──
320
+ function plainTextPlan(text) {
321
+ if (!text) {
322
+ return { segments: [], plainText: "", wasSSML: false, warnings: [] };
323
+ }
324
+ return {
325
+ segments: [{ type: "text", value: text }],
326
+ plainText: text,
327
+ wasSSML: false,
328
+ warnings: [],
329
+ };
330
+ }
331
+ function plainTextFallback(input, errorMessage) {
332
+ const stripped = stripAllTags(input);
333
+ return {
334
+ segments: stripped ? [{ type: "text", value: stripped }] : [],
335
+ plainText: stripped,
336
+ wasSSML: true,
337
+ warnings: [{
338
+ code: "SSML_PARSE_FAILED",
339
+ message: `SSML parse failed, using plain text fallback: ${errorMessage}`,
340
+ }],
341
+ };
342
+ }
343
+ function stripAllTags(input) {
344
+ return decodeEntities(input.replace(/<[^>]*>/g, ""))
345
+ .replace(/\s+/g, " ")
346
+ .trim();
347
+ }
348
+ //# sourceMappingURL=parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.js","sourceRoot":"","sources":["../../src/ssml/parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ /** SSML-lite types — backend-agnostic speech plan representation. */
2
+ export interface BreakEvent {
3
+ readonly type: "break";
4
+ /** Duration in milliseconds. */
5
+ readonly timeMs: number;
6
+ }
7
+ export interface ProsodyEvent {
8
+ readonly type: "prosody";
9
+ /** Speed multiplier (e.g. 0.8 for slow, 1.2 for fast). */
10
+ readonly rate: number;
11
+ }
12
+ export interface ProsodyEndEvent {
13
+ readonly type: "prosody_end";
14
+ }
15
+ export interface EmphasisEvent {
16
+ readonly type: "emphasis";
17
+ readonly level: "strong" | "moderate" | "reduced" | "none";
18
+ }
19
+ export interface EmphasisEndEvent {
20
+ readonly type: "emphasis_end";
21
+ }
22
+ export type SpeechEvent = BreakEvent | ProsodyEvent | ProsodyEndEvent | EmphasisEvent | EmphasisEndEvent;
23
+ export interface TextSegment {
24
+ readonly type: "text";
25
+ readonly value: string;
26
+ }
27
+ export interface EventSegment {
28
+ readonly type: "event";
29
+ readonly event: SpeechEvent;
30
+ }
31
+ export type PlanSegment = TextSegment | EventSegment;
32
+ export interface SsmlWarning {
33
+ readonly code: string;
34
+ readonly message: string;
35
+ }
36
+ export interface SpeechPlan {
37
+ /** Ordered segments: text and events interleaved. */
38
+ readonly segments: readonly PlanSegment[];
39
+ /** Plain text with SSML stripped (for backends that don't support events). */
40
+ readonly plainText: string;
41
+ /** Whether the input was SSML (even if fallback occurred). */
42
+ readonly wasSSML: boolean;
43
+ /** Non-fatal warnings (e.g. SSML_PARSE_FAILED for fallback). */
44
+ readonly warnings: readonly SsmlWarning[];
45
+ }
46
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/ssml/types.ts"],"names":[],"mappings":"AAAA,qEAAqE;AAIrE,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,gCAAgC;IAChC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,0DAA0D;IAC1D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;CAC9B;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,QAAQ,GAAG,UAAU,GAAG,SAAS,GAAG,MAAM,CAAC;CAC5D;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;CAC/B;AAED,MAAM,MAAM,WAAW,GACnB,UAAU,GACV,YAAY,GACZ,eAAe,GACf,aAAa,GACb,gBAAgB,CAAC;AAIrB,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;CAC7B;AAED,MAAM,MAAM,WAAW,GAAG,WAAW,GAAG,YAAY,CAAC;AAIrD,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,UAAU;IACzB,qDAAqD;IACrD,QAAQ,CAAC,QAAQ,EAAE,SAAS,WAAW,EAAE,CAAC;IAC1C,8EAA8E;IAC9E,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,8DAA8D;IAC9D,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,gEAAgE;IAChE,QAAQ,CAAC,QAAQ,EAAE,SAAS,WAAW,EAAE,CAAC;CAC3C"}
@@ -0,0 +1,3 @@
1
+ /** SSML-lite types — backend-agnostic speech plan representation. */
2
+ export {};
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/ssml/types.ts"],"names":[],"mappings":"AAAA,qEAAqE"}
@@ -0,0 +1,29 @@
1
+ /** Input validation — voice and preset resolution. */
2
+ import { type VoiceInfo } from "./voices.js";
3
+ export declare class VoiceValidationError extends Error {
4
+ readonly code: string;
5
+ readonly context?: Record<string, unknown> | undefined;
6
+ constructor(message: string, code: string, context?: Record<string, unknown> | undefined);
7
+ }
8
+ /**
9
+ * Assert that a voice ID is in the approved roster.
10
+ * Throws VoiceValidationError with the roster if not.
11
+ */
12
+ export declare function assertApprovedVoice(voiceId: string): VoiceInfo;
13
+ export interface ResolvedVoice {
14
+ readonly voice: VoiceInfo;
15
+ readonly speed: number;
16
+ readonly source: "voice" | "preset" | "default";
17
+ readonly presetName?: string;
18
+ }
19
+ /**
20
+ * Resolve a voice or preset name to a concrete voice + speed.
21
+ *
22
+ * Resolution order:
23
+ * 1. If input matches a preset name → use preset's voice + speed
24
+ * 2. If input matches an approved voice ID → use that voice, speed = 1.0
25
+ * 3. If input is undefined/empty → use DEFAULT_VOICE, speed = 1.0
26
+ * 4. Otherwise → throw VoiceValidationError
27
+ */
28
+ export declare function resolveVoiceOrPreset(input: string | undefined, speedOverride?: number): ResolvedVoice;
29
+ //# sourceMappingURL=validate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"AAAA,sDAAsD;AAEtD,OAAO,EAA+C,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AAG1F,qBAAa,oBAAqB,SAAQ,KAAK;aAG3B,IAAI,EAAE,MAAM;aACZ,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;gBAFjD,OAAO,EAAE,MAAM,EACC,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,YAAA;CAKpD;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAU9D;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,OAAO,GAAG,QAAQ,GAAG,SAAS,CAAC;IAChD,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,aAAa,CAAC,EAAE,MAAM,GACrB,aAAa,CAiCf"}
@@ -0,0 +1,60 @@
1
+ /** Input validation — voice and preset resolution. */
2
+ import { APPROVED_VOICE_IDS, DEFAULT_VOICE, getVoice } from "./voices.js";
3
+ import { getPreset } from "./presets.js";
4
+ export class VoiceValidationError extends Error {
5
+ code;
6
+ context;
7
+ constructor(message, code, context) {
8
+ super(message);
9
+ this.code = code;
10
+ this.context = context;
11
+ this.name = "VoiceValidationError";
12
+ }
13
+ }
14
+ /**
15
+ * Assert that a voice ID is in the approved roster.
16
+ * Throws VoiceValidationError with the roster if not.
17
+ */
18
+ export function assertApprovedVoice(voiceId) {
19
+ const voice = getVoice(voiceId);
20
+ if (!voice) {
21
+ throw new VoiceValidationError(`Voice "${voiceId}" is not in the approved roster`, "VOICE_NOT_APPROVED", { requested: voiceId, approved: [...APPROVED_VOICE_IDS] });
22
+ }
23
+ return voice;
24
+ }
25
+ /**
26
+ * Resolve a voice or preset name to a concrete voice + speed.
27
+ *
28
+ * Resolution order:
29
+ * 1. If input matches a preset name → use preset's voice + speed
30
+ * 2. If input matches an approved voice ID → use that voice, speed = 1.0
31
+ * 3. If input is undefined/empty → use DEFAULT_VOICE, speed = 1.0
32
+ * 4. Otherwise → throw VoiceValidationError
33
+ */
34
+ export function resolveVoiceOrPreset(input, speedOverride) {
35
+ // Default
36
+ if (!input || input.trim() === "") {
37
+ const voice = getVoice(DEFAULT_VOICE);
38
+ return { voice, speed: speedOverride ?? 1.0, source: "default" };
39
+ }
40
+ const trimmed = input.trim().toLowerCase();
41
+ // Try preset first
42
+ const preset = getPreset(trimmed);
43
+ if (preset) {
44
+ const voice = getVoice(preset.voice);
45
+ return {
46
+ voice,
47
+ speed: speedOverride ?? preset.speed,
48
+ source: "preset",
49
+ presetName: preset.name,
50
+ };
51
+ }
52
+ // Try direct voice ID
53
+ const voice = getVoice(trimmed);
54
+ if (voice) {
55
+ return { voice, speed: speedOverride ?? 1.0, source: "voice" };
56
+ }
57
+ // Not found
58
+ throw new VoiceValidationError(`"${input}" is not a recognized voice or preset`, "VOICE_OR_PRESET_NOT_FOUND", { requested: input, approved: [...APPROVED_VOICE_IDS], presets: [...getPreset("assistant") ? ["assistant", "narrator", "announcer", "storyteller", "whisper"] : []] });
59
+ }
60
+ //# sourceMappingURL=validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"AAAA,sDAAsD;AAEtD,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,QAAQ,EAAkB,MAAM,aAAa,CAAC;AAC1F,OAAO,EAAE,SAAS,EAAqB,MAAM,cAAc,CAAC;AAE5D,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IAG3B;IACA;IAHlB,YACE,OAAe,EACC,IAAY,EACZ,OAAiC;QAEjD,KAAK,CAAC,OAAO,CAAC,CAAC;QAHC,SAAI,GAAJ,IAAI,CAAQ;QACZ,YAAO,GAAP,OAAO,CAA0B;QAGjD,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;IACrC,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAAe;IACjD,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;IAChC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,oBAAoB,CAC5B,UAAU,OAAO,iCAAiC,EAClD,oBAAoB,EACpB,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,GAAG,kBAAkB,CAAC,EAAE,CAC1D,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AASD;;;;;;;;GAQG;AACH,MAAM,UAAU,oBAAoB,CAClC,KAAyB,EACzB,aAAsB;IAEtB,UAAU;IACV,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QAClC,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAE,CAAC;QACvC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,aAAa,IAAI,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;IACnE,CAAC;IAED,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAE3C,mBAAmB;IACnB,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC;IAClC,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAE,CAAC;QACtC,OAAO;YACL,KAAK;YACL,KAAK,EAAE,aAAa,IAAI,MAAM,CAAC,KAAK;YACpC,MAAM,EAAE,QAAQ;YAChB,UAAU,EAAE,MAAM,CAAC,IAAI;SACxB,CAAC;IACJ,CAAC;IAED,sBAAsB;IACtB,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;IAChC,IAAI,KAAK,EAAE,CAAC;QACV,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,aAAa,IAAI,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;IACjE,CAAC;IAED,YAAY;IACZ,MAAM,IAAI,oBAAoB,CAC5B,IAAI,KAAK,uCAAuC,EAChD,2BAA2B,EAC3B,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,GAAG,kBAAkB,CAAC,EAAE,OAAO,EAAE,CAAC,GAAG,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,aAAa,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CACtK,CAAC;AACJ,CAAC"}
@@ -0,0 +1,22 @@
1
+ /** Approved voice roster — single source of truth. */
2
+ export interface VoiceInfo {
3
+ readonly id: string;
4
+ readonly name: string;
5
+ readonly gender: "male" | "female";
6
+ readonly accent: "american" | "british";
7
+ readonly style: string;
8
+ readonly language: string;
9
+ }
10
+ export declare const DEFAULT_VOICE: "bm_george";
11
+ /**
12
+ * Approved voice roster (12 voices).
13
+ * All voices are Kokoro-compatible, English-only.
14
+ */
15
+ export declare const VOICES: ReadonlyMap<string, VoiceInfo>;
16
+ /** All approved voice IDs as a set for O(1) lookup. */
17
+ export declare const APPROVED_VOICE_IDS: ReadonlySet<string>;
18
+ /** Get a voice by ID, or undefined if not in the approved roster. */
19
+ export declare function getVoice(id: string): VoiceInfo | undefined;
20
+ /** Check if a voice ID is in the approved roster. */
21
+ export declare function isApprovedVoice(id: string): boolean;
22
+ //# sourceMappingURL=voices.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"voices.d.ts","sourceRoot":"","sources":["../src/voices.ts"],"names":[],"mappings":"AAAA,sDAAsD;AAEtD,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,CAAC;IACnC,QAAQ,CAAC,MAAM,EAAE,UAAU,GAAG,SAAS,CAAC;IACxC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,eAAO,MAAM,aAAa,EAAG,WAAoB,CAAC;AAElD;;;GAGG;AACH,eAAO,MAAM,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,CAahD,CAAC;AAEH,uDAAuD;AACvD,eAAO,MAAM,kBAAkB,EAAE,WAAW,CAAC,MAAM,CAA0B,CAAC;AAE9E,qEAAqE;AACrE,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAE1D;AAED,qDAAqD;AACrD,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAEnD"}
package/dist/voices.js ADDED
@@ -0,0 +1,31 @@
1
+ /** Approved voice roster — single source of truth. */
2
+ export const DEFAULT_VOICE = "bm_george";
3
+ /**
4
+ * Approved voice roster (12 voices).
5
+ * All voices are Kokoro-compatible, English-only.
6
+ */
7
+ export const VOICES = new Map([
8
+ ["af_aoede", { id: "af_aoede", name: "Aoede", gender: "female", accent: "american", style: "musical", language: "en" }],
9
+ ["af_jessica", { id: "af_jessica", name: "Jessica", gender: "female", accent: "american", style: "professional", language: "en" }],
10
+ ["af_sky", { id: "af_sky", name: "Sky", gender: "female", accent: "american", style: "airy", language: "en" }],
11
+ ["am_eric", { id: "am_eric", name: "Eric", gender: "male", accent: "american", style: "confident", language: "en" }],
12
+ ["am_fenrir", { id: "am_fenrir", name: "Fenrir", gender: "male", accent: "american", style: "powerful", language: "en" }],
13
+ ["am_liam", { id: "am_liam", name: "Liam", gender: "male", accent: "american", style: "friendly", language: "en" }],
14
+ ["am_onyx", { id: "am_onyx", name: "Onyx", gender: "male", accent: "american", style: "smooth", language: "en" }],
15
+ ["bf_alice", { id: "bf_alice", name: "Alice", gender: "female", accent: "british", style: "proper", language: "en" }],
16
+ ["bf_emma", { id: "bf_emma", name: "Emma", gender: "female", accent: "british", style: "refined", language: "en" }],
17
+ ["bf_isabella", { id: "bf_isabella", name: "Isabella", gender: "female", accent: "british", style: "warm", language: "en" }],
18
+ ["bm_george", { id: "bm_george", name: "George", gender: "male", accent: "british", style: "authoritative", language: "en" }],
19
+ ["bm_lewis", { id: "bm_lewis", name: "Lewis", gender: "male", accent: "british", style: "friendly", language: "en" }],
20
+ ]);
21
+ /** All approved voice IDs as a set for O(1) lookup. */
22
+ export const APPROVED_VOICE_IDS = new Set(VOICES.keys());
23
+ /** Get a voice by ID, or undefined if not in the approved roster. */
24
+ export function getVoice(id) {
25
+ return VOICES.get(id);
26
+ }
27
+ /** Check if a voice ID is in the approved roster. */
28
+ export function isApprovedVoice(id) {
29
+ return APPROVED_VOICE_IDS.has(id);
30
+ }
31
+ //# sourceMappingURL=voices.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"voices.js","sourceRoot":"","sources":["../src/voices.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "@mcptoolshop/voice-soundboard-core",
3
+ "version": "0.1.0",
4
+ "description": "Backend-agnostic core library for MCP Voice Soundboard — validation, SSML-lite, chunking, emotion spans, SFX tags, and schemas.",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "files": [
9
+ "dist"
10
+ ],
11
+ "license": "MIT",
12
+ "author": "mcp-tool-shop <64996768+mcp-tool-shop@users.noreply.github.com>",
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "https://github.com/mcp-tool-shop-org/mcp-voice-soundboard.git",
16
+ "directory": "packages/core"
17
+ },
18
+ "homepage": "https://github.com/mcp-tool-shop-org/mcp-voice-soundboard/tree/main/packages/core#readme",
19
+ "bugs": {
20
+ "url": "https://github.com/mcp-tool-shop-org/mcp-voice-soundboard/issues"
21
+ },
22
+ "keywords": [
23
+ "mcp",
24
+ "voice",
25
+ "tts",
26
+ "text-to-speech",
27
+ "soundboard",
28
+ "ssml",
29
+ "speech-synthesis",
30
+ "ai-agent",
31
+ "model-context-protocol"
32
+ ],
33
+ "engines": {
34
+ "node": ">=20.0.0"
35
+ },
36
+ "devDependencies": {
37
+ "@types/node": "^22.0.0",
38
+ "typescript": "^5.7.0",
39
+ "vitest": "^3.0.0"
40
+ },
41
+ "scripts": {
42
+ "build": "tsc",
43
+ "test": "vitest run",
44
+ "clean": "rm -rf dist"
45
+ }
46
+ }