@cogitator-ai/voice 0.1.13 → 0.2.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 +121 -77
- package/dist/audio.d.ts +7 -0
- package/dist/audio.d.ts.map +1 -1
- package/dist/audio.js +40 -3
- package/dist/audio.js.map +1 -1
- package/dist/cogitator-runner.d.ts +34 -0
- package/dist/cogitator-runner.d.ts.map +1 -0
- package/dist/cogitator-runner.js +28 -0
- package/dist/cogitator-runner.js.map +1 -0
- package/dist/index.d.ts +6 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -4
- package/dist/index.js.map +1 -1
- package/dist/pipeline/index.d.ts +2 -2
- package/dist/pipeline/index.d.ts.map +1 -1
- package/dist/pipeline/index.js.map +1 -1
- package/dist/pipeline/pipeline-session.d.ts +20 -2
- package/dist/pipeline/pipeline-session.d.ts.map +1 -1
- package/dist/pipeline/pipeline-session.js +187 -63
- package/dist/pipeline/pipeline-session.js.map +1 -1
- package/dist/pipeline/voice-pipeline.d.ts +12 -7
- package/dist/pipeline/voice-pipeline.d.ts.map +1 -1
- package/dist/pipeline/voice-pipeline.js +14 -4
- package/dist/pipeline/voice-pipeline.js.map +1 -1
- package/dist/realtime/gemini-realtime.d.ts +15 -3
- package/dist/realtime/gemini-realtime.d.ts.map +1 -1
- package/dist/realtime/gemini-realtime.js +140 -94
- package/dist/realtime/gemini-realtime.js.map +1 -1
- package/dist/realtime/openai-realtime.d.ts +10 -1
- package/dist/realtime/openai-realtime.d.ts.map +1 -1
- package/dist/realtime/openai-realtime.js +140 -69
- package/dist/realtime/openai-realtime.js.map +1 -1
- package/dist/realtime/realtime-session.d.ts +10 -0
- package/dist/realtime/realtime-session.d.ts.map +1 -1
- package/dist/realtime/realtime-session.js +60 -7
- package/dist/realtime/realtime-session.js.map +1 -1
- package/dist/stt/deepgram-stt.d.ts +3 -0
- package/dist/stt/deepgram-stt.d.ts.map +1 -1
- package/dist/stt/deepgram-stt.js +104 -55
- package/dist/stt/deepgram-stt.js.map +1 -1
- package/dist/stt/openai-stt.d.ts +5 -0
- package/dist/stt/openai-stt.d.ts.map +1 -1
- package/dist/stt/openai-stt.js +70 -13
- package/dist/stt/openai-stt.js.map +1 -1
- package/dist/tools.d.ts +3 -3
- package/dist/transport/ws-transport.d.ts +6 -7
- package/dist/transport/ws-transport.d.ts.map +1 -1
- package/dist/transport/ws-transport.js +58 -20
- package/dist/transport/ws-transport.js.map +1 -1
- package/dist/tts/elevenlabs-tts.d.ts.map +1 -1
- package/dist/tts/elevenlabs-tts.js +26 -16
- package/dist/tts/elevenlabs-tts.js.map +1 -1
- package/dist/types.d.ts +38 -16
- package/dist/types.d.ts.map +1 -1
- package/dist/vad/silero-vad.d.ts +14 -1
- package/dist/vad/silero-vad.d.ts.map +1 -1
- package/dist/vad/silero-vad.js +101 -25
- package/dist/vad/silero-vad.js.map +1 -1
- package/dist/voice-agent.d.ts +14 -0
- package/dist/voice-agent.d.ts.map +1 -1
- package/dist/voice-agent.js +112 -23
- package/dist/voice-agent.js.map +1 -1
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -33,31 +33,47 @@ pnpm add onnxruntime-node # Silero VAD (neural network-based)
|
|
|
33
33
|
## Quick Start
|
|
34
34
|
|
|
35
35
|
```typescript
|
|
36
|
-
import {
|
|
37
|
-
import {
|
|
36
|
+
import { Cogitator, Agent } from '@cogitator-ai/core';
|
|
37
|
+
import {
|
|
38
|
+
VoiceAgent,
|
|
39
|
+
OpenAISTT,
|
|
40
|
+
OpenAITTS,
|
|
41
|
+
EnergyVAD,
|
|
42
|
+
createCogitatorRunner,
|
|
43
|
+
} from '@cogitator-ai/voice';
|
|
38
44
|
|
|
39
|
-
const
|
|
45
|
+
const cogitator = new Cogitator({ memory: { adapter: 'memory' } });
|
|
46
|
+
const agent = new Agent({
|
|
47
|
+
name: 'assistant',
|
|
48
|
+
model: 'openai/gpt-4o-mini',
|
|
49
|
+
instructions: 'You are a helpful voice assistant. Keep answers short.',
|
|
50
|
+
});
|
|
40
51
|
|
|
41
52
|
const voiceAgent = new VoiceAgent({
|
|
42
|
-
agent,
|
|
43
53
|
mode: 'pipeline',
|
|
54
|
+
agent: createCogitatorRunner(cogitator, agent),
|
|
44
55
|
stt: new OpenAISTT({ apiKey: process.env.OPENAI_API_KEY! }),
|
|
45
56
|
tts: new OpenAITTS({ apiKey: process.env.OPENAI_API_KEY! }),
|
|
57
|
+
vad: new EnergyVAD(),
|
|
46
58
|
});
|
|
47
59
|
|
|
48
60
|
await voiceAgent.listen(8080);
|
|
49
61
|
```
|
|
50
62
|
|
|
51
|
-
Connect from any WebSocket client at `ws://localhost:8080/voice` — send binary
|
|
63
|
+
Connect from any WebSocket client at `ws://localhost:8080/voice` — send binary PCM16 frames, receive binary audio + JSON events (see [WebSocket Protocol](#websocket-protocol)).
|
|
64
|
+
|
|
65
|
+
`createCogitatorRunner()` adapts a `Cogitator` runtime + `Agent` to the `VoiceAgentRunner` interface (`run(input, { sessionId, signal })`). Each voice session gets its own memory thread (`voice:<sessionId>`), and interrupted turns abort the underlying run. Any object with a compatible `run()` works as well.
|
|
52
66
|
|
|
53
67
|
---
|
|
54
68
|
|
|
55
69
|
## STT Providers
|
|
56
70
|
|
|
57
|
-
| Provider | Default Model | Streaming | Word Timestamps
|
|
58
|
-
| ------------- | ------------------------ | ------------------- |
|
|
59
|
-
| `OpenAISTT` | `gpt-4o-mini-transcribe` | Buffered |
|
|
60
|
-
| `DeepgramSTT` | `nova-3` | Real-time WebSocket | Yes
|
|
71
|
+
| Provider | Default Model | Streaming | Word Timestamps | Notes |
|
|
72
|
+
| ------------- | ------------------------ | ------------------- | ---------------- | ---------------------------------------------- |
|
|
73
|
+
| `OpenAISTT` | `gpt-4o-mini-transcribe` | Buffered | `whisper-1` only | Also supports `gpt-4o-transcribe`, `whisper-1` |
|
|
74
|
+
| `DeepgramSTT` | `nova-3` | Real-time WebSocket | Yes | Interim results, endpointing, auto-punctuation |
|
|
75
|
+
|
|
76
|
+
Both providers accept containerized audio (wav, mp3, ogg, flac, webm, mp4 — detected from magic bytes) or headerless PCM16 mono. Streams (`createStream()`) expect raw PCM16 at `sampleRate` (default 16kHz).
|
|
61
77
|
|
|
62
78
|
### OpenAI STT
|
|
63
79
|
|
|
@@ -71,13 +87,15 @@ const stt = new OpenAISTT({
|
|
|
71
87
|
|
|
72
88
|
const result = await stt.transcribe(audioBuffer, { language: 'en' });
|
|
73
89
|
console.log(result.text);
|
|
74
|
-
|
|
75
|
-
|
|
90
|
+
|
|
91
|
+
const whisper = new OpenAISTT({ apiKey: process.env.OPENAI_API_KEY!, model: 'whisper-1' });
|
|
92
|
+
const detailed = await whisper.transcribe(audioBuffer);
|
|
93
|
+
console.log(detailed.words, detailed.duration);
|
|
76
94
|
```
|
|
77
95
|
|
|
78
96
|
### Deepgram STT
|
|
79
97
|
|
|
80
|
-
Real-time streaming with interim results:
|
|
98
|
+
Real-time streaming with interim results. `close()` resolves with the full utterance (all final segments joined):
|
|
81
99
|
|
|
82
100
|
```typescript
|
|
83
101
|
import { DeepgramSTT } from '@cogitator-ai/voice';
|
|
@@ -86,6 +104,7 @@ const stt = new DeepgramSTT({
|
|
|
86
104
|
apiKey: process.env.DEEPGRAM_API_KEY!,
|
|
87
105
|
model: 'nova-3',
|
|
88
106
|
language: 'en',
|
|
107
|
+
sampleRate: 16000,
|
|
89
108
|
});
|
|
90
109
|
|
|
91
110
|
const stream = stt.createStream({ interimResults: true, endpointing: 500 });
|
|
@@ -98,9 +117,9 @@ stream.on('final', (result) => {
|
|
|
98
117
|
console.log('final:', result.text);
|
|
99
118
|
});
|
|
100
119
|
|
|
101
|
-
stream.write(
|
|
102
|
-
stream.write(
|
|
103
|
-
await stream.close();
|
|
120
|
+
stream.write(pcm16Chunk1);
|
|
121
|
+
stream.write(pcm16Chunk2);
|
|
122
|
+
const { text } = await stream.close();
|
|
104
123
|
```
|
|
105
124
|
|
|
106
125
|
---
|
|
@@ -112,6 +131,8 @@ await stream.close();
|
|
|
112
131
|
| `OpenAITTS` | `gpt-4o-mini-tts` | Yes | alloy, ash, ballad, coral, echo, fable, onyx, nova, sage, shimmer, verse, marin, cedar | Also supports `tts-1`, `tts-1-hd`. Supports `instructions` for voice style control |
|
|
113
132
|
| `ElevenLabsTTS` | `eleven_flash_v2_5` | Yes | By voice ID | ~75ms latency. Also supports `eleven_turbo_v2_5`, `eleven_multilingual_v2`, `eleven_v3` |
|
|
114
133
|
|
|
134
|
+
Default output is MP3. `format: 'pcm16'` returns raw PCM16 mono at **24kHz** for both providers. ElevenLabs supports `speed` (0.7–1.2) but not `wav`/`aac` output.
|
|
135
|
+
|
|
115
136
|
### OpenAI TTS
|
|
116
137
|
|
|
117
138
|
```typescript
|
|
@@ -193,7 +214,7 @@ switch (event.type) {
|
|
|
193
214
|
|
|
194
215
|
### Silero VAD
|
|
195
216
|
|
|
196
|
-
Neural network-based VAD using the Silero ONNX model:
|
|
217
|
+
Neural network-based VAD using the Silero ONNX model. Both the v4 (`h`/`c`) and v5 (`state`) model signatures are supported. Chunks of any size are buffered into 32ms frames (512 samples @ 16kHz, 256 @ 8kHz):
|
|
197
218
|
|
|
198
219
|
```typescript
|
|
199
220
|
import { SileroVAD } from '@cogitator-ai/voice';
|
|
@@ -265,19 +286,35 @@ session.on('audio', (chunk) => {
|
|
|
265
286
|
playAudio(chunk);
|
|
266
287
|
});
|
|
267
288
|
|
|
289
|
+
session.on('turn_end', () => {
|
|
290
|
+
console.log('Agent finished speaking');
|
|
291
|
+
});
|
|
292
|
+
|
|
268
293
|
session.pushAudio(pcm16Chunk);
|
|
294
|
+
session.endAudio();
|
|
295
|
+
|
|
296
|
+
await session.sendText('Skip STT and answer this');
|
|
269
297
|
|
|
270
298
|
session.interrupt();
|
|
271
299
|
|
|
272
300
|
await session.close();
|
|
273
301
|
```
|
|
274
302
|
|
|
303
|
+
Without a VAD, audio is buffered until `endAudio()`. `interrupt()` cancels the in-flight turn (the agent receives an aborted `signal`), and `close()` returns without waiting for hung providers. Empty transcripts never reach the agent.
|
|
304
|
+
|
|
275
305
|
---
|
|
276
306
|
|
|
277
307
|
## Realtime Mode
|
|
278
308
|
|
|
279
309
|
Native speech-to-speech without the STT/TTS pipeline. The LLM directly processes and generates audio. Lower latency, more natural conversation flow.
|
|
280
310
|
|
|
311
|
+
| Provider | Default model | Input audio | Output audio | Notes |
|
|
312
|
+
| -------- | ------------------- | ---------------- | ---------------- | ---------------------------------------------- |
|
|
313
|
+
| `openai` | `gpt-realtime-mini` | PCM16 24kHz mono | PCM16 24kHz mono | Realtime API (GA), server VAD, `marin` voice |
|
|
314
|
+
| `gemini` | `gemini-3.8-live` | PCM16 16kHz mono | PCM16 24kHz mono | Gemini Live API, input + output transcriptions |
|
|
315
|
+
|
|
316
|
+
Audio and text sent before `connect()` resolves are queued and flushed once the session is ready. Tools are executed by the session and their results sent back to the model automatically.
|
|
317
|
+
|
|
281
318
|
### OpenAI Realtime
|
|
282
319
|
|
|
283
320
|
```typescript
|
|
@@ -286,8 +323,8 @@ import { RealtimeSession } from '@cogitator-ai/voice';
|
|
|
286
323
|
const session = new RealtimeSession({
|
|
287
324
|
provider: 'openai',
|
|
288
325
|
apiKey: process.env.OPENAI_API_KEY!,
|
|
289
|
-
model: 'gpt-
|
|
290
|
-
voice: '
|
|
326
|
+
model: 'gpt-realtime-mini',
|
|
327
|
+
voice: 'marin',
|
|
291
328
|
instructions: 'You are a helpful assistant.',
|
|
292
329
|
tools: [
|
|
293
330
|
{
|
|
@@ -322,7 +359,7 @@ import { RealtimeSession } from '@cogitator-ai/voice';
|
|
|
322
359
|
const session = new RealtimeSession({
|
|
323
360
|
provider: 'gemini',
|
|
324
361
|
apiKey: process.env.GOOGLE_API_KEY!,
|
|
325
|
-
model: 'gemini-
|
|
362
|
+
model: 'gemini-3.8-live',
|
|
326
363
|
voice: 'Puck',
|
|
327
364
|
instructions: 'You are a helpful assistant.',
|
|
328
365
|
});
|
|
@@ -346,6 +383,8 @@ import { WebSocketTransport, VoiceClient } from '@cogitator-ai/voice';
|
|
|
346
383
|
const transport = new WebSocketTransport({
|
|
347
384
|
path: '/voice',
|
|
348
385
|
maxConnections: 100,
|
|
386
|
+
verifyClient: async (req) =>
|
|
387
|
+
(await isValidToken(req.headers.authorization)) ? true : { code: 401, message: 'Unauthorized' },
|
|
349
388
|
});
|
|
350
389
|
|
|
351
390
|
transport.on('connection', (client: VoiceClient) => {
|
|
@@ -375,14 +414,18 @@ transport.attachToServer(httpServer);
|
|
|
375
414
|
await transport.close();
|
|
376
415
|
```
|
|
377
416
|
|
|
417
|
+
When attached to an existing server, upgrade requests for other paths are left untouched for other handlers; a standalone `listen()` server rejects them with `404`.
|
|
418
|
+
|
|
378
419
|
### WebSocket Protocol
|
|
379
420
|
|
|
380
|
-
| Direction | Format | Content
|
|
381
|
-
| ---------------- | ----------- |
|
|
382
|
-
| Client -> Server | Binary | PCM16
|
|
383
|
-
| Client -> Server | Text (JSON) |
|
|
384
|
-
| Server -> Client | Binary | PCM16
|
|
385
|
-
| Server -> Client | Text (JSON) | `
|
|
421
|
+
| Direction | Format | Content |
|
|
422
|
+
| ---------------- | ----------- | ------------------------------------------------------------------------------------------------------ |
|
|
423
|
+
| Client -> Server | Binary | PCM16 mono 16-bit LE (16kHz for pipeline and Gemini, 24kHz for OpenAI realtime) |
|
|
424
|
+
| Client -> Server | Text (JSON) | `{ type: 'interrupt' }`, `{ type: 'end_of_speech' }`, `{ type: 'text', text }` |
|
|
425
|
+
| Server -> Client | Binary | Response audio (TTS output format in pipeline mode, PCM16 24kHz in realtime mode) |
|
|
426
|
+
| Server -> Client | Text (JSON) | `transcript` (`text`, `isFinal` or `role`), `agent_response`, `speech_start`, `speech_end`, `turn_end` |
|
|
427
|
+
|
|
428
|
+
`end_of_speech` commits buffered audio when no VAD is configured (pipeline mode). `interrupt` cancels the current turn. `text` runs a turn from text input in both modes. Unknown control message types are reported through the `error` event. If the realtime provider cannot be reached or disconnects, the client is closed with code `1011`.
|
|
386
429
|
|
|
387
430
|
---
|
|
388
431
|
|
|
@@ -409,24 +452,36 @@ voiceAgent.on('error', (err) => console.error(err));
|
|
|
409
452
|
console.log(`Active sessions: ${voiceAgent.activeSessions}`);
|
|
410
453
|
|
|
411
454
|
await voiceAgent.listen(8080);
|
|
455
|
+
// or share an existing HTTP server: voiceAgent.attach(httpServer);
|
|
412
456
|
await voiceAgent.close();
|
|
413
457
|
```
|
|
414
458
|
|
|
459
|
+
Attach an `error` listener to observe provider and client errors; without one, errors are not thrown (a misbehaving client cannot crash the server).
|
|
460
|
+
|
|
415
461
|
### Realtime mode with VoiceAgent
|
|
416
462
|
|
|
417
463
|
```typescript
|
|
418
464
|
const voiceAgent = new VoiceAgent({
|
|
419
|
-
agent:
|
|
465
|
+
agent: createCogitatorRunner(cogitator, agent),
|
|
420
466
|
mode: 'realtime',
|
|
421
|
-
realtimeProvider: '
|
|
422
|
-
realtimeApiKey: process.env.
|
|
423
|
-
|
|
424
|
-
|
|
467
|
+
realtimeProvider: 'gemini',
|
|
468
|
+
realtimeApiKey: process.env.GOOGLE_API_KEY!,
|
|
469
|
+
voice: 'Puck',
|
|
470
|
+
tools: [
|
|
471
|
+
{
|
|
472
|
+
name: 'get_time',
|
|
473
|
+
description: 'Current server time',
|
|
474
|
+
parameters: { type: 'object', properties: {} },
|
|
475
|
+
execute: async () => ({ time: new Date().toISOString() }),
|
|
476
|
+
},
|
|
477
|
+
],
|
|
425
478
|
});
|
|
426
479
|
|
|
427
480
|
await voiceAgent.listen(8080);
|
|
428
481
|
```
|
|
429
482
|
|
|
483
|
+
In realtime mode the agent's `instructions` are used as the session instructions unless `instructions` is set explicitly.
|
|
484
|
+
|
|
430
485
|
---
|
|
431
486
|
|
|
432
487
|
## Agent Integration
|
|
@@ -436,41 +491,22 @@ Give any Cogitator agent the ability to transcribe audio or synthesize speech:
|
|
|
436
491
|
```typescript
|
|
437
492
|
import { Agent, tool } from '@cogitator-ai/core';
|
|
438
493
|
import { voiceTools, OpenAISTT, OpenAITTS } from '@cogitator-ai/voice';
|
|
439
|
-
import { z } from 'zod';
|
|
440
494
|
|
|
441
495
|
const [transcribe, speak] = voiceTools({
|
|
442
496
|
stt: new OpenAISTT({ apiKey: process.env.OPENAI_API_KEY! }),
|
|
443
497
|
tts: new OpenAITTS({ apiKey: process.env.OPENAI_API_KEY! }),
|
|
444
498
|
});
|
|
445
499
|
|
|
446
|
-
const transcribeTool = tool({
|
|
447
|
-
name: transcribe.name,
|
|
448
|
-
description: transcribe.description,
|
|
449
|
-
parameters: z.object({
|
|
450
|
-
audioBase64: z.string().describe('Base64-encoded audio data'),
|
|
451
|
-
language: z.string().optional().describe('Language code'),
|
|
452
|
-
}),
|
|
453
|
-
execute: async (params) => transcribe.execute(params),
|
|
454
|
-
});
|
|
455
|
-
|
|
456
|
-
const speakTool = tool({
|
|
457
|
-
name: speak.name,
|
|
458
|
-
description: speak.description,
|
|
459
|
-
parameters: z.object({
|
|
460
|
-
text: z.string().describe('Text to convert to speech'),
|
|
461
|
-
voice: z.string().optional().describe('Voice to use'),
|
|
462
|
-
}),
|
|
463
|
-
execute: async (params) => speak.execute(params),
|
|
464
|
-
});
|
|
465
|
-
|
|
466
500
|
const agent = new Agent({
|
|
467
501
|
name: 'voice-assistant',
|
|
468
|
-
model: 'gpt-4o',
|
|
502
|
+
model: 'openai/gpt-4o',
|
|
469
503
|
instructions: 'You can transcribe audio and generate speech.',
|
|
470
|
-
tools: [
|
|
504
|
+
tools: [tool(transcribe), tool(speak)],
|
|
471
505
|
});
|
|
472
506
|
```
|
|
473
507
|
|
|
508
|
+
`VoiceTool` objects carry Zod parameter schemas, so they can be passed to `tool()` as-is.
|
|
509
|
+
|
|
474
510
|
---
|
|
475
511
|
|
|
476
512
|
## Audio Utilities
|
|
@@ -485,6 +521,7 @@ import {
|
|
|
485
521
|
wavToPcm,
|
|
486
522
|
resample,
|
|
487
523
|
calculateRMS,
|
|
524
|
+
detectAudioFormat,
|
|
488
525
|
} from '@cogitator-ai/voice';
|
|
489
526
|
|
|
490
527
|
const pcm = float32ToPcm16(float32Samples);
|
|
@@ -496,6 +533,8 @@ const { samples, sampleRate } = wavToPcm(wavBuffer);
|
|
|
496
533
|
const resampled = resample(float32Samples, 44100, 16000);
|
|
497
534
|
|
|
498
535
|
const rms = calculateRMS(float32Samples);
|
|
536
|
+
|
|
537
|
+
detectAudioFormat(fileBuffer); // 'wav' | 'mp3' | 'ogg' | 'flac' | 'webm' | 'mp4' | null (raw PCM)
|
|
499
538
|
```
|
|
500
539
|
|
|
501
540
|
---
|
|
@@ -504,18 +543,20 @@ const rms = calculateRMS(float32Samples);
|
|
|
504
543
|
|
|
505
544
|
### `VoiceAgentConfig`
|
|
506
545
|
|
|
507
|
-
| Field | Type
|
|
508
|
-
| ------------------ |
|
|
509
|
-
| `agent` | `
|
|
510
|
-
| `mode` | `'pipeline' \| 'realtime'`
|
|
511
|
-
| `stt` | `STTProvider`
|
|
512
|
-
| `tts` | `TTSProvider`
|
|
513
|
-
| `vad` | `VADProvider`
|
|
514
|
-
| `realtimeProvider` | `'openai' \| 'gemini'`
|
|
515
|
-
| `realtimeApiKey` | `string`
|
|
516
|
-
| `realtimeModel` | `string`
|
|
517
|
-
| `
|
|
518
|
-
| `
|
|
546
|
+
| Field | Type | Required | Description |
|
|
547
|
+
| ------------------ | -------------------------- | ------------- | --------------------------------------------------------- |
|
|
548
|
+
| `agent` | `VoiceAgentRunner` | Yes | `createCogitatorRunner(...)` or any `{ run(input, ctx) }` |
|
|
549
|
+
| `mode` | `'pipeline' \| 'realtime'` | Yes | Processing mode |
|
|
550
|
+
| `stt` | `STTProvider` | Pipeline only | Speech-to-text provider |
|
|
551
|
+
| `tts` | `TTSProvider` | Pipeline only | Text-to-speech provider |
|
|
552
|
+
| `vad` | `VADProvider` | No | Voice activity detection |
|
|
553
|
+
| `realtimeProvider` | `'openai' \| 'gemini'` | Realtime only | Realtime API provider |
|
|
554
|
+
| `realtimeApiKey` | `string` | Realtime only | API key for realtime provider |
|
|
555
|
+
| `realtimeModel` | `string` | No | Model override |
|
|
556
|
+
| `instructions` | `string` | No | Realtime instructions (defaults to `agent.instructions`) |
|
|
557
|
+
| `tools` | `RealtimeTool[]` | No | Realtime tools executed by the session |
|
|
558
|
+
| `voice` | `string` | No | Voice for realtime |
|
|
559
|
+
| `transport` | `WebSocketTransportConfig` | No | Transport options |
|
|
519
560
|
|
|
520
561
|
### `OpenAISTTConfig`
|
|
521
562
|
|
|
@@ -527,11 +568,12 @@ const rms = calculateRMS(float32Samples);
|
|
|
527
568
|
|
|
528
569
|
### `DeepgramSTTConfig`
|
|
529
570
|
|
|
530
|
-
| Field
|
|
531
|
-
|
|
|
532
|
-
| `apiKey`
|
|
533
|
-
| `model`
|
|
534
|
-
| `language`
|
|
571
|
+
| Field | Type | Default | Description |
|
|
572
|
+
| ------------ | -------- | -------- | ---------------------------------------------- |
|
|
573
|
+
| `apiKey` | `string` | — | Deepgram API key |
|
|
574
|
+
| `model` | `string` | `nova-3` | Model ID |
|
|
575
|
+
| `language` | `string` | — | Default language code |
|
|
576
|
+
| `sampleRate` | `number` | `16000` | Sample rate of raw PCM16 (streams, headerless) |
|
|
535
577
|
|
|
536
578
|
### `OpenAITTSConfig`
|
|
537
579
|
|
|
@@ -569,10 +611,11 @@ const rms = calculateRMS(float32Samples);
|
|
|
569
611
|
|
|
570
612
|
### `WebSocketTransportConfig`
|
|
571
613
|
|
|
572
|
-
| Field | Type
|
|
573
|
-
| ---------------- |
|
|
574
|
-
| `path` | `string`
|
|
575
|
-
| `maxConnections` | `number`
|
|
614
|
+
| Field | Type | Default | Description |
|
|
615
|
+
| ---------------- | ---------------------------------------------------- | -------- | ---------------------------------------------- |
|
|
616
|
+
| `path` | `string` | `/voice` | WebSocket endpoint path |
|
|
617
|
+
| `maxConnections` | `number` | `100` | Maximum concurrent connections |
|
|
618
|
+
| `verifyClient` | `(req) => true \| { code, message } \| Promise<...>` | — | Authorize upgrades (throwing rejects with 500) |
|
|
576
619
|
|
|
577
620
|
---
|
|
578
621
|
|
|
@@ -580,9 +623,10 @@ const rms = calculateRMS(float32Samples);
|
|
|
580
623
|
|
|
581
624
|
See [`examples/voice/`](../../examples/voice/) for runnable examples:
|
|
582
625
|
|
|
583
|
-
- **01-pipeline
|
|
584
|
-
- **02-realtime
|
|
585
|
-
- **03-
|
|
626
|
+
- **01-pipeline.ts** — STT -> Cogitator agent -> TTS with `VoicePipeline` and `createCogitatorRunner`
|
|
627
|
+
- **02-realtime.ts** — Realtime session with tool calling (Gemini Live or OpenAI Realtime)
|
|
628
|
+
- **03-voice-agent.ts** — WebSocket `VoiceAgent` with Deepgram STT, ElevenLabs TTS and EnergyVAD
|
|
629
|
+
- **04-realtime-voice-agent.ts** — Realtime `VoiceAgent` (Gemini Live) with a server-side tool and a WebSocket client
|
|
586
630
|
|
|
587
631
|
---
|
|
588
632
|
|
package/dist/audio.d.ts
CHANGED
|
@@ -7,4 +7,11 @@ export declare function wavToPcm(wav: Buffer): {
|
|
|
7
7
|
};
|
|
8
8
|
export declare function resample(samples: Float32Array, fromRate: number, toRate: number): Float32Array;
|
|
9
9
|
export declare function calculateRMS(samples: Float32Array): number;
|
|
10
|
+
export type DetectedAudioFormat = 'wav' | 'mp3' | 'ogg' | 'flac' | 'webm' | 'mp4';
|
|
11
|
+
/**
|
|
12
|
+
* Detect a containerized audio format from its magic bytes.
|
|
13
|
+
* Returns `null` for headerless data such as raw PCM16.
|
|
14
|
+
*/
|
|
15
|
+
export declare function detectAudioFormat(audio: Buffer): DetectedAudioFormat | null;
|
|
16
|
+
export declare function audioMimeType(format: DetectedAudioFormat): string;
|
|
10
17
|
//# sourceMappingURL=audio.d.ts.map
|
package/dist/audio.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audio.d.ts","sourceRoot":"","sources":["../src/audio.ts"],"names":[],"mappings":"AAAA,wBAAgB,cAAc,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,CAQ5D;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,CAQ3D;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,SAAQ,GAAG,MAAM,CAuBhE;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,YAAY,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAiCnF;AAED,wBAAgB,QAAQ,CAAC,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,YAAY,CAiB9F;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,CAK1D"}
|
|
1
|
+
{"version":3,"file":"audio.d.ts","sourceRoot":"","sources":["../src/audio.ts"],"names":[],"mappings":"AAAA,wBAAgB,cAAc,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,CAQ5D;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,CAQ3D;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,SAAQ,GAAG,MAAM,CAuBhE;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,YAAY,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAiCnF;AAED,wBAAgB,QAAQ,CAAC,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,YAAY,CAiB9F;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,CAK1D;AAED,MAAM,MAAM,mBAAmB,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;AAWlF;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,mBAAmB,GAAG,IAAI,CAe3E;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,mBAAmB,GAAG,MAAM,CAEjE"}
|
package/dist/audio.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export function float32ToPcm16(samples) {
|
|
2
2
|
const buffer = Buffer.alloc(samples.length * 2);
|
|
3
|
-
const view = new DataView(buffer.buffer, buffer.byteOffset);
|
|
3
|
+
const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
|
|
4
4
|
for (let i = 0; i < samples.length; i++) {
|
|
5
5
|
const clamped = Math.max(-1, Math.min(1, samples[i]));
|
|
6
6
|
view.setInt16(i * 2, clamped < 0 ? clamped * 0x8000 : clamped * 0x7fff, true);
|
|
@@ -8,8 +8,8 @@ export function float32ToPcm16(samples) {
|
|
|
8
8
|
return buffer;
|
|
9
9
|
}
|
|
10
10
|
export function pcm16ToFloat32(buffer) {
|
|
11
|
-
const view = new DataView(buffer.buffer, buffer.byteOffset);
|
|
12
|
-
const samples = new Float32Array(buffer.length / 2);
|
|
11
|
+
const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
|
|
12
|
+
const samples = new Float32Array(Math.floor(buffer.length / 2));
|
|
13
13
|
for (let i = 0; i < samples.length; i++) {
|
|
14
14
|
const val = view.getInt16(i * 2, true);
|
|
15
15
|
samples[i] = val < 0 ? val / 0x8000 : val / 0x7fff;
|
|
@@ -93,4 +93,41 @@ export function calculateRMS(samples) {
|
|
|
93
93
|
sum += s * s;
|
|
94
94
|
return Math.sqrt(sum / samples.length);
|
|
95
95
|
}
|
|
96
|
+
const AUDIO_MIME_TYPES = {
|
|
97
|
+
wav: 'audio/wav',
|
|
98
|
+
mp3: 'audio/mpeg',
|
|
99
|
+
ogg: 'audio/ogg',
|
|
100
|
+
flac: 'audio/flac',
|
|
101
|
+
webm: 'audio/webm',
|
|
102
|
+
mp4: 'audio/mp4',
|
|
103
|
+
};
|
|
104
|
+
/**
|
|
105
|
+
* Detect a containerized audio format from its magic bytes.
|
|
106
|
+
* Returns `null` for headerless data such as raw PCM16.
|
|
107
|
+
*/
|
|
108
|
+
export function detectAudioFormat(audio) {
|
|
109
|
+
if (audio.length < 4)
|
|
110
|
+
return null;
|
|
111
|
+
const ascii4 = audio.toString('ascii', 0, 4);
|
|
112
|
+
if (ascii4 === 'RIFF' && audio.length >= 12 && audio.toString('ascii', 8, 12) === 'WAVE') {
|
|
113
|
+
return 'wav';
|
|
114
|
+
}
|
|
115
|
+
if (ascii4 === 'OggS')
|
|
116
|
+
return 'ogg';
|
|
117
|
+
if (ascii4 === 'fLaC')
|
|
118
|
+
return 'flac';
|
|
119
|
+
if (audio.toString('ascii', 0, 3) === 'ID3')
|
|
120
|
+
return 'mp3';
|
|
121
|
+
if (audio[0] === 0xff && (audio[1] & 0xe0) === 0xe0 && (audio[1] & 0x06) !== 0)
|
|
122
|
+
return 'mp3';
|
|
123
|
+
if (audio[0] === 0x1a && audio[1] === 0x45 && audio[2] === 0xdf && audio[3] === 0xa3) {
|
|
124
|
+
return 'webm';
|
|
125
|
+
}
|
|
126
|
+
if (audio.length >= 8 && audio.toString('ascii', 4, 8) === 'ftyp')
|
|
127
|
+
return 'mp4';
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
export function audioMimeType(format) {
|
|
131
|
+
return AUDIO_MIME_TYPES[format];
|
|
132
|
+
}
|
|
96
133
|
//# sourceMappingURL=audio.js.map
|
package/dist/audio.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audio.js","sourceRoot":"","sources":["../src/audio.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,cAAc,CAAC,OAAqB;IAClD,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAChD,MAAM,IAAI,GAAG,IAAI,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"audio.js","sourceRoot":"","sources":["../src/audio.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { VoiceAgentRunner, VoiceRunContext } from './types.js';
|
|
2
|
+
export interface CogitatorLike<TAgent> {
|
|
3
|
+
run(agent: TAgent, options: {
|
|
4
|
+
input: string;
|
|
5
|
+
threadId?: string;
|
|
6
|
+
signal?: AbortSignal;
|
|
7
|
+
}): Promise<{
|
|
8
|
+
readonly output: string;
|
|
9
|
+
}>;
|
|
10
|
+
}
|
|
11
|
+
export interface CogitatorRunnerOptions {
|
|
12
|
+
/**
|
|
13
|
+
* Thread id used for agent memory. Defaults to `voice:<sessionId>` so each voice
|
|
14
|
+
* session keeps its own conversation history.
|
|
15
|
+
*/
|
|
16
|
+
threadId?: (context: VoiceRunContext) => string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Adapt a Cogitator runtime + agent to the `VoiceAgentRunner` interface used by
|
|
20
|
+
* `VoicePipeline` and `VoiceAgent`.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```ts
|
|
24
|
+
* const voice = new VoiceAgent({
|
|
25
|
+
* mode: 'pipeline',
|
|
26
|
+
* agent: createCogitatorRunner(cogitator, agent),
|
|
27
|
+
* stt, tts,
|
|
28
|
+
* });
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export declare function createCogitatorRunner<TAgent extends {
|
|
32
|
+
readonly instructions?: string;
|
|
33
|
+
}>(cogitator: CogitatorLike<TAgent>, agent: TAgent, options?: CogitatorRunnerOptions): VoiceAgentRunner;
|
|
34
|
+
//# sourceMappingURL=cogitator-runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cogitator-runner.d.ts","sourceRoot":"","sources":["../src/cogitator-runner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAEpE,MAAM,WAAW,aAAa,CAAC,MAAM;IACnC,GAAG,CACD,KAAK,EAAE,MAAM,EACb,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GAClE,OAAO,CAAC;QAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACzC;AAED,MAAM,WAAW,sBAAsB;IACrC;;;OAGG;IACH,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,MAAM,CAAC;CACjD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,SAAS;IAAE,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,EACrF,SAAS,EAAE,aAAa,CAAC,MAAM,CAAC,EAChC,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,sBAA2B,GACnC,gBAAgB,CAalB"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Adapt a Cogitator runtime + agent to the `VoiceAgentRunner` interface used by
|
|
3
|
+
* `VoicePipeline` and `VoiceAgent`.
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* ```ts
|
|
7
|
+
* const voice = new VoiceAgent({
|
|
8
|
+
* mode: 'pipeline',
|
|
9
|
+
* agent: createCogitatorRunner(cogitator, agent),
|
|
10
|
+
* stt, tts,
|
|
11
|
+
* });
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
export function createCogitatorRunner(cogitator, agent, options = {}) {
|
|
15
|
+
const resolveThreadId = options.threadId ?? ((ctx) => `voice:${ctx.sessionId}`);
|
|
16
|
+
return {
|
|
17
|
+
instructions: agent.instructions,
|
|
18
|
+
async run(input, context) {
|
|
19
|
+
const result = await cogitator.run(agent, {
|
|
20
|
+
input,
|
|
21
|
+
...(context && { threadId: resolveThreadId(context) }),
|
|
22
|
+
...(context?.signal && { signal: context.signal }),
|
|
23
|
+
});
|
|
24
|
+
return { content: result.output };
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=cogitator-runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cogitator-runner.js","sourceRoot":"","sources":["../src/cogitator-runner.ts"],"names":[],"mappings":"AAiBA;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,qBAAqB,CACnC,SAAgC,EAChC,KAAa,EACb,UAAkC,EAAE;IAEpC,MAAM,eAAe,GAAG,OAAO,CAAC,QAAQ,IAAI,CAAC,CAAC,GAAoB,EAAE,EAAE,CAAC,SAAS,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC;IACjG,OAAO;QACL,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO;YACtB,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE;gBACxC,KAAK;gBACL,GAAG,CAAC,OAAO,IAAI,EAAE,QAAQ,EAAE,eAAe,CAAC,OAAO,CAAC,EAAE,CAAC;gBACtD,GAAG,CAAC,OAAO,EAAE,MAAM,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC;aACnD,CAAC,CAAC;YACH,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC;QACpC,CAAC;KACF,CAAC;AACJ,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
|
-
export declare const VERSION
|
|
2
|
-
export type { STTOptions, STTStreamOptions, STTProvider, STTStream, TTSOptions, TTSProvider, VADEvent, VADProvider, VoicePipelineConfig, RealtimeSessionConfig, WebSocketTransportConfig, VoiceAgentConfig, TranscribeResult, VoiceAudioFormat, } from './types.js';
|
|
3
|
-
export { float32ToPcm16, pcm16ToFloat32, pcmToWav, wavToPcm, resample, calculateRMS, } from './audio.js';
|
|
1
|
+
export declare const VERSION: string;
|
|
2
|
+
export type { STTOptions, STTStreamOptions, STTProvider, STTStream, TTSOptions, TTSProvider, VADEvent, VADProvider, VoicePipelineConfig, VoiceAgentRunner, VoiceRunContext, RealtimeSessionConfig, RealtimeTool, WebSocketTransportConfig, VerifyClientResult, VoiceAgentConfig, TranscribeResult, VoiceAudioFormat, } from './types.js';
|
|
3
|
+
export { float32ToPcm16, pcm16ToFloat32, pcmToWav, wavToPcm, resample, calculateRMS, detectAudioFormat, audioMimeType, type DetectedAudioFormat, } from './audio.js';
|
|
4
4
|
export { OpenAISTT, type OpenAISTTConfig } from './stt/index.js';
|
|
5
5
|
export { DeepgramSTT, type DeepgramSTTConfig } from './stt/index.js';
|
|
6
6
|
export { OpenAITTS, type OpenAITTSConfig } from './tts/index.js';
|
|
7
7
|
export { ElevenLabsTTS, type ElevenLabsTTSConfig } from './tts/index.js';
|
|
8
8
|
export { EnergyVAD, type EnergyVADConfig } from './vad/index.js';
|
|
9
9
|
export { SileroVAD, type SileroVADConfig } from './vad/index.js';
|
|
10
|
-
export { VoicePipeline, PipelineSession } from './pipeline/index.js';
|
|
10
|
+
export { VoicePipeline, PipelineSession, type VoicePipelineResult, type PipelineSessionOptions, } from './pipeline/index.js';
|
|
11
11
|
export { OpenAIRealtimeAdapter } from './realtime/index.js';
|
|
12
12
|
export { GeminiRealtimeAdapter } from './realtime/index.js';
|
|
13
13
|
export { RealtimeSession } from './realtime/index.js';
|
|
14
|
-
export { WebSocketTransport, VoiceClient } from './transport/index.js';
|
|
14
|
+
export { WebSocketTransport, VoiceClient, type WebSocketTransportOptions, } from './transport/index.js';
|
|
15
15
|
export { VoiceAgent } from './voice-agent.js';
|
|
16
|
+
export { createCogitatorRunner, type CogitatorLike, type CogitatorRunnerOptions, } from './cogitator-runner.js';
|
|
16
17
|
export { transcribeTool, speakTool, voiceTools, type VoiceTool } from './tools.js';
|
|
17
18
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,OAAO,EAAE,MAA4B,CAAC;AAEnD,YAAY,EACV,UAAU,EACV,gBAAgB,EAChB,WAAW,EACX,SAAS,EACT,UAAU,EACV,WAAW,EACX,QAAQ,EACR,WAAW,EACX,mBAAmB,EACnB,gBAAgB,EAChB,eAAe,EACf,qBAAqB,EACrB,YAAY,EACZ,wBAAwB,EACxB,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,cAAc,EACd,cAAc,EACd,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,YAAY,EACZ,iBAAiB,EACjB,aAAa,EACb,KAAK,mBAAmB,GACzB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,SAAS,EAAE,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjE,OAAO,EAAE,WAAW,EAAE,KAAK,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAErE,OAAO,EAAE,SAAS,EAAE,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,KAAK,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAEzE,OAAO,EAAE,SAAS,EAAE,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjE,OAAO,EAAE,SAAS,EAAE,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEjE,OAAO,EACL,aAAa,EACb,eAAe,EACf,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,GAC5B,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtD,OAAO,EACL,kBAAkB,EAClB,WAAW,EACX,KAAK,yBAAyB,GAC/B,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EACL,qBAAqB,EACrB,KAAK,aAAa,EAClB,KAAK,sBAAsB,GAC5B,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,UAAU,EAAE,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,16 +1,19 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { createRequire } from 'node:module';
|
|
2
|
+
const packageJson = createRequire(import.meta.url)('../package.json');
|
|
3
|
+
export const VERSION = packageJson.version;
|
|
4
|
+
export { float32ToPcm16, pcm16ToFloat32, pcmToWav, wavToPcm, resample, calculateRMS, detectAudioFormat, audioMimeType, } from './audio.js';
|
|
3
5
|
export { OpenAISTT } from './stt/index.js';
|
|
4
6
|
export { DeepgramSTT } from './stt/index.js';
|
|
5
7
|
export { OpenAITTS } from './tts/index.js';
|
|
6
8
|
export { ElevenLabsTTS } from './tts/index.js';
|
|
7
9
|
export { EnergyVAD } from './vad/index.js';
|
|
8
10
|
export { SileroVAD } from './vad/index.js';
|
|
9
|
-
export { VoicePipeline, PipelineSession } from './pipeline/index.js';
|
|
11
|
+
export { VoicePipeline, PipelineSession, } from './pipeline/index.js';
|
|
10
12
|
export { OpenAIRealtimeAdapter } from './realtime/index.js';
|
|
11
13
|
export { GeminiRealtimeAdapter } from './realtime/index.js';
|
|
12
14
|
export { RealtimeSession } from './realtime/index.js';
|
|
13
|
-
export { WebSocketTransport, VoiceClient } from './transport/index.js';
|
|
15
|
+
export { WebSocketTransport, VoiceClient, } from './transport/index.js';
|
|
14
16
|
export { VoiceAgent } from './voice-agent.js';
|
|
17
|
+
export { createCogitatorRunner, } from './cogitator-runner.js';
|
|
15
18
|
export { transcribeTool, speakTool, voiceTools } from './tools.js';
|
|
16
19
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,WAAW,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,iBAAiB,CAAwB,CAAC;AAE7F,MAAM,CAAC,MAAM,OAAO,GAAW,WAAW,CAAC,OAAO,CAAC;AAuBnD,OAAO,EACL,cAAc,EACd,cAAc,EACd,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,YAAY,EACZ,iBAAiB,EACjB,aAAa,GAEd,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,SAAS,EAAwB,MAAM,gBAAgB,CAAC;AACjE,OAAO,EAAE,WAAW,EAA0B,MAAM,gBAAgB,CAAC;AAErE,OAAO,EAAE,SAAS,EAAwB,MAAM,gBAAgB,CAAC;AACjE,OAAO,EAAE,aAAa,EAA4B,MAAM,gBAAgB,CAAC;AAEzE,OAAO,EAAE,SAAS,EAAwB,MAAM,gBAAgB,CAAC;AACjE,OAAO,EAAE,SAAS,EAAwB,MAAM,gBAAgB,CAAC;AAEjE,OAAO,EACL,aAAa,EACb,eAAe,GAGhB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtD,OAAO,EACL,kBAAkB,EAClB,WAAW,GAEZ,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EACL,qBAAqB,GAGtB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,UAAU,EAAkB,MAAM,YAAY,CAAC"}
|