austack
Version:
TypeScript/JavaScript client SDK for Austack conversational AI
118 lines • 4.13 kB
JavaScript
import { AudioInterface } from './AudioInterface';
import { WebSocketManager } from './WebSocketManager';
export class ConversationManager {
constructor(websocketUrl, stateChangeCallback) {
this.isRunning = false;
this.state = {
isConnected: false,
isRecording: false,
isPlaying: false,
currentAmplitude: 0,
error: null,
};
this.websocketUrl = websocketUrl;
this.stateChangeCallback = stateChangeCallback;
// Create audio interface with callback to send audio data
this.audioInterface = new AudioInterface(
// @ts-ignore
this.onAudioInput.bind(this), this.onAmplitudeChange.bind(this), this.onInterrupt.bind(this));
// Create websocket manager
this.webSocketManager = new WebSocketManager(this.websocketUrl, this.audioInterface);
}
onAudioInput(audioData) {
this.webSocketManager.sendAudioData(audioData);
}
onAmplitudeChange(amplitude) {
this.updateState({ currentAmplitude: amplitude });
}
onInterrupt() {
console.log('Audio interrupt detected, sending interrupt signal');
this.webSocketManager.sendInterrupt();
}
updateState(updates) {
this.state = { ...this.state, ...updates };
if (this.stateChangeCallback) {
this.stateChangeCallback(this.state);
}
}
async startConversation() {
if (this.isRunning) {
console.warn('Conversation already running');
return;
}
try {
this.updateState({ error: null });
// Connect to WebSocket
console.log('Connecting to WebSocket...');
await this.webSocketManager.connect();
this.updateState({ isConnected: true });
// Start audio interface
console.log('Starting audio interface...');
await this.audioInterface.start();
this.updateState({ isRecording: true });
this.isRunning = true;
console.log('Conversation started successfully');
}
catch (error) {
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
console.error('Error starting conversation:', error);
this.updateState({
error: `Failed to start conversation: ${errorMessage}`,
isConnected: false,
isRecording: false
});
// Clean up on error
this.stopConversation();
throw error;
}
}
stopConversation() {
if (!this.isRunning) {
console.warn('Conversation not running');
return;
}
console.log('Stopping conversation...');
this.isRunning = false;
// Stop audio interface
this.audioInterface.stop();
// Disconnect WebSocket
this.webSocketManager.disconnect();
this.updateState({
isConnected: false,
isRecording: false,
isPlaying: false,
currentAmplitude: 0,
error: null
});
console.log('Conversation stopped');
}
sendMessage(message) {
if (!this.isRunning || !this.webSocketManager.isConnected()) {
console.warn('Cannot send message: conversation not active');
return;
}
this.webSocketManager.sendMessage(message);
}
cleanup() {
this.stopConversation();
this.audioInterface.cleanup();
}
getState() {
return { ...this.state };
}
isActive() {
return this.isRunning;
}
isConnected() {
return this.webSocketManager.isConnected();
}
// Utility method to update WebSocket URL
updateWebSocketUrl(newUrl) {
if (this.isRunning) {
throw new Error('Cannot update WebSocket URL while conversation is active');
}
this.websocketUrl = newUrl;
this.webSocketManager = new WebSocketManager(newUrl, this.audioInterface);
}
}
//# sourceMappingURL=ConversationManager.js.map