Sibilance Client
The Sibilance client is the core of the library. It manages voice survey sessions, survey state, and coordinates with the Sibilance platform.
Overview
The SibilanceClient class provides:
- 🎤 Session Management - Start/stop voice survey sessions
- 📊 Survey State - Track survey progress and collected information
- 📝 YAML Output - Generate structured data from conversations
- 🔄 Lifecycle Callbacks - Handle survey events (complete, pause, error)
- 🔐 Secure - Domain validation and encrypted API key storage
Basic Setup
typescript
import { SibilanceClient } from '@sibilance.is/client';
const client = new SibilanceClient({
surveyKey: 'sibilance_your_key_here',
}, {
onComplete: (yaml) => {
console.log('Survey completed!', yaml);
}
});Configuration
SibilanceConfig
The SibilanceClient constructor accepts a configuration object:
typescript
interface SibilanceConfig {
// Production mode: Fetch survey from backend
surveyKey?: string;
// Editor/test mode: Use provided survey config directly
survey?: SurveyConfig;
// Optional: Custom backend URL
backendUrl?: string;
// Optional: Auto-start voice session
autoStart?: boolean;
// Optional: Additional AI instructions
customInstructions?: string;
// Optional: Voice configuration
voiceConfig?: {
provider?: 'vowel-prime' | 'gemini' | 'openai';
model?: string;
voiceId?: string;
speakingRate?: number;
};
}Survey Configuration (Editor/Test Mode)
When using direct survey config (for testing):
typescript
const client = new SibilanceClient({
survey: {
markdown: `# My Survey\n## Start\nWelcome!`,
steps: [
{ id: 'start', script: 'Welcome!' }
],
mermaidDiagram: 'graph LR\n Start[Start]',
surveyName: 'Test Survey'
}
});Session Management
Starting a Session
typescript
// Start voice session
await client.connect();Stopping a Session
typescript
// Stop voice session
await client.disconnect();Toggling Session
typescript
// Toggle voice session
await client.toggleSession();Checking Session State
typescript
// Get current voice state
const voiceState = client.getVoiceState();
console.log(voiceState.isConnected); // Is session connected?
console.log(voiceState.isUserSpeaking); // Is user speaking?
console.log(voiceState.isAISpeaking); // Is AI speaking?
console.log(voiceState.isAIThinking); // Is AI thinking?Survey State
Getting Survey State
typescript
// Get current survey state
const surveyState = client.getSurveyState();
console.log(surveyState.isActive); // Is survey active?
console.log(surveyState.currentStepId); // Current step ID
console.log(surveyState.collectedInfo); // Collected information
console.log(surveyState.conversationLog); // Conversation history
console.log(surveyState.isComplete); // Is survey complete?Survey State Structure
typescript
interface SurveyState {
isActive: boolean;
currentStepId: string | null;
collectedInfo: CollectedInformation[];
conversationLog: ConversationLogEntry[];
yamlData: any[];
isComplete: boolean;
}
interface CollectedInformation {
field: string;
value: string;
sourceStep?: string;
timestamp: number;
}
interface ConversationLogEntry {
speaker: 'ai' | 'user';
message: string;
timestamp: number;
}Callbacks
onComplete
Called when survey is completed:
typescript
const client = new SibilanceClient({
surveyKey: 'sibilance_your_key_here'
}, {
onComplete: (yaml) => {
// yaml is an array of collected information
console.log('Survey completed!', yaml);
// Submit to your backend
fetch('/api/survey-results', {
method: 'POST',
body: JSON.stringify({ results: yaml })
});
}
});onRecordInformation
Called when information is collected:
typescript
const client = new SibilanceClient({
surveyKey: 'sibilance_your_key_here'
}, {
onRecordInformation: (info) => {
console.log('Recorded:', info.field, '=', info.value);
// info: { field: string, value: string, sourceStep?: string, timestamp: number }
}
});onLogConversation
Called for each conversation entry:
typescript
const client = new SibilanceClient({
surveyKey: 'sibilance_your_key_here'
}, {
onLogConversation: (speaker, message) => {
console.log(`${speaker}: ${message}`);
}
});onError
Called when an error occurs:
typescript
const client = new SibilanceClient({
surveyKey: 'sibilance_your_key_here'
}, {
onError: (error) => {
console.error('Survey error:', error);
// Handle error (show notification, retry, etc.)
}
});onStepChange
Called when survey step changes:
typescript
const client = new SibilanceClient({
surveyKey: 'sibilance_your_key_here'
}, {
onStepChange: (stepId) => {
console.log('Moved to step:', stepId);
}
});Survey Methods
Complete Survey
Manually complete the survey:
typescript
client.complete();Pause Survey
Pause the survey (mute mic/speaker but keep connection):
typescript
client.pause();Resume Survey
Resume a paused survey:
typescript
client.resume();Get YAML Output
Get collected information as YAML:
typescript
const yaml = client.getYAML();
console.log('Collected data:', yaml);Get Survey Config
Get the current survey configuration:
typescript
const config = client.getSurveyConfig();
console.log('Survey name:', config?.surveyName);
console.log('Steps:', config?.steps);State Subscription
Listen to voice state changes:
typescript
// Subscribe to voice state changes
const unsubscribe = client.onStateChange((state) => {
console.log('Voice state changed:', state);
if (state.isConnected) {
console.log('Session connected');
}
if (state.isUserSpeaking) {
console.log('User is speaking');
}
if (state.isAISpeaking) {
console.log('AI is speaking');
}
});
// Cleanup
unsubscribe();Complete Example
typescript
import { SibilanceClient } from '@sibilance.is/client';
// Create client
const client = new SibilanceClient({
surveyKey: 'sibilance_your_key_here',
autoStart: false
}, {
onComplete: async (yaml) => {
console.log('Survey completed!', yaml);
// Submit to backend
await fetch('/api/survey-results', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ results: yaml })
});
},
onRecordInformation: (info) => {
console.log(`Recorded ${info.field}: ${info.value}`);
},
onError: (error) => {
console.error('Error:', error);
},
onStepChange: (stepId) => {
console.log('Step changed to:', stepId);
}
});
// Subscribe to state changes
const unsubscribe = client.onStateChange((state) => {
console.log('Connection:', state.isConnected);
console.log('User speaking:', state.isUserSpeaking);
console.log('AI speaking:', state.isAISpeaking);
});
// Start session
await client.connect();
// Later: cleanup
await client.disconnect();
unsubscribe();Error Handling
Handle errors gracefully:
typescript
try {
await client.connect();
} catch (error) {
console.error('Failed to start session:', error);
if (error.message.includes('microphone')) {
alert('Please allow microphone access to use voice surveys.');
} else if (error.message.includes('survey')) {
alert('Survey not found. Please check your Survey Key.');
} else {
alert('Failed to start survey. Please try again.');
}
}
// Or use onError callback
const client = new SibilanceClient({
surveyKey: 'sibilance_your_key_here'
}, {
onError: (error) => {
console.error('Survey error:', error);
// Handle error
}
});Cleanup
Always cleanup when done:
typescript
// Stop session
await client.disconnect();
// Unsubscribe from state changes
unsubscribe();
// Destroy client (if needed)
client.destroy();Related
- Getting Started - Basic setup guide
- React Integration - React-specific patterns
- Survey State - Survey state management
- API Reference - Complete API documentation