wellnua-lite-Robert/services/livekitService.ts
Sergei 6d017ea617 WellNuo Lite Robert - Julia Robust Agent (no barge-in)
Changes:
- Updated livekitService.ts to use remote token server
- Julia-robust agent with disabled interruptions
- Added discard_audio_if_uninterruptible=True
- Added min_interruption_duration=2.0
- Token server configured for julia-robust agent
2026-01-24 15:22:21 -08:00

148 lines
4.2 KiB
TypeScript

/**
* LiveKit Voice AI Service
* Connects to LiveKit Cloud with Julia AI agent
* Uses dedicated Julia Token Server for token generation
*/
// Julia Token Server (dedicated endpoint for LiveKit tokens)
// Production: Use remote Julia Token Server
const JULIA_TOKEN_SERVER = 'https://wellnuo.smartlaunchhub.com/julia';
// Voice configuration
export const VOICE_ID = 'Asteria';
export const VOICE_NAME = 'Asteria';
// ============================================================================
// SINGLE_DEPLOYMENT_MODE
// When true: sends only deploymentId (no beneficiaryNamesDict)
// When false: sends both deploymentId AND beneficiaryNamesDict
//
// Use true for WellNuo Lite (single beneficiary per user)
// Use false for full WellNuo app (multiple beneficiaries)
// ============================================================================
export const SINGLE_DEPLOYMENT_MODE = true;
// Beneficiary data to pass to voice agent
export interface BeneficiaryData {
deploymentId: string;
beneficiaryNamesDict: Record<string, string>;
}
// API Response types
export interface LiveKitTokenResponse {
success: boolean;
data?: {
token: string;
roomName: string;
wsUrl: string;
};
error?: string;
}
/**
* Get a LiveKit access token from Julia Token Server
* No authentication required - token server is dedicated for voice AI
* @param userId - User identifier
* @param beneficiaryData - Optional beneficiary data to pass to voice agent
*/
export async function getToken(
userId: string,
beneficiaryData?: BeneficiaryData
): Promise<LiveKitTokenResponse> {
try {
console.log('[LiveKit] Getting token for user:', userId);
console.log('[LiveKit] SINGLE_DEPLOYMENT_MODE:', SINGLE_DEPLOYMENT_MODE);
// Prepare request body based on SINGLE_DEPLOYMENT_MODE
let requestBody: { userId: string; beneficiaryData?: BeneficiaryData };
if (SINGLE_DEPLOYMENT_MODE && beneficiaryData) {
// In single deployment mode: send only deploymentId, no beneficiaryNamesDict
requestBody = {
userId,
beneficiaryData: {
deploymentId: beneficiaryData.deploymentId,
beneficiaryNamesDict: {}, // Empty - no list of names
},
};
console.log('[LiveKit] Single deployment mode - sending only deploymentId:', beneficiaryData.deploymentId);
} else {
// Full mode: send everything
requestBody = { userId, beneficiaryData };
if (beneficiaryData) {
console.log('[LiveKit] Full mode - sending beneficiary data:', beneficiaryData);
}
}
// Request LiveKit token from Julia Token Server
const response = await fetch(`${JULIA_TOKEN_SERVER}/token`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(requestBody),
});
if (!response.ok) {
const errorData = await response.json().catch(() => ({}));
console.error('[LiveKit] Token request failed:', response.status, errorData);
return {
success: false,
error: errorData.error || `Failed to get token: ${response.status}`,
};
}
const data = await response.json();
if (!data.success) {
return {
success: false,
error: data.error || 'Token generation failed',
};
}
console.log('[LiveKit] Token received:', {
room: data.data.roomName,
identity: data.data.identity,
url: data.data.wsUrl,
});
return {
success: true,
data: {
token: data.data.token,
roomName: data.data.roomName,
wsUrl: data.data.wsUrl,
},
};
} catch (error) {
console.error('[LiveKit] Get token error:', error);
return {
success: false,
error: error instanceof Error ? error.message : 'Failed to get token',
};
}
}
/**
* Check if LiveKit service is available
*/
export async function checkServerHealth(): Promise<boolean> {
try {
const response = await fetch(`${JULIA_TOKEN_SERVER}/health`, {
method: 'GET',
});
if (response.ok) {
const data = await response.json();
console.log('[LiveKit] Health check:', data);
return data.status === 'ok';
}
return false;
} catch (error) {
console.error('[LiveKit] Health check failed:', error);
return false;
}
}