@cogitator-ai/voice 0.1.0 → 0.1.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.
Files changed (93) hide show
  1. package/dist/audio.d.ts +10 -0
  2. package/dist/audio.d.ts.map +1 -0
  3. package/dist/audio.js +75 -0
  4. package/dist/audio.js.map +1 -0
  5. package/dist/index.d.ts +17 -0
  6. package/dist/index.d.ts.map +1 -0
  7. package/dist/index.js +16 -0
  8. package/dist/index.js.map +1 -0
  9. package/dist/pipeline/index.d.ts +3 -0
  10. package/dist/pipeline/index.d.ts.map +1 -0
  11. package/dist/pipeline/index.js +3 -0
  12. package/dist/pipeline/index.js.map +1 -0
  13. package/dist/pipeline/pipeline-session.d.ts +21 -0
  14. package/dist/pipeline/pipeline-session.d.ts.map +1 -0
  15. package/dist/pipeline/pipeline-session.js +131 -0
  16. package/dist/pipeline/pipeline-session.js.map +1 -0
  17. package/dist/pipeline/voice-pipeline.d.ts +13 -0
  18. package/dist/pipeline/voice-pipeline.d.ts.map +1 -0
  19. package/dist/pipeline/voice-pipeline.js +17 -0
  20. package/dist/pipeline/voice-pipeline.js.map +1 -0
  21. package/dist/realtime/gemini-realtime.d.ts +28 -0
  22. package/dist/realtime/gemini-realtime.d.ts.map +1 -0
  23. package/dist/realtime/gemini-realtime.js +153 -0
  24. package/dist/realtime/gemini-realtime.js.map +1 -0
  25. package/dist/realtime/index.d.ts +4 -0
  26. package/dist/realtime/index.d.ts.map +1 -0
  27. package/dist/realtime/index.js +4 -0
  28. package/dist/realtime/index.js.map +1 -0
  29. package/dist/realtime/openai-realtime.d.ts +27 -0
  30. package/dist/realtime/openai-realtime.d.ts.map +1 -0
  31. package/dist/realtime/openai-realtime.js +138 -0
  32. package/dist/realtime/openai-realtime.js.map +1 -0
  33. package/dist/realtime/realtime-session.d.ts +23 -0
  34. package/dist/realtime/realtime-session.d.ts.map +1 -0
  35. package/dist/realtime/realtime-session.js +47 -0
  36. package/dist/realtime/realtime-session.js.map +1 -0
  37. package/dist/stt/deepgram-stt.d.ts +17 -0
  38. package/dist/stt/deepgram-stt.d.ts.map +1 -0
  39. package/dist/stt/deepgram-stt.js +138 -0
  40. package/dist/stt/deepgram-stt.js.map +1 -0
  41. package/dist/stt/index.d.ts +3 -0
  42. package/dist/stt/index.d.ts.map +1 -0
  43. package/dist/stt/index.js +3 -0
  44. package/dist/stt/index.js.map +1 -0
  45. package/dist/stt/openai-stt.d.ts +17 -0
  46. package/dist/stt/openai-stt.d.ts.map +1 -0
  47. package/dist/stt/openai-stt.js +80 -0
  48. package/dist/stt/openai-stt.js.map +1 -0
  49. package/dist/tools.d.ts +26 -0
  50. package/dist/tools.d.ts.map +1 -0
  51. package/dist/tools.js +36 -0
  52. package/dist/tools.js.map +1 -0
  53. package/dist/transport/index.d.ts +2 -0
  54. package/dist/transport/index.d.ts.map +1 -0
  55. package/dist/transport/index.js +2 -0
  56. package/dist/transport/index.js.map +1 -0
  57. package/dist/transport/ws-transport.d.ts +37 -0
  58. package/dist/transport/ws-transport.d.ts.map +1 -0
  59. package/dist/transport/ws-transport.js +110 -0
  60. package/dist/transport/ws-transport.js.map +1 -0
  61. package/dist/tts/elevenlabs-tts.d.ts +16 -0
  62. package/dist/tts/elevenlabs-tts.d.ts.map +1 -0
  63. package/dist/tts/elevenlabs-tts.js +77 -0
  64. package/dist/tts/elevenlabs-tts.js.map +1 -0
  65. package/dist/tts/index.d.ts +3 -0
  66. package/dist/tts/index.d.ts.map +1 -0
  67. package/dist/tts/index.js +3 -0
  68. package/dist/tts/index.js.map +1 -0
  69. package/dist/tts/openai-tts.d.ts +18 -0
  70. package/dist/tts/openai-tts.d.ts.map +1 -0
  71. package/dist/tts/openai-tts.js +47 -0
  72. package/dist/tts/openai-tts.js.map +1 -0
  73. package/dist/types.d.ts +96 -0
  74. package/dist/types.d.ts.map +1 -0
  75. package/dist/types.js +2 -0
  76. package/dist/types.js.map +1 -0
  77. package/dist/vad/energy-vad.d.ts +19 -0
  78. package/dist/vad/energy-vad.d.ts.map +1 -0
  79. package/dist/vad/energy-vad.js +49 -0
  80. package/dist/vad/energy-vad.js.map +1 -0
  81. package/dist/vad/index.d.ts +3 -0
  82. package/dist/vad/index.d.ts.map +1 -0
  83. package/dist/vad/index.js +3 -0
  84. package/dist/vad/index.js.map +1 -0
  85. package/dist/vad/silero-vad.d.ts +27 -0
  86. package/dist/vad/silero-vad.d.ts.map +1 -0
  87. package/dist/vad/silero-vad.js +83 -0
  88. package/dist/vad/silero-vad.js.map +1 -0
  89. package/dist/voice-agent.d.ts +25 -0
  90. package/dist/voice-agent.d.ts.map +1 -0
  91. package/dist/voice-agent.js +139 -0
  92. package/dist/voice-agent.js.map +1 -0
  93. package/package.json +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ws-transport.d.ts","sourceRoot":"","sources":["../../src/transport/ws-transport.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAmB,SAAS,EAAE,MAAM,IAAI,CAAC;AAEhD,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAE5D,UAAU,iBAAiB;IACzB,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACvB,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACxC,KAAK,EAAE,EAAE,CAAC;IACV,KAAK,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;CACvB;AAED,qBAAa,WAAY,SAAQ,YAAY,CAAC,iBAAiB,CAAC;IAGlD,OAAO,CAAC,QAAQ,CAAC,EAAE;IAF/B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;gBAES,EAAE,EAAE,SAAS;IAqB1C,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAM9B,WAAW,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAM/C,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI;CAG5C;AAED,UAAU,eAAe;IACvB,UAAU,EAAE,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;CACnC;AAED,qBAAa,kBAAmB,SAAQ,YAAY,CAAC,eAAe,CAAC;IACnE,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,GAAG,CAAgC;IAC3C,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,OAAO,CAA0B;gBAE7B,MAAM,CAAC,EAAE,wBAAwB;IAMvC,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOzC,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,GAAG,IAAI;IAMzC,IAAI,IAAI,IAAI,MAAM,GAAG,SAAS,CAI7B;IAEK,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAmB5B,OAAO,CAAC,QAAQ;CA2BjB"}
