modular-voice-agent-sdk 1.0.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 +102 -0
- package/USAGE.md +567 -0
- package/dist/backends/cloud/index.d.ts +7 -0
- package/dist/backends/cloud/index.d.ts.map +1 -0
- package/dist/backends/cloud/index.js +6 -0
- package/dist/backends/cloud/index.js.map +1 -0
- package/dist/backends/cloud/llm.d.ts +22 -0
- package/dist/backends/cloud/llm.d.ts.map +1 -0
- package/dist/backends/cloud/llm.js +234 -0
- package/dist/backends/cloud/llm.js.map +1 -0
- package/dist/backends/index.d.ts +2 -0
- package/dist/backends/index.d.ts.map +1 -0
- package/dist/backends/index.js +6 -0
- package/dist/backends/index.js.map +1 -0
- package/dist/backends/native/index.d.ts +5 -0
- package/dist/backends/native/index.d.ts.map +1 -0
- package/dist/backends/native/index.js +6 -0
- package/dist/backends/native/index.js.map +1 -0
- package/dist/backends/native/llm.d.ts +71 -0
- package/dist/backends/native/llm.d.ts.map +1 -0
- package/dist/backends/native/llm.js +435 -0
- package/dist/backends/native/llm.js.map +1 -0
- package/dist/backends/native/stt.d.ts +15 -0
- package/dist/backends/native/stt.d.ts.map +1 -0
- package/dist/backends/native/stt.js +94 -0
- package/dist/backends/native/stt.js.map +1 -0
- package/dist/backends/native/tts.d.ts +21 -0
- package/dist/backends/native/tts.d.ts.map +1 -0
- package/dist/backends/native/tts.js +105 -0
- package/dist/backends/native/tts.js.map +1 -0
- package/dist/backends/transformers/index.d.ts +4 -0
- package/dist/backends/transformers/index.d.ts.map +1 -0
- package/dist/backends/transformers/index.js +4 -0
- package/dist/backends/transformers/index.js.map +1 -0
- package/dist/backends/transformers/llm.d.ts +29 -0
- package/dist/backends/transformers/llm.d.ts.map +1 -0
- package/dist/backends/transformers/llm.js +117 -0
- package/dist/backends/transformers/llm.js.map +1 -0
- package/dist/backends/transformers/stt.d.ts +17 -0
- package/dist/backends/transformers/stt.d.ts.map +1 -0
- package/dist/backends/transformers/stt.js +43 -0
- package/dist/backends/transformers/stt.js.map +1 -0
- package/dist/backends/transformers/tts.d.ts +17 -0
- package/dist/backends/transformers/tts.d.ts.map +1 -0
- package/dist/backends/transformers/tts.js +40 -0
- package/dist/backends/transformers/tts.js.map +1 -0
- package/dist/cache.d.ts +37 -0
- package/dist/cache.d.ts.map +1 -0
- package/dist/cache.js +49 -0
- package/dist/cache.js.map +1 -0
- package/dist/cli.d.ts +11 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +392 -0
- package/dist/cli.js.map +1 -0
- package/dist/client/audio-player.d.ts +45 -0
- package/dist/client/audio-player.d.ts.map +1 -0
- package/dist/client/audio-player.js +90 -0
- package/dist/client/audio-player.js.map +1 -0
- package/dist/client/audio-recorder.d.ts +42 -0
- package/dist/client/audio-recorder.d.ts.map +1 -0
- package/dist/client/audio-recorder.js +128 -0
- package/dist/client/audio-recorder.js.map +1 -0
- package/dist/client/index.d.ts +34 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +33 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/protocol.d.ts +80 -0
- package/dist/client/protocol.d.ts.map +1 -0
- package/dist/client/protocol.js +29 -0
- package/dist/client/protocol.js.map +1 -0
- package/dist/client/voice-client.d.ts +249 -0
- package/dist/client/voice-client.d.ts.map +1 -0
- package/dist/client/voice-client.js +826 -0
- package/dist/client/voice-client.js.map +1 -0
- package/dist/client/web-speech-stt.d.ts +65 -0
- package/dist/client/web-speech-stt.d.ts.map +1 -0
- package/dist/client/web-speech-stt.js +122 -0
- package/dist/client/web-speech-stt.js.map +1 -0
- package/dist/client/web-speech-tts.d.ts +59 -0
- package/dist/client/web-speech-tts.d.ts.map +1 -0
- package/dist/client/web-speech-tts.js +145 -0
- package/dist/client/web-speech-tts.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/server/encoding.d.ts +18 -0
- package/dist/server/encoding.d.ts.map +1 -0
- package/dist/server/encoding.js +41 -0
- package/dist/server/encoding.js.map +1 -0
- package/dist/server/handler.d.ts +86 -0
- package/dist/server/handler.d.ts.map +1 -0
- package/dist/server/handler.js +224 -0
- package/dist/server/handler.js.map +1 -0
- package/dist/server/index.d.ts +31 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +32 -0
- package/dist/server/index.js.map +1 -0
- package/dist/services/function-service.d.ts +17 -0
- package/dist/services/function-service.d.ts.map +1 -0
- package/dist/services/function-service.js +82 -0
- package/dist/services/function-service.js.map +1 -0
- package/dist/services/index.d.ts +4 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +3 -0
- package/dist/services/index.js.map +1 -0
- package/dist/services/llm-logger.d.ts +136 -0
- package/dist/services/llm-logger.d.ts.map +1 -0
- package/dist/services/llm-logger.js +275 -0
- package/dist/services/llm-logger.js.map +1 -0
- package/dist/services/text-normalizer.d.ts +17 -0
- package/dist/services/text-normalizer.d.ts.map +1 -0
- package/dist/services/text-normalizer.js +100 -0
- package/dist/services/text-normalizer.js.map +1 -0
- package/dist/types.d.ts +195 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +48 -0
- package/dist/types.js.map +1 -0
- package/dist/voice-pipeline.d.ts +125 -0
- package/dist/voice-pipeline.d.ts.map +1 -0
- package/dist/voice-pipeline.js +390 -0
- package/dist/voice-pipeline.js.map +1 -0
- package/package.json +96 -0
- package/scripts/setup-binaries.sh +159 -0
- package/scripts/setup.sh +201 -0
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Audio Recorder
|
|
3
|
+
*
|
|
4
|
+
* Handles microphone capture with AudioWorklet for real-time PCM streaming.
|
|
5
|
+
*/
|
|
6
|
+
const PCM_WORKLET_CODE = `
|
|
7
|
+
class PCMProcessor extends AudioWorkletProcessor {
|
|
8
|
+
process(inputs) {
|
|
9
|
+
const input = inputs[0][0];
|
|
10
|
+
if (input) {
|
|
11
|
+
// Convert to Int16 for transmission efficiency
|
|
12
|
+
const int16 = new Int16Array(input.length);
|
|
13
|
+
for (let i = 0; i < input.length; i++) {
|
|
14
|
+
int16[i] = Math.max(-32768, Math.min(32767, input[i] * 32768));
|
|
15
|
+
}
|
|
16
|
+
this.port.postMessage(int16);
|
|
17
|
+
}
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
registerProcessor('pcm-processor', PCMProcessor);
|
|
22
|
+
`;
|
|
23
|
+
export class AudioRecorder {
|
|
24
|
+
sampleRate;
|
|
25
|
+
audioContext = null;
|
|
26
|
+
mediaStream = null;
|
|
27
|
+
mediaStreamSource = null;
|
|
28
|
+
workletNode = null;
|
|
29
|
+
workletRegistered = false;
|
|
30
|
+
isRecording = false;
|
|
31
|
+
onChunkCallback = null;
|
|
32
|
+
constructor(config = {}) {
|
|
33
|
+
this.sampleRate = config.sampleRate ?? 16000;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Check if currently recording
|
|
37
|
+
*/
|
|
38
|
+
get recording() {
|
|
39
|
+
return this.isRecording;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Set callback for audio chunks (called during streaming recording)
|
|
43
|
+
*/
|
|
44
|
+
onChunk(callback) {
|
|
45
|
+
this.onChunkCallback = callback;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Start recording from microphone
|
|
49
|
+
*/
|
|
50
|
+
async start() {
|
|
51
|
+
if (this.isRecording)
|
|
52
|
+
return;
|
|
53
|
+
this.isRecording = true;
|
|
54
|
+
// Create fresh AudioContext for each session
|
|
55
|
+
if (this.audioContext) {
|
|
56
|
+
await this.audioContext.close();
|
|
57
|
+
this.workletRegistered = false;
|
|
58
|
+
}
|
|
59
|
+
this.audioContext = new AudioContext({ sampleRate: this.sampleRate });
|
|
60
|
+
// Register worklet if needed
|
|
61
|
+
if (!this.workletRegistered) {
|
|
62
|
+
const blob = new Blob([PCM_WORKLET_CODE], { type: 'application/javascript' });
|
|
63
|
+
await this.audioContext.audioWorklet.addModule(URL.createObjectURL(blob));
|
|
64
|
+
this.workletRegistered = true;
|
|
65
|
+
}
|
|
66
|
+
// Get microphone stream
|
|
67
|
+
this.mediaStream = await navigator.mediaDevices.getUserMedia({
|
|
68
|
+
audio: {
|
|
69
|
+
sampleRate: this.sampleRate,
|
|
70
|
+
channelCount: 1,
|
|
71
|
+
echoCancellation: true,
|
|
72
|
+
noiseSuppression: true,
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
// Create audio graph
|
|
76
|
+
this.mediaStreamSource = this.audioContext.createMediaStreamSource(this.mediaStream);
|
|
77
|
+
this.workletNode = new AudioWorkletNode(this.audioContext, 'pcm-processor');
|
|
78
|
+
// Handle audio chunks
|
|
79
|
+
this.workletNode.port.onmessage = (e) => {
|
|
80
|
+
if (this.onChunkCallback) {
|
|
81
|
+
// Convert Int16 back to Float32
|
|
82
|
+
const float32 = new Float32Array(e.data.length);
|
|
83
|
+
for (let i = 0; i < e.data.length; i++) {
|
|
84
|
+
float32[i] = e.data[i] / 32768.0;
|
|
85
|
+
}
|
|
86
|
+
this.onChunkCallback(float32);
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
// Connect the graph
|
|
90
|
+
this.mediaStreamSource.connect(this.workletNode);
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Stop recording and clean up resources
|
|
94
|
+
*/
|
|
95
|
+
async stop() {
|
|
96
|
+
if (!this.isRecording)
|
|
97
|
+
return;
|
|
98
|
+
this.isRecording = false;
|
|
99
|
+
// Disconnect nodes
|
|
100
|
+
if (this.mediaStreamSource) {
|
|
101
|
+
this.mediaStreamSource.disconnect();
|
|
102
|
+
this.mediaStreamSource = null;
|
|
103
|
+
}
|
|
104
|
+
if (this.workletNode) {
|
|
105
|
+
this.workletNode.disconnect();
|
|
106
|
+
this.workletNode = null;
|
|
107
|
+
}
|
|
108
|
+
// Stop media tracks
|
|
109
|
+
if (this.mediaStream) {
|
|
110
|
+
this.mediaStream.getTracks().forEach((track) => track.stop());
|
|
111
|
+
this.mediaStream = null;
|
|
112
|
+
}
|
|
113
|
+
// Close audio context
|
|
114
|
+
if (this.audioContext) {
|
|
115
|
+
await this.audioContext.close();
|
|
116
|
+
this.audioContext = null;
|
|
117
|
+
this.workletRegistered = false;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Clean up all resources
|
|
122
|
+
*/
|
|
123
|
+
async dispose() {
|
|
124
|
+
await this.stop();
|
|
125
|
+
this.onChunkCallback = null;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=audio-recorder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audio-recorder.js","sourceRoot":"","sources":["../../src/client/audio-recorder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Modular Voice Agent SDK - Browser Client
|
|
3
|
+
*
|
|
4
|
+
* High-level SDK for building voice assistant browser clients.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```typescript
|
|
8
|
+
* import { VoiceClient } from 'modular-voice-agent-sdk/client';
|
|
9
|
+
*
|
|
10
|
+
* const client = new VoiceClient({ serverUrl: 'ws://localhost:8080' });
|
|
11
|
+
*
|
|
12
|
+
* client.on('transcript', (text) => console.log('User:', text));
|
|
13
|
+
* client.on('responseChunk', (chunk) => console.log('Assistant:', chunk));
|
|
14
|
+
* client.on('status', (status) => console.log('Status:', status));
|
|
15
|
+
*
|
|
16
|
+
* client.connect();
|
|
17
|
+
*
|
|
18
|
+
* // Push-to-talk
|
|
19
|
+
* button.onmousedown = () => client.startRecording();
|
|
20
|
+
* button.onmouseup = () => client.stopRecording();
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export { VoiceClient, createVoiceClient } from './voice-client';
|
|
24
|
+
export type { VoiceClientConfig, VoiceClientEvents, VoiceClientStatus, BrowserSupport } from './voice-client';
|
|
25
|
+
export { WebSpeechSTT } from './web-speech-stt';
|
|
26
|
+
export type { WebSpeechSTTConfig, WebSpeechSTTResult } from './web-speech-stt';
|
|
27
|
+
export { WebSpeechTTS } from './web-speech-tts';
|
|
28
|
+
export type { WebSpeechTTSConfig } from './web-speech-tts';
|
|
29
|
+
export { AudioRecorder } from './audio-recorder';
|
|
30
|
+
export type { AudioRecorderConfig, AudioChunkCallback } from './audio-recorder';
|
|
31
|
+
export { AudioPlayer } from './audio-player';
|
|
32
|
+
export type { AudioPlayerConfig } from './audio-player';
|
|
33
|
+
export { float32ToBase64, base64ToFloat32, type ClientMessage, type ServerMessage, type AudioMessage, type EndAudioMessage, type ClearHistoryMessage, type TextMessage, type TranscriptMessage, type ResponseChunkMessage, type AudioResponseMessage, type CompleteMessage, type ErrorMessage, } from './protocol';
|
|
34
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAGH,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAChE,YAAY,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAG9G,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,YAAY,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAE/E,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,YAAY,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAG3D,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,YAAY,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAEhF,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAGxD,OAAO,EACL,eAAe,EACf,eAAe,EACf,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACxB,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EACzB,KAAK,eAAe,EACpB,KAAK,YAAY,GAClB,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Modular Voice Agent SDK - Browser Client
|
|
3
|
+
*
|
|
4
|
+
* High-level SDK for building voice assistant browser clients.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```typescript
|
|
8
|
+
* import { VoiceClient } from 'modular-voice-agent-sdk/client';
|
|
9
|
+
*
|
|
10
|
+
* const client = new VoiceClient({ serverUrl: 'ws://localhost:8080' });
|
|
11
|
+
*
|
|
12
|
+
* client.on('transcript', (text) => console.log('User:', text));
|
|
13
|
+
* client.on('responseChunk', (chunk) => console.log('Assistant:', chunk));
|
|
14
|
+
* client.on('status', (status) => console.log('Status:', status));
|
|
15
|
+
*
|
|
16
|
+
* client.connect();
|
|
17
|
+
*
|
|
18
|
+
* // Push-to-talk
|
|
19
|
+
* button.onmousedown = () => client.startRecording();
|
|
20
|
+
* button.onmouseup = () => client.stopRecording();
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
// Main SDK
|
|
24
|
+
export { VoiceClient, createVoiceClient } from './voice-client';
|
|
25
|
+
// Browser speech APIs (for local STT/TTS)
|
|
26
|
+
export { WebSpeechSTT } from './web-speech-stt';
|
|
27
|
+
export { WebSpeechTTS } from './web-speech-tts';
|
|
28
|
+
// Lower-level utilities (for custom implementations)
|
|
29
|
+
export { AudioRecorder } from './audio-recorder';
|
|
30
|
+
export { AudioPlayer } from './audio-player';
|
|
31
|
+
// Protocol types and utilities
|
|
32
|
+
export { float32ToBase64, base64ToFloat32, } from './protocol';
|
|
33
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,WAAW;AACX,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAGhE,0CAA0C;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAGhD,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAGhD,qDAAqD;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGjD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAG7C,+BAA+B;AAC/B,OAAO,EACL,eAAe,EACf,eAAe,GAYhB,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebSocket Protocol Types for Voice Pipeline
|
|
3
|
+
*
|
|
4
|
+
* Shared types for client-server communication.
|
|
5
|
+
*/
|
|
6
|
+
export type AudioMessage = {
|
|
7
|
+
type: 'audio';
|
|
8
|
+
data: string;
|
|
9
|
+
sampleRate: number;
|
|
10
|
+
};
|
|
11
|
+
export type EndAudioMessage = {
|
|
12
|
+
type: 'end_audio';
|
|
13
|
+
};
|
|
14
|
+
export type ClearHistoryMessage = {
|
|
15
|
+
type: 'clear_history';
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Text message - sent when client does STT locally
|
|
19
|
+
* Server skips STT and goes straight to LLM
|
|
20
|
+
*/
|
|
21
|
+
export type TextMessage = {
|
|
22
|
+
type: 'text';
|
|
23
|
+
text: string;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Capabilities message - sent on connect to tell server what client handles
|
|
27
|
+
*/
|
|
28
|
+
export type CapabilitiesMessage = {
|
|
29
|
+
type: 'capabilities';
|
|
30
|
+
hasSTT: boolean;
|
|
31
|
+
hasTTS: boolean;
|
|
32
|
+
};
|
|
33
|
+
export type ClientMessage = AudioMessage | EndAudioMessage | ClearHistoryMessage | TextMessage | CapabilitiesMessage;
|
|
34
|
+
export type TranscriptMessage = {
|
|
35
|
+
type: 'transcript';
|
|
36
|
+
text: string;
|
|
37
|
+
};
|
|
38
|
+
export type ResponseChunkMessage = {
|
|
39
|
+
type: 'response_chunk';
|
|
40
|
+
text: string;
|
|
41
|
+
};
|
|
42
|
+
export type AudioResponseMessage = {
|
|
43
|
+
type: 'audio';
|
|
44
|
+
data: string;
|
|
45
|
+
sampleRate: number;
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Sent when a tool call is being executed
|
|
49
|
+
*/
|
|
50
|
+
export type ToolCallMessage = {
|
|
51
|
+
type: 'tool_call';
|
|
52
|
+
toolCallId: string;
|
|
53
|
+
name: string;
|
|
54
|
+
arguments: Record<string, unknown>;
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Sent when a tool call completes
|
|
58
|
+
*/
|
|
59
|
+
export type ToolResultMessage = {
|
|
60
|
+
type: 'tool_result';
|
|
61
|
+
toolCallId: string;
|
|
62
|
+
result: unknown;
|
|
63
|
+
};
|
|
64
|
+
export type CompleteMessage = {
|
|
65
|
+
type: 'complete';
|
|
66
|
+
};
|
|
67
|
+
export type ErrorMessage = {
|
|
68
|
+
type: 'error';
|
|
69
|
+
message: string;
|
|
70
|
+
};
|
|
71
|
+
export type ServerMessage = TranscriptMessage | ResponseChunkMessage | AudioResponseMessage | ToolCallMessage | ToolResultMessage | CompleteMessage | ErrorMessage;
|
|
72
|
+
/**
|
|
73
|
+
* Encode Float32Array to base64 string
|
|
74
|
+
*/
|
|
75
|
+
export declare function float32ToBase64(audio: Float32Array): string;
|
|
76
|
+
/**
|
|
77
|
+
* Decode base64 string to Float32Array
|
|
78
|
+
*/
|
|
79
|
+
export declare function base64ToFloat32(data: string): Float32Array;
|
|
80
|
+
//# sourceMappingURL=protocol.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/client/protocol.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,WAAW,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,EAAE,eAAe,CAAC;CACvB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,EAAE,cAAc,CAAC;IACrB,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,YAAY,GAAG,eAAe,GAAG,mBAAmB,GAAG,WAAW,GAAG,mBAAmB,CAAC;AAIrH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,YAAY,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,IAAI,EAAE,gBAAgB,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,WAAW,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,aAAa,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,UAAU,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,aAAa,GACrB,iBAAiB,GACjB,oBAAoB,GACpB,oBAAoB,GACpB,eAAe,GACf,iBAAiB,GACjB,eAAe,GACf,YAAY,CAAC;AAIjB;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,CAO3D;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CAO1D"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebSocket Protocol Types for Voice Pipeline
|
|
3
|
+
*
|
|
4
|
+
* Shared types for client-server communication.
|
|
5
|
+
*/
|
|
6
|
+
// ============ Encoding Utilities ============
|
|
7
|
+
/**
|
|
8
|
+
* Encode Float32Array to base64 string
|
|
9
|
+
*/
|
|
10
|
+
export function float32ToBase64(audio) {
|
|
11
|
+
const bytes = new Uint8Array(audio.buffer, audio.byteOffset, audio.byteLength);
|
|
12
|
+
let binary = '';
|
|
13
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
14
|
+
binary += String.fromCharCode(bytes[i]);
|
|
15
|
+
}
|
|
16
|
+
return btoa(binary);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Decode base64 string to Float32Array
|
|
20
|
+
*/
|
|
21
|
+
export function base64ToFloat32(data) {
|
|
22
|
+
const binary = atob(data);
|
|
23
|
+
const bytes = new Uint8Array(binary.length);
|
|
24
|
+
for (let i = 0; i < binary.length; i++) {
|
|
25
|
+
bytes[i] = binary.charCodeAt(i);
|
|
26
|
+
}
|
|
27
|
+
return new Float32Array(bytes.buffer);
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=protocol.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../src/client/protocol.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AA6FH,+CAA+C;AAE/C;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,KAAmB;IACjD,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;IAC/E,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,IAAI,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1C,CAAC;IACD,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC;AACtB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACvC,KAAK,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IAClC,CAAC;IACD,OAAO,IAAI,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;AACxC,CAAC"}
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Voice Client
|
|
3
|
+
*
|
|
4
|
+
* Unified browser SDK for voice assistants.
|
|
5
|
+
* Handles three modes:
|
|
6
|
+
* 1. Fully local - all components run in browser, no server needed
|
|
7
|
+
* 2. Fully remote - all processing on server via WebSocket
|
|
8
|
+
* 3. Hybrid - mix of local and server components
|
|
9
|
+
*
|
|
10
|
+
* Component logic:
|
|
11
|
+
* - Component provided → runs locally
|
|
12
|
+
* - Component is null + serverUrl → server handles it
|
|
13
|
+
* - All components local → no WebSocket needed
|
|
14
|
+
*/
|
|
15
|
+
import type { STTPipeline, LLMPipeline, TTSPipeline } from '../types';
|
|
16
|
+
import { WebSpeechSTT } from './web-speech-stt';
|
|
17
|
+
import { WebSpeechTTS } from './web-speech-tts';
|
|
18
|
+
export interface BrowserSupport {
|
|
19
|
+
/** Web Speech API speech recognition (Chrome, Edge, Safari only) */
|
|
20
|
+
webSpeechSTT: boolean;
|
|
21
|
+
/** Web Speech API speech synthesis (most browsers) */
|
|
22
|
+
webSpeechTTS: boolean;
|
|
23
|
+
/** WebGPU for ML acceleration (Chrome, Edge) */
|
|
24
|
+
webGPU: boolean;
|
|
25
|
+
/** MediaDevices API for microphone access */
|
|
26
|
+
mediaDevices: boolean;
|
|
27
|
+
/** WebSocket support */
|
|
28
|
+
webSocket: boolean;
|
|
29
|
+
/** AudioContext for audio processing */
|
|
30
|
+
audioContext: boolean;
|
|
31
|
+
}
|
|
32
|
+
export type VoiceClientStatus = 'disconnected' | 'connecting' | 'initializing' | 'ready' | 'listening' | 'processing' | 'speaking';
|
|
33
|
+
export interface VoiceClientConfig {
|
|
34
|
+
/**
|
|
35
|
+
* STT backend - runs locally in browser
|
|
36
|
+
* - Provide an STTPipeline (e.g., TransformersSTT) or WebSpeechSTT for local STT
|
|
37
|
+
* - Set to null to use server-side STT (requires serverUrl)
|
|
38
|
+
* @default null (server handles)
|
|
39
|
+
*/
|
|
40
|
+
stt?: STTPipeline | WebSpeechSTT | null;
|
|
41
|
+
/**
|
|
42
|
+
* LLM backend - runs locally in browser
|
|
43
|
+
* - Provide an LLMPipeline (e.g., TransformersLLM) for local LLM
|
|
44
|
+
* - Set to null to use server-side LLM (requires serverUrl)
|
|
45
|
+
* @default null (server handles)
|
|
46
|
+
*/
|
|
47
|
+
llm?: LLMPipeline | null;
|
|
48
|
+
/**
|
|
49
|
+
* TTS backend - runs locally in browser
|
|
50
|
+
* - Provide a TTSPipeline (e.g., TransformersTTS) or WebSpeechTTS for local TTS
|
|
51
|
+
* - Set to null to use server-side TTS (requires serverUrl)
|
|
52
|
+
* @default null (server handles)
|
|
53
|
+
*/
|
|
54
|
+
tts?: TTSPipeline | WebSpeechTTS | null;
|
|
55
|
+
/**
|
|
56
|
+
* System prompt for the LLM (required if llm is provided)
|
|
57
|
+
*/
|
|
58
|
+
systemPrompt?: string;
|
|
59
|
+
/**
|
|
60
|
+
* WebSocket server URL (required if any component is null)
|
|
61
|
+
*/
|
|
62
|
+
serverUrl?: string;
|
|
63
|
+
/**
|
|
64
|
+
* Audio sample rate for recording (default: 16000)
|
|
65
|
+
*/
|
|
66
|
+
sampleRate?: number;
|
|
67
|
+
/**
|
|
68
|
+
* Auto-reconnect on disconnect - only applies when using server (default: true)
|
|
69
|
+
*/
|
|
70
|
+
autoReconnect?: boolean;
|
|
71
|
+
/**
|
|
72
|
+
* Reconnect delay in ms (default: 2000)
|
|
73
|
+
*/
|
|
74
|
+
reconnectDelay?: number;
|
|
75
|
+
}
|
|
76
|
+
export interface ToolCallInfo {
|
|
77
|
+
id: string;
|
|
78
|
+
name: string;
|
|
79
|
+
arguments: Record<string, unknown>;
|
|
80
|
+
}
|
|
81
|
+
export interface VoiceClientEvents {
|
|
82
|
+
/** Connection/initialization status changed */
|
|
83
|
+
status: (status: VoiceClientStatus) => void;
|
|
84
|
+
/** User transcript received (from STT) */
|
|
85
|
+
transcript: (text: string) => void;
|
|
86
|
+
/** Assistant response chunk (streaming) */
|
|
87
|
+
responseChunk: (text: string) => void;
|
|
88
|
+
/** Full response complete */
|
|
89
|
+
responseComplete: (fullText: string) => void;
|
|
90
|
+
/** Tool call started (function calling) */
|
|
91
|
+
toolCall: (toolCall: ToolCallInfo) => void;
|
|
92
|
+
/** Tool call result received */
|
|
93
|
+
toolResult: (toolCallId: string, result: unknown) => void;
|
|
94
|
+
/** Error occurred */
|
|
95
|
+
error: (error: Error) => void;
|
|
96
|
+
/** Model loading progress (for local models) */
|
|
97
|
+
progress: (info: {
|
|
98
|
+
status: string;
|
|
99
|
+
file?: string;
|
|
100
|
+
progress?: number;
|
|
101
|
+
}) => void;
|
|
102
|
+
}
|
|
103
|
+
type EventName = keyof VoiceClientEvents;
|
|
104
|
+
export declare class VoiceClient {
|
|
105
|
+
/**
|
|
106
|
+
* Check browser support for voice features.
|
|
107
|
+
* Call this before creating a VoiceClient to determine what's available.
|
|
108
|
+
*
|
|
109
|
+
* @example
|
|
110
|
+
* const support = VoiceClient.getBrowserSupport();
|
|
111
|
+
* if (!support.webSpeechSTT) {
|
|
112
|
+
* showMessage("Voice input requires Chrome, Edge, or Safari");
|
|
113
|
+
* }
|
|
114
|
+
*/
|
|
115
|
+
static getBrowserSupport(): BrowserSupport;
|
|
116
|
+
/**
|
|
117
|
+
* Get a human-readable description of what's not supported.
|
|
118
|
+
* Returns null if everything needed for basic operation is supported.
|
|
119
|
+
*/
|
|
120
|
+
static getUnsupportedFeatures(): string[];
|
|
121
|
+
private config;
|
|
122
|
+
private mode;
|
|
123
|
+
private needsServer;
|
|
124
|
+
private localSTT;
|
|
125
|
+
private localLLM;
|
|
126
|
+
private localTTS;
|
|
127
|
+
private localPipeline;
|
|
128
|
+
private ws;
|
|
129
|
+
private recorder;
|
|
130
|
+
private player;
|
|
131
|
+
private status;
|
|
132
|
+
private listeners;
|
|
133
|
+
private currentResponse;
|
|
134
|
+
private reconnectTimer;
|
|
135
|
+
private pendingTTSText;
|
|
136
|
+
private ttsQueue;
|
|
137
|
+
private isSpeaking;
|
|
138
|
+
private conversationId;
|
|
139
|
+
private history;
|
|
140
|
+
private audioContext;
|
|
141
|
+
private mediaRecorder;
|
|
142
|
+
private audioChunks;
|
|
143
|
+
private mediaRecording;
|
|
144
|
+
private generateConversationId;
|
|
145
|
+
constructor(config: VoiceClientConfig);
|
|
146
|
+
private setupComponents;
|
|
147
|
+
private setupWebSpeechSTT;
|
|
148
|
+
/**
|
|
149
|
+
* Initialize and connect (if using server)
|
|
150
|
+
*/
|
|
151
|
+
connect(): Promise<void>;
|
|
152
|
+
private initializeLocalComponents;
|
|
153
|
+
private connectWebSocket;
|
|
154
|
+
/**
|
|
155
|
+
* Disconnect and clean up
|
|
156
|
+
*/
|
|
157
|
+
disconnect(): void;
|
|
158
|
+
/**
|
|
159
|
+
* Start recording/listening
|
|
160
|
+
*/
|
|
161
|
+
startRecording(): Promise<void>;
|
|
162
|
+
/**
|
|
163
|
+
* Stop recording/listening and process
|
|
164
|
+
*/
|
|
165
|
+
stopRecording(): Promise<void>;
|
|
166
|
+
private startMediaRecorder;
|
|
167
|
+
private stopMediaRecorder;
|
|
168
|
+
private processLocalAudio;
|
|
169
|
+
private processTextLocally;
|
|
170
|
+
private runLocalPipeline;
|
|
171
|
+
private runLocalLLM;
|
|
172
|
+
/**
|
|
173
|
+
* Clear conversation history
|
|
174
|
+
*/
|
|
175
|
+
clearHistory(): void;
|
|
176
|
+
/**
|
|
177
|
+
* Get current status
|
|
178
|
+
*/
|
|
179
|
+
getStatus(): VoiceClientStatus;
|
|
180
|
+
/**
|
|
181
|
+
* Check if ready for interaction
|
|
182
|
+
*/
|
|
183
|
+
isReady(): boolean;
|
|
184
|
+
/**
|
|
185
|
+
* Check if currently recording
|
|
186
|
+
*/
|
|
187
|
+
isRecording(): boolean;
|
|
188
|
+
/**
|
|
189
|
+
* Get current mode
|
|
190
|
+
*/
|
|
191
|
+
getMode(): 'local' | 'remote' | 'hybrid';
|
|
192
|
+
/**
|
|
193
|
+
* Check which components are local
|
|
194
|
+
*/
|
|
195
|
+
getLocalComponents(): {
|
|
196
|
+
stt: boolean;
|
|
197
|
+
llm: boolean;
|
|
198
|
+
tts: boolean;
|
|
199
|
+
};
|
|
200
|
+
/**
|
|
201
|
+
* Subscribe to events
|
|
202
|
+
*/
|
|
203
|
+
on<K extends EventName>(event: K, callback: VoiceClientEvents[K]): void;
|
|
204
|
+
/**
|
|
205
|
+
* Unsubscribe from events
|
|
206
|
+
*/
|
|
207
|
+
off<K extends EventName>(event: K, callback: VoiceClientEvents[K]): void;
|
|
208
|
+
/**
|
|
209
|
+
* Clean up all resources
|
|
210
|
+
*/
|
|
211
|
+
dispose(): Promise<void>;
|
|
212
|
+
private send;
|
|
213
|
+
private handleServerMessage;
|
|
214
|
+
private handleLocalTTSChunk;
|
|
215
|
+
private flushLocalTTS;
|
|
216
|
+
private processLocalTTSQueue;
|
|
217
|
+
private setStatus;
|
|
218
|
+
private emit;
|
|
219
|
+
private scheduleReconnect;
|
|
220
|
+
private validateBrowserSupport;
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Create a VoiceClient instance
|
|
224
|
+
* @example
|
|
225
|
+
* // Fully local
|
|
226
|
+
* const client = createVoiceClient({
|
|
227
|
+
* stt: new TransformersSTT({ model: '...' }),
|
|
228
|
+
* llm: new TransformersLLM({ model: '...' }),
|
|
229
|
+
* tts: new WebSpeechTTS(),
|
|
230
|
+
* systemPrompt: 'You are a helpful assistant.',
|
|
231
|
+
* });
|
|
232
|
+
*
|
|
233
|
+
* @example
|
|
234
|
+
* // Fully remote
|
|
235
|
+
* const client = createVoiceClient({
|
|
236
|
+
* serverUrl: 'ws://localhost:3000',
|
|
237
|
+
* });
|
|
238
|
+
*
|
|
239
|
+
* @example
|
|
240
|
+
* // Hybrid: local STT/TTS, server LLM
|
|
241
|
+
* const client = createVoiceClient({
|
|
242
|
+
* stt: new WebSpeechSTT(),
|
|
243
|
+
* tts: new WebSpeechTTS(),
|
|
244
|
+
* serverUrl: 'ws://localhost:3000',
|
|
245
|
+
* });
|
|
246
|
+
*/
|
|
247
|
+
export declare function createVoiceClient(config: VoiceClientConfig): VoiceClient;
|
|
248
|
+
export {};
|
|
249
|
+
//# sourceMappingURL=voice-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"voice-client.d.ts","sourceRoot":"","sources":["../../src/client/voice-client.ts"],"names":[],"mappings":"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"}
|