Sergei dde0ecb9cd Add Julia AI voice agent with LiveKit integration
Voice AI Features:
- LiveKit Agents integration for real-time voice calls
- Julia AI agent (Python) deployed to LiveKit Cloud
- Token server for authentication
- Debug screen with voice call testing
- Voice call screen with full-screen UI

Agent Configuration:
- STT: Deepgram Nova-2
- LLM: OpenAI GPT-4o
- TTS: Deepgram Aura Asteria (female voice)
- Turn Detection: LiveKit Multilingual Model
- VAD: Silero
- Noise Cancellation: LiveKit BVC

Files added:
- julia-agent/ - Complete agent code and token server
- app/voice-call.tsx - Full-screen voice call UI
- services/livekitService.ts - LiveKit client service
- contexts/VoiceTranscriptContext.tsx - Transcript state
- polyfills/livekit-globals.ts - WebRTC polyfills

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-17 17:58:31 -08:00

124 lines
5.3 KiB
JavaScript

/**
* Test Julia AI Agent Connection
* Creates a room and waits to see if agent joins
*/
const { RoomServiceClient } = require('livekit-server-sdk');
const LIVEKIT_API_KEY = 'APIEivUcPW3WSrV';
const LIVEKIT_API_SECRET = 'A65mc5KUKE0VGdZNaMRwe6uJpA9ZQPAxS66akZTOfmL';
const LIVEKIT_HTTP_URL = 'https://live-kit-demo-70txlh6a.livekit.cloud';
const AGENT_NAME = 'julia-ai';
async function testAgentConnection() {
const roomService = new RoomServiceClient(LIVEKIT_HTTP_URL, LIVEKIT_API_KEY, LIVEKIT_API_SECRET);
const roomName = 'julia-agent-test-' + Date.now();
console.log('╔════════════════════════════════════════════════════════════╗');
console.log('║ Julia AI Agent Connection Test ║');
console.log('╚════════════════════════════════════════════════════════════╝');
console.log('');
try {
// Step 1: Create room
console.log('Step 1: Creating room...');
const room = await roomService.createRoom({
name: roomName,
emptyTimeout: 300, // 5 minutes
maxParticipants: 10,
});
console.log(' ✅ Room created:', room.name);
console.log(' Room SID:', room.sid);
// Step 2: Check participants (agent should not be there yet - needs user to join)
console.log('\nStep 2: Checking initial participants...');
let participants = await roomService.listParticipants(roomName);
console.log(' Participants:', participants.length);
if (participants.length > 0) {
participants.forEach(p => {
console.log(` - ${p.identity} (${p.name || 'no name'})`);
});
}
// Step 3: Dispatch agent explicitly
console.log('\nStep 3: Dispatching Julia AI agent...');
try {
// Try to dispatch agent using createAgentDispatch if available
// Note: This requires agent to be deployed in LiveKit Cloud
const dispatch = await roomService.createAgentDispatch(roomName, AGENT_NAME, {
metadata: JSON.stringify({ role: 'assistant' }),
});
console.log(' ✅ Agent dispatch request sent');
console.log(' Dispatch ID:', dispatch.agentId || 'N/A');
} catch (dispatchError) {
console.log(' ⚠️ Agent dispatch method not available or agent not deployed');
console.log(' Error:', dispatchError.message);
console.log('');
console.log(' Note: Agent dispatch requires:');
console.log(' 1. Agent deployed in LiveKit Cloud');
console.log(' 2. Agent name matches: "' + AGENT_NAME + '"');
}
// Step 4: Wait and check for agent
console.log('\nStep 4: Waiting for agent to join (30 seconds)...');
let agentJoined = false;
for (let i = 0; i < 6; i++) {
await new Promise(resolve => setTimeout(resolve, 5000)); // Wait 5 seconds
console.log(` Checking... (${(i + 1) * 5}s)`);
participants = await roomService.listParticipants(roomName);
if (participants.length > 0) {
console.log(' Found participants:');
participants.forEach(p => {
const isAgent = p.identity.includes('agent') || p.identity.includes('julia');
console.log(` - ${p.identity} ${isAgent ? '🤖' : '👤'}`);
if (isAgent) agentJoined = true;
});
if (agentJoined) break;
}
}
// Step 5: Cleanup
console.log('\nStep 5: Cleanup...');
await roomService.deleteRoom(roomName);
console.log(' Room deleted');
// Summary
console.log('\n═══════════════════════════════════════════════════════════════');
console.log(' RESULT ');
console.log('═══════════════════════════════════════════════════════════════');
if (agentJoined) {
console.log(' ✅ Agent successfully joined the room!');
console.log(' Voice AI is ready for mobile app testing.');
} else {
console.log(' ⚠️ Agent did not join automatically.');
console.log('');
console.log(' This is NORMAL if:');
console.log(' - Agent requires a user to be in the room first');
console.log(' - Agent dispatch is triggered by token configuration');
console.log('');
console.log(' The token server includes agent config in the token.');
console.log(' When mobile app connects, agent should join automatically.');
console.log('');
console.log(' To verify agent is deployed, check:');
console.log(' https://cloud.livekit.io/projects');
}
console.log('═══════════════════════════════════════════════════════════════');
} catch (error) {
console.error('Test failed:', error);
// Cleanup on error
try {
await roomService.deleteRoom(roomName);
} catch (e) {
// Ignore cleanup errors
}
}
}
testAgentConnection();