@@ -0,0 +1,110 @@
1
+ import { EventEmitter } from 'node:events';
2
+ import http from 'node:http';
3
+ import { WebSocketServer, WebSocket } from 'ws';
4
+ import { nanoid } from 'nanoid';
5
+ export class VoiceClient extends EventEmitter {
6
+ ws;
7
+ id;
8
+ constructor(ws) {
9
+ super();
10
+ this.ws = ws;
11
+ this.id = nanoid();
12
+ ws.on('message', (data, isBinary) => {
13
+ if (isBinary) {
14
+ this.emit('audio', Buffer.from(data));
15
+ }
16
+ else {
17
+ try {
18
+ const parsed = JSON.parse(data.toString());
19
+ this.emit('message', parsed);
20
+ }
21
+ catch (err) {
22
+ this.emit('error', new Error(`Invalid JSON: ${err.message}`));
23
+ }
24
+ }
25
+ });
26
+ ws.on('close', () => this.emit('close'));
27
+ ws.on('error', (err) => this.emit('error', err));
28
+ }
29
+ sendAudio(chunk) {
30
+ if (this.ws.readyState === WebSocket.OPEN) {
31
+ this.ws.send(chunk);
32
+ }
33
+ }
34
+ sendMessage(msg) {
35
+ if (this.ws.readyState === WebSocket.OPEN) {
36
+ this.ws.send(JSON.stringify(msg));
37
+ }
38
+ }
39
+ close(code, reason) {
40
+ this.ws.close(code, reason);
41
+ }
42
+ }
43
+ export class WebSocketTransport extends EventEmitter {
44
+ path;
45
+ maxConnections;
46
+ wss = null;
47
+ server = null;
48
+ ownsServer = false;
49
+ clients = new Set();
50
+ constructor(config) {
51
+ super();
52
+ this.path = config?.path ?? '/voice';
53
+ this.maxConnections = config?.maxConnections ?? 100;
54
+ }
55
+ async listen(port) {
56
+ this.server = http.createServer();
57
+ this.ownsServer = true;
58
+ this.setupWss(this.server);
59
+ await new Promise((resolve) => this.server.listen(port, resolve));
60
+ }
61
+ attachToServer(server) {
62
+ this.server = server;
63
+ this.ownsServer = false;
64
+ this.setupWss(server);
65
+ }
66
+ get port() {
67
+ const addr = this.server?.address();
68
+ if (addr && typeof addr === 'object')
69
+ return addr.port;
70
+ return undefined;
71
+ }
72
+ async close() {
73
+ for (const client of this.clients) {
74
+ client.close(1001, 'server shutting down');
75
+ }
76
+ this.clients.clear();
77
+ if (this.wss) {
78
+ await new Promise((resolve) => this.wss.close(() => resolve()));
79
+ this.wss = null;
80
+ }
81
+ if (this.ownsServer && this.server) {
82
+ await new Promise((resolve, reject) => this.server.close((err) => (err ? reject(err) : resolve())));
83
+ this.server = null;
84
+ }
85
+ }
86
+ setupWss(server) {
87
+ this.wss = new WebSocketServer({ noServer: true });
88
+ server.on('upgrade', (req, socket, head) => {
89
+ const url = new URL(req.url || '/', `http://${req.headers.host || 'localhost'}`);
90
+ if (url.pathname !== this.path) {
91
+ socket.write('HTTP/1.1 404 Not Found\r\n\r\n');
92
+ socket.destroy();
93
+ return;
94
+ }
95
+ if (this.clients.size >= this.maxConnections) {
96
+ this.wss.handleUpgrade(req, socket, head, (ws) => {
97
+ ws.close(1013, 'max connections reached');
98
+ });
99
+ return;
100
+ }
101
+ this.wss.handleUpgrade(req, socket, head, (ws) => {
102
+ const client = new VoiceClient(ws);
103
+ this.clients.add(client);
104
+ client.on('close', () => this.clients.delete(client));
105
+ this.emit('connection', client);
106
+ });
107
+ });
108
+ }
109
+ }
110
+ //# sourceMappingURL=ws-transport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ws-transport.js","sourceRoot":"","sources":["../../src/transport/ws-transport.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAUhC,MAAM,OAAO,WAAY,SAAQ,YAA+B;IAGjC;IAFpB,EAAE,CAAS;IAEpB,YAA6B,EAAa;QACxC,KAAK,EAAE,CAAC;QADmB,OAAE,GAAF,EAAE,CAAW;QAExC,IAAI,CAAC,EAAE,GAAG,MAAM,EAAE,CAAC;QAEnB,EAAE,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,IAAqB,EAAE,QAAiB,EAAE,EAAE;YAC5D,IAAI,QAAQ,EAAE,CAAC;gBACb,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,IAAc,CAAC,CAAC,CAAC;YAClD,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,CAA4B,CAAC;oBACtE,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;gBAC/B,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,KAAK,CAAC,iBAAkB,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;gBAC3E,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;QACzC,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;IACnD,CAAC;IAED,SAAS,CAAC,KAAa;QACrB,IAAI,IAAI,CAAC,EAAE,CAAC,UAAU,KAAK,SAAS,CAAC,IAAI,EAAE,CAAC;YAC1C,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC;IACH,CAAC;IAED,WAAW,CAAC,GAA4B;QACtC,IAAI,IAAI,CAAC,EAAE,CAAC,UAAU,KAAK,SAAS,CAAC,IAAI,EAAE,CAAC;YAC1C,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;IAED,KAAK,CAAC,IAAa,EAAE,MAAe;QAClC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC9B,CAAC;CACF;AAMD,MAAM,OAAO,kBAAmB,SAAQ,YAA6B;IAClD,IAAI,CAAS;IACb,cAAc,CAAS;IAChC,GAAG,GAA2B,IAAI,CAAC;IACnC,MAAM,GAAuB,IAAI,CAAC;IAClC,UAAU,GAAG,KAAK,CAAC;IACnB,OAAO,GAAG,IAAI,GAAG,EAAe,CAAC;IAEzC,YAAY,MAAiC;QAC3C,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,IAAI,GAAG,MAAM,EAAE,IAAI,IAAI,QAAQ,CAAC;QACrC,IAAI,CAAC,cAAc,GAAG,MAAM,EAAE,cAAc,IAAI,GAAG,CAAC;IACtD,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,IAAY;QACvB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QAClC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC3B,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,MAAO,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;IAC3E,CAAC;IAED,cAAc,CAAC,MAAmB;QAChC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;QACxB,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACxB,CAAC;IAED,IAAI,IAAI;QACN,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;QACpC,IAAI,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC,IAAI,CAAC;QACvD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,KAAK,CAAC,KAAK;QACT,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YAClC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,sBAAsB,CAAC,CAAC;QAC7C,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QAErB,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;YACb,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,GAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;YACvE,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC;QAClB,CAAC;QAED,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YACnC,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,CAC1C,IAAI,CAAC,MAAO,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAC7D,CAAC;YACF,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACrB,CAAC;IACH,CAAC;IAEO,QAAQ,CAAC,MAAmB;QAClC,IAAI,CAAC,GAAG,GAAG,IAAI,eAAe,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;QAEnD,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE;YACzC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,EAAE,UAAU,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,WAAW,EAAE,CAAC,CAAC;YAEjF,IAAI,GAAG,CAAC,QAAQ,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC;gBAC/B,MAAM,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC;gBAC/C,MAAM,CAAC,OAAO,EAAE,CAAC;gBACjB,OAAO;YACT,CAAC;YAED,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;gBAC7C,IAAI,CAAC,GAAI,CAAC,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE;oBAChD,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,yBAAyB,CAAC,CAAC;gBAC5C,CAAC,CAAC,CAAC;gBACH,OAAO;YACT,CAAC;YAED,IAAI,CAAC,GAAI,CAAC,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE;gBAChD,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC,EAAE,CAAC,CAAC;gBACnC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;gBACzB,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;gBACtD,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;YAClC,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;CACF"}
@@ -0,0 +1,16 @@
1
+ import type { TTSProvider, TTSOptions } from '../types.js';
2
+ export interface ElevenLabsTTSConfig {
3
+ apiKey: string;
4
+ voiceId?: string;
5
+ model?: string;
6
+ }
7
+ export declare class ElevenLabsTTS implements TTSProvider {
8
+ readonly name = "elevenlabs";
9
+ private readonly apiKey;
10
+ private readonly voiceId;
11
+ private readonly model;
12
+ constructor(config: ElevenLabsTTSConfig);
13
+ synthesize(text: string, options?: TTSOptions): Promise<Buffer>;
14
+ streamSynthesize(text: string, options?: TTSOptions): AsyncGenerator<Buffer>;
15
+ }
16
+ //# sourceMappingURL=elevenlabs-tts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"elevenlabs-tts.d.ts","sourceRoot":"","sources":["../../src/tts/elevenlabs-tts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAoB,MAAM,aAAa,CAAC;AAE7E,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAiBD,qBAAa,aAAc,YAAW,WAAW;IAC/C,QAAQ,CAAC,IAAI,gBAAgB;IAE7B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;gBAEnB,MAAM,EAAE,mBAAmB;IAMjC,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC;IA6B9D,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,cAAc,CAAC,MAAM,CAAC;CA8BpF"}
@@ -0,0 +1,77 @@
1
+ const BASE_URL = 'https://api.elevenlabs.io';
2
+ const DEFAULT_VOICE_ID = '21m00Tcm4TlvDq8ikWAM';
3
+ const DEFAULT_MODEL = 'eleven_flash_v2_5';
4
+ function mapFormat(format) {
5
+ switch (format) {
6
+ case 'pcm16':
7
+ return 'pcm_16000';
8
+ case 'mp3':
9
+ return 'mp3_44100_128';
10
+ default:
11
+ return 'mp3_44100_128';
12
+ }
13
+ }
14
+ export class ElevenLabsTTS {
15
+ name = 'elevenlabs';
16
+ apiKey;
17
+ voiceId;
18
+ model;
19
+ constructor(config) {
20
+ this.apiKey = config.apiKey;
21
+ this.voiceId = config.voiceId ?? DEFAULT_VOICE_ID;
22
+ this.model = config.model ?? DEFAULT_MODEL;
23
+ }
24
+ async synthesize(text, options) {
25
+ const voiceId = options?.voice ?? this.voiceId;
26
+ const outputFormat = mapFormat(options?.format);
27
+ const url = `${BASE_URL}/v1/text-to-speech/${voiceId}?output_format=${outputFormat}`;
28
+ const response = await fetch(url, {
29
+ method: 'POST',
30
+ headers: {
31
+ 'xi-api-key': this.apiKey,
32
+ 'Content-Type': 'application/json',
33
+ },
34
+ body: JSON.stringify({
35
+ text,
36
+ model_id: this.model,
37
+ voice_settings: {
38
+ stability: 0.5,
39
+ similarity_boost: 0.75,
40
+ },
41
+ }),
42
+ });
43
+ if (!response.ok) {
44
+ throw new Error(`ElevenLabs API error ${response.status}`);
45
+ }
46
+ const arrayBuffer = await response.arrayBuffer();
47
+ return Buffer.from(arrayBuffer);
48
+ }
49
+ async *streamSynthesize(text, options) {
50
+ const voiceId = options?.voice ?? this.voiceId;
51
+ const outputFormat = mapFormat(options?.format);
52
+ const url = `${BASE_URL}/v1/text-to-speech/${voiceId}/stream?output_format=${outputFormat}`;
53
+ const response = await fetch(url, {
54
+ method: 'POST',
55
+ headers: {
56
+ 'xi-api-key': this.apiKey,
57
+ 'Content-Type': 'application/json',
58
+ },
59
+ body: JSON.stringify({
60
+ text,
61
+ model_id: this.model,
62
+ voice_settings: {
63
+ stability: 0.5,
64
+ similarity_boost: 0.75,
65
+ },
66
+ }),
67
+ });
68
+ if (!response.ok) {
69
+ throw new Error(`ElevenLabs API error ${response.status}`);
70
+ }
71
+ const body = response.body;
72
+ for await (const chunk of body) {
73
+ yield Buffer.from(chunk);
74
+ }
75
+ }
76
+ }
77
+ //# sourceMappingURL=elevenlabs-tts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"elevenlabs-tts.js","sourceRoot":"","sources":["../../src/tts/elevenlabs-tts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export { OpenAITTS, type OpenAITTSConfig } from './openai-tts.js';
2
+ export { ElevenLabsTTS, type ElevenLabsTTSConfig } from './elevenlabs-tts.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tts/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClE,OAAO,EAAE,aAAa,EAAE,KAAK,mBAAmB,EAAE,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { OpenAITTS } from './openai-tts.js';
2
+ export { ElevenLabsTTS } from './elevenlabs-tts.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tts/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAwB,MAAM,iBAAiB,CAAC;AAClE,OAAO,EAAE,aAAa,EAA4B,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,18 @@
1
+ import type { TTSProvider, TTSOptions } from '../types.js';
2
+ export interface OpenAITTSConfig {
3
+ apiKey: string;
4
+ model?: string;
5
+ voice?: string;
6
+ baseURL?: string;
7
+ }
8
+ export declare class OpenAITTS implements TTSProvider {
9
+ readonly name = "openai";
10
+ private readonly client;
11
+ private readonly model;
12
+ private readonly voice;
13
+ constructor(config: OpenAITTSConfig);
14
+ synthesize(text: string, options?: TTSOptions): Promise<Buffer>;
15
+ streamSynthesize(text: string, options?: TTSOptions): AsyncGenerator<Buffer>;
16
+ private buildParams;
17
+ }
18
+ //# sourceMappingURL=openai-tts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai-tts.d.ts","sourceRoot":"","sources":["../../src/tts/openai-tts.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAoB,MAAM,aAAa,CAAC;AAE7E,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAUD,qBAAa,SAAU,YAAW,WAAW;IAC3C,QAAQ,CAAC,IAAI,YAAY;IAEzB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;gBAEnB,MAAM,EAAE,eAAe;IAS7B,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC;IAM9D,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,cAAc,CAAC,MAAM,CAAC;IAQnF,OAAO,CAAC,WAAW;CAYpB"}
@@ -0,0 +1,47 @@
1
+ import OpenAI from 'openai';
2
+ const DEFAULT_MODEL = 'gpt-4o-mini-tts';
3
+ const DEFAULT_VOICE = 'alloy';
4
+ function mapFormat(format) {
5
+ if (format === 'pcm16')
6
+ return 'pcm';
7
+ return format;
8
+ }
9
+ export class OpenAITTS {
10
+ name = 'openai';
11
+ client;
12
+ model;
13
+ voice;
14
+ constructor(config) {
15
+ this.client = new OpenAI({
16
+ apiKey: config.apiKey,
17
+ ...(config.baseURL && { baseURL: config.baseURL }),
18
+ });
19
+ this.model = config.model ?? DEFAULT_MODEL;
20
+ this.voice = config.voice ?? DEFAULT_VOICE;
21
+ }
22
+ async synthesize(text, options) {
23
+ const response = await this.client.audio.speech.create(this.buildParams(text, options));
24
+ const arrayBuffer = await response.arrayBuffer();
25
+ return Buffer.from(arrayBuffer);
26
+ }
27
+ async *streamSynthesize(text, options) {
28
+ const response = await this.client.audio.speech.create(this.buildParams(text, options));
29
+ const body = response.body;
30
+ for await (const chunk of body) {
31
+ yield Buffer.from(chunk);
32
+ }
33
+ }
34
+ buildParams(text, options) {
35
+ return {
36
+ model: this.model,
37
+ voice: options?.voice ?? this.voice,
38
+ input: text,
39
+ ...(options?.speed !== undefined && { speed: options.speed }),
40
+ ...(options?.format && {
41
+ response_format: mapFormat(options.format),
42
+ }),
43
+ ...(options?.instructions && { instructions: options.instructions }),
44
+ };
45
+ }
46
+ }
47
+ //# sourceMappingURL=openai-tts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai-tts.js","sourceRoot":"","sources":["../../src/tts/openai-tts.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAW5B,MAAM,aAAa,GAAG,iBAAiB,CAAC;AACxC,MAAM,aAAa,GAAG,OAAO,CAAC;AAE9B,SAAS,SAAS,CAAC,MAAwB;IACzC,IAAI,MAAM,KAAK,OAAO;QAAE,OAAO,KAAK,CAAC;IACrC,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,OAAO,SAAS;IACX,IAAI,GAAG,QAAQ,CAAC;IAER,MAAM,CAAS;IACf,KAAK,CAAS;IACd,KAAK,CAAS;IAE/B,YAAY,MAAuB;QACjC,IAAI,CAAC,MAAM,GAAG,IAAI,MAAM,CAAC;YACvB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,GAAG,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;SACnD,CAAC,CAAC;QACH,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,aAAa,CAAC;QAC3C,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,aAAa,CAAC;IAC7C,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,IAAY,EAAE,OAAoB;QACjD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;QACxF,MAAM,WAAW,GAAG,MAAM,QAAQ,CAAC,WAAW,EAAE,CAAC;QACjD,OAAO,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAClC,CAAC;IAED,KAAK,CAAC,CAAC,gBAAgB,CAAC,IAAY,EAAE,OAAoB;QACxD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;QACxF,MAAM,IAAI,GAAI,QAA2D,CAAC,IAAI,CAAC;QAC/E,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,IAAI,EAAE,CAAC;YAC/B,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;IAEO,WAAW,CAAC,IAAY,EAAE,OAAoB;QACpD,OAAO;YACL,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,KAAK,EAAE,OAAO,EAAE,KAAK,IAAI,IAAI,CAAC,KAAK;YACnC,KAAK,EAAE,IAAI;YACX,GAAG,CAAC,OAAO,EAAE,KAAK,KAAK,SAAS,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC;YAC7D,GAAG,CAAC,OAAO,EAAE,MAAM,IAAI;gBACrB,eAAe,EAAE,SAAS,CAAC,OAAO,CAAC,MAAM,CAA0C;aACpF,CAAC;YACF,GAAG,CAAC,OAAO,EAAE,YAAY,IAAI,EAAE,YAAY,EAAE,OAAO,CAAC,YAAY,EAAE,CAAC;SACrE,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,96 @@
1
+ import type { TranscribeResult, VoiceAudioFormat } from '@cogitator-ai/types';
2
+ export type { TranscribeResult, VoiceAudioFormat };
3
+ export interface STTOptions {
4
+ language?: string;
5
+ prompt?: string;
6
+ }
7
+ export interface STTStreamOptions extends STTOptions {
8
+ interimResults?: boolean;
9
+ endpointing?: number;
10
+ }
11
+ export interface STTProvider {
12
+ readonly name: string;
13
+ transcribe(audio: Buffer, options?: STTOptions): Promise<TranscribeResult>;
14
+ createStream(options?: STTStreamOptions): STTStream;
15
+ }
16
+ export interface STTStream {
17
+ write(chunk: Buffer): void;
18
+ close(): Promise<TranscribeResult>;
19
+ on(event: 'partial', cb: (text: string) => void): this;
20
+ on(event: 'final', cb: (result: TranscribeResult) => void): this;
21
+ on(event: 'error', cb: (error: Error) => void): this;
22
+ off(event: string, cb: (...args: unknown[]) => void): this;
23
+ removeAllListeners(): this;
24
+ }
25
+ export interface TTSOptions {
26
+ voice?: string;
27
+ speed?: number;
28
+ format?: VoiceAudioFormat;
29
+ instructions?: string;
30
+ }
31
+ export interface TTSProvider {
32
+ readonly name: string;
33
+ synthesize(text: string, options?: TTSOptions): Promise<Buffer>;
34
+ streamSynthesize(text: string, options?: TTSOptions): AsyncGenerator<Buffer>;
35
+ }
36
+ export type VADEvent = {
37
+ type: 'speech_start';
38
+ } | {
39
+ type: 'speech_end';
40
+ duration: number;
41
+ } | {
42
+ type: 'speech';
43
+ probability: number;
44
+ } | {
45
+ type: 'silence';
46
+ };
47
+ export interface VADProvider {
48
+ readonly name: string;
49
+ process(samples: Float32Array): VADEvent;
50
+ reset(): void;
51
+ }
52
+ export interface VoicePipelineConfig {
53
+ stt: STTProvider;
54
+ tts: TTSProvider;
55
+ vad?: VADProvider;
56
+ agent: {
57
+ run: (input: string) => Promise<{
58
+ content: string;
59
+ }>;
60
+ };
61
+ sampleRate?: number;
62
+ }
63
+ export interface RealtimeSessionConfig {
64
+ provider: 'openai' | 'gemini';
65
+ model?: string;
66
+ apiKey: string;
67
+ instructions?: string;
68
+ tools?: Array<{
69
+ name: string;
70
+ description: string;
71
+ parameters: Record<string, unknown>;
72
+ execute: (args: unknown) => Promise<unknown>;
73
+ }>;
74
+ voice?: string;
75
+ }
76
+ export interface WebSocketTransportConfig {
77
+ path?: string;
78
+ maxConnections?: number;
79
+ }
80
+ export interface VoiceAgentConfig {
81
+ agent: {
82
+ run: (input: string) => Promise<{
83
+ content: string;
84
+ }>;
85
+ };
86
+ mode: 'pipeline' | 'realtime';
87
+ stt?: STTProvider;
88
+ tts?: TTSProvider;
89
+ vad?: VADProvider;
90
+ realtimeProvider?: 'openai' | 'gemini';
91
+ realtimeApiKey?: string;
92
+ realtimeModel?: string;
93
+ voice?: string;
94
+ transport?: WebSocketTransportConfig;
95
+ }
96
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,19 @@
1
+ import type { VADEvent, VADProvider } from '../types.js';
2
+ export interface EnergyVADConfig {
3
+ threshold?: number;
4
+ silenceDuration?: number;
5
+ sampleRate?: number;
6
+ }
7
+ export declare class EnergyVAD implements VADProvider {
8
+ readonly name = "energy";
9
+ private readonly threshold;
10
+ private readonly silenceDuration;
11
+ private readonly sampleRate;
12
+ private state;
13
+ private speechSamples;
14
+ private silenceSamples;
15
+ constructor(config?: EnergyVADConfig);
16
+ process(samples: Float32Array): VADEvent;
17
+ reset(): void;
18
+ }
19
+ //# sourceMappingURL=energy-vad.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"energy-vad.d.ts","sourceRoot":"","sources":["../../src/vad/energy-vad.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAGzD,MAAM,WAAW,eAAe;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,SAAU,YAAW,WAAW;IAC3C,QAAQ,CAAC,IAAI,YAAY;IAEzB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IAEpC,OAAO,CAAC,KAAK,CAA+B;IAC5C,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,cAAc,CAAK;gBAEf,MAAM,GAAE,eAAoB;IAMxC,OAAO,CAAC,OAAO,EAAE,YAAY,GAAG,QAAQ;IAmCxC,KAAK,IAAI,IAAI;CAKd"}
@@ -0,0 +1,49 @@
1
+ import { calculateRMS } from '../audio.js';
2
+ export class EnergyVAD {
3
+ name = 'energy';
4
+ threshold;
5
+ silenceDuration;
6
+ sampleRate;
7
+ state = 'idle';
8
+ speechSamples = 0;
9
+ silenceSamples = 0;
10
+ constructor(config = {}) {
11
+ this.threshold = config.threshold ?? 0.01;
12
+ this.silenceDuration = config.silenceDuration ?? 500;
13
+ this.sampleRate = config.sampleRate ?? 16000;
14
+ }
15
+ process(samples) {
16
+ const rms = calculateRMS(samples);
17
+ const isSpeech = rms > this.threshold;
18
+ const chunkDurationMs = (samples.length / this.sampleRate) * 1000;
19
+ if (this.state === 'idle') {
20
+ if (isSpeech) {
21
+ this.state = 'speaking';
22
+ this.speechSamples = samples.length;
23
+ this.silenceSamples = 0;
24
+ return { type: 'speech_start' };
25
+ }
26
+ return { type: 'silence' };
27
+ }
28
+ this.speechSamples += samples.length;
29
+ if (isSpeech) {
30
+ this.silenceSamples = 0;
31
+ return { type: 'speech', probability: Math.min(1, rms / 0.5) };
32
+ }
33
+ this.silenceSamples += chunkDurationMs;
34
+ if (this.silenceSamples >= this.silenceDuration) {
35
+ const duration = (this.speechSamples / this.sampleRate) * 1000;
36
+ this.state = 'idle';
37
+ this.speechSamples = 0;
38
+ this.silenceSamples = 0;
39
+ return { type: 'speech_end', duration };
40
+ }
41
+ return { type: 'speech', probability: 0 };
42
+ }
43
+ reset() {
44
+ this.state = 'idle';
45
+ this.silenceSamples = 0;
46
+ this.speechSamples = 0;
47
+ }
48
+ }
49
+ //# sourceMappingURL=energy-vad.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"energy-vad.js","sourceRoot":"","sources":["../../src/vad/energy-vad.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAQ3C,MAAM,OAAO,SAAS;IACX,IAAI,GAAG,QAAQ,CAAC;IAER,SAAS,CAAS;IAClB,eAAe,CAAS;IACxB,UAAU,CAAS;IAE5B,KAAK,GAAwB,MAAM,CAAC;IACpC,aAAa,GAAG,CAAC,CAAC;IAClB,cAAc,GAAG,CAAC,CAAC;IAE3B,YAAY,SAA0B,EAAE;QACtC,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,IAAI,CAAC;QAC1C,IAAI,CAAC,eAAe,GAAG,MAAM,CAAC,eAAe,IAAI,GAAG,CAAC;QACrD,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,IAAI,KAAK,CAAC;IAC/C,CAAC;IAED,OAAO,CAAC,OAAqB;QAC3B,MAAM,GAAG,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;QAClC,MAAM,QAAQ,GAAG,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC;QACtC,MAAM,eAAe,GAAG,CAAC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC;QAElE,IAAI,IAAI,CAAC,KAAK,KAAK,MAAM,EAAE,CAAC;YAC1B,IAAI,QAAQ,EAAE,CAAC;gBACb,IAAI,CAAC,KAAK,GAAG,UAAU,CAAC;gBACxB,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC;gBACpC,IAAI,CAAC,cAAc,GAAG,CAAC,CAAC;gBACxB,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC;YAClC,CAAC;YACD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QAC7B,CAAC;QAED,IAAI,CAAC,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC;QAErC,IAAI,QAAQ,EAAE,CAAC;YACb,IAAI,CAAC,cAAc,GAAG,CAAC,CAAC;YACxB,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,GAAG,GAAG,CAAC,EAAE,CAAC;QACjE,CAAC;QAED,IAAI,CAAC,cAAc,IAAI,eAAe,CAAC;QAEvC,IAAI,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;YAChD,MAAM,QAAQ,GAAG,CAAC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC;YAC/D,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC;YACpB,IAAI,CAAC,aAAa,GAAG,CAAC,CAAC;YACvB,IAAI,CAAC,cAAc,GAAG,CAAC,CAAC;YACxB,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC;QAC1C,CAAC;QAED,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC;IAC5C,CAAC;IAED,KAAK;QACH,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC;QACpB,IAAI,CAAC,cAAc,GAAG,CAAC,CAAC;QACxB,IAAI,CAAC,aAAa,GAAG,CAAC,CAAC;IACzB,CAAC;CACF"}
@@ -0,0 +1,3 @@
1
+ export { EnergyVAD, type EnergyVADConfig } from './energy-vad.js';
2
+ export { SileroVAD, type SileroVADConfig } from './silero-vad.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/vad/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClE,OAAO,EAAE,SAAS,EAAE,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { EnergyVAD } from './energy-vad.js';
2
+ export { SileroVAD } from './silero-vad.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/vad/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAwB,MAAM,iBAAiB,CAAC;AAClE,OAAO,EAAE,SAAS,EAAwB,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,27 @@
1
+ import type { VADEvent, VADProvider } from '../types.js';
2
+ export interface SileroVADConfig {
3
+ modelPath: string;
4
+ threshold?: number;
5
+ silenceDuration?: number;
6
+ sampleRate?: number;
7
+ }
8
+ export declare class SileroVAD implements VADProvider {
9
+ readonly name = "silero";
10
+ private readonly modelPath;
11
+ private readonly threshold;
12
+ private readonly silenceDuration;
13
+ private readonly sampleRate;
14
+ private session;
15
+ private ort;
16
+ private hn;
17
+ private cn;
18
+ private state;
19
+ private speechSamples;
20
+ private silenceSamples;
21
+ constructor(config: SileroVADConfig);
22
+ init(): Promise<void>;
23
+ process(samples: Float32Array): VADEvent;
24
+ reset(): void;
25
+ private evaluate;
26
+ }
27
+ //# sourceMappingURL=silero-vad.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"silero-vad.d.ts","sourceRoot":"","sources":["../../src/vad/silero-vad.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAEzD,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAmBD,qBAAa,SAAU,YAAW,WAAW;IAC3C,QAAQ,CAAC,IAAI,YAAY;IAEzB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IAEpC,OAAO,CAAC,OAAO,CAA4B;IAC3C,OAAO,CAAC,GAAG,CAA4B;IAEvC,OAAO,CAAC,EAAE,CAAe;IACzB,OAAO,CAAC,EAAE,CAAe;IAEzB,OAAO,CAAC,KAAK,CAA+B;IAC5C,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,cAAc,CAAK;gBAEf,MAAM,EAAE,eAAe;IAU7B,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAY3B,OAAO,CAAC,OAAO,EAAE,YAAY,GAAG,QAAQ;IAqBxC,KAAK,IAAI,IAAI;IAQb,OAAO,CAAC,QAAQ;CAiCjB"}
@@ -0,0 +1,83 @@
1
+ export class SileroVAD {
2
+ name = 'silero';
3
+ modelPath;
4
+ threshold;
5
+ silenceDuration;
6
+ sampleRate;
7
+ session = null;
8
+ ort = null;
9
+ hn;
10
+ cn;
11
+ state = 'idle';
12
+ speechSamples = 0;
13
+ silenceSamples = 0;
14
+ constructor(config) {
15
+ this.modelPath = config.modelPath;
16
+ this.threshold = config.threshold ?? 0.5;
17
+ this.silenceDuration = config.silenceDuration ?? 500;
18
+ this.sampleRate = config.sampleRate ?? 16000;
19
+ this.hn = new Float32Array(2 * 1 * 64);
20
+ this.cn = new Float32Array(2 * 1 * 64);
21
+ }
22
+ async init() {
23
+ const moduleName = 'onnxruntime-node';
24
+ try {
25
+ this.ort = (await import(/* webpackIgnore: true */ moduleName));
26
+ }
27
+ catch {
28
+ throw new Error('onnxruntime-node is required for SileroVAD. Install it with: npm install onnxruntime-node');
29
+ }
30
+ this.session = await this.ort.InferenceSession.create(this.modelPath);
31
+ }
32
+ process(samples) {
33
+ if (!this.session || !this.ort) {
34
+ throw new Error('SileroVAD: must call init() before process()');
35
+ }
36
+ const { Tensor } = this.ort;
37
+ const input = new Tensor('float32', samples, [1, samples.length]);
38
+ const sr = new Tensor('int64', BigInt64Array.from([BigInt(this.sampleRate)]), [1]);
39
+ const h = new Tensor('float32', this.hn, [2, 1, 64]);
40
+ const c = new Tensor('float32', this.cn, [2, 1, 64]);
41
+ const feeds = { input, sr, h, c };
42
+ const result = this.session.run(feeds);
43
+ const probability = result.output.data[0];
44
+ this.hn = new Float32Array(result.hn.data);
45
+ this.cn = new Float32Array(result.cn.data);
46
+ return this.evaluate(probability, samples.length);
47
+ }
48
+ reset() {
49
+ this.state = 'idle';
50
+ this.speechSamples = 0;
51
+ this.silenceSamples = 0;
52
+ this.hn = new Float32Array(2 * 1 * 64);
53
+ this.cn = new Float32Array(2 * 1 * 64);
54
+ }
55
+ evaluate(probability, chunkLength) {
56
+ const isSpeech = probability >= this.threshold;
57
+ const chunkDurationMs = (chunkLength / this.sampleRate) * 1000;
58
+ if (this.state === 'idle') {
59
+ if (isSpeech) {
60
+ this.state = 'speaking';
61
+ this.speechSamples = chunkLength;
62
+ this.silenceSamples = 0;
63
+ return { type: 'speech_start' };
64
+ }
65
+ return { type: 'silence' };
66
+ }
67
+ this.speechSamples += chunkLength;
68
+ if (isSpeech) {
69
+ this.silenceSamples = 0;
70
+ return { type: 'speech', probability };
71
+ }
72
+ this.silenceSamples += chunkDurationMs;
73
+ if (this.silenceSamples >= this.silenceDuration) {
74
+ const duration = (this.speechSamples / this.sampleRate) * 1000;
75
+ this.state = 'idle';
76
+ this.speechSamples = 0;
77
+ this.silenceSamples = 0;
78
+ return { type: 'speech_end', duration };
79
+ }
80
+ return { type: 'speech', probability: 0 };
81
+ }
82
+ }
83
+ //# sourceMappingURL=silero-vad.js.map