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>
68 lines
1.8 KiB
JavaScript
68 lines
1.8 KiB
JavaScript
const express = require('express');
|
|
const cors = require('cors');
|
|
const { AccessToken } = require('livekit-server-sdk');
|
|
require('dotenv').config();
|
|
|
|
const app = express();
|
|
app.use(cors());
|
|
app.use(express.json());
|
|
|
|
const LIVEKIT_API_KEY = process.env.LIVEKIT_API_KEY || 'APIEivUcPW3WSrV';
|
|
const LIVEKIT_API_SECRET = process.env.LIVEKIT_API_SECRET || 'A65mc5KUKE0VGdZNaMRwe6uJpA9ZQPAxS66akZTOfmL';
|
|
const LIVEKIT_URL = 'wss://live-kit-demo-70txlh6a.livekit.cloud';
|
|
const AGENT_NAME = 'julia-ai';
|
|
|
|
// Health check
|
|
app.get('/health', (req, res) => {
|
|
res.json({ status: 'ok', agent: AGENT_NAME, url: LIVEKIT_URL });
|
|
});
|
|
|
|
// Generate LiveKit token
|
|
app.post('/token', async (req, res) => {
|
|
try {
|
|
const { userId } = req.body;
|
|
const identity = userId || `user-${Date.now()}`;
|
|
const roomName = `julia-room-${Date.now()}`;
|
|
|
|
const token = new AccessToken(LIVEKIT_API_KEY, LIVEKIT_API_SECRET, {
|
|
identity: identity,
|
|
ttl: 3600, // 1 hour
|
|
});
|
|
|
|
token.addGrant({
|
|
room: roomName,
|
|
roomJoin: true,
|
|
canPublish: true,
|
|
canSubscribe: true,
|
|
canPublishData: true,
|
|
});
|
|
|
|
// Request Julia AI agent to join the room
|
|
token.roomConfig = {
|
|
agents: [{ agentName: AGENT_NAME }],
|
|
};
|
|
|
|
const jwt = await token.toJwt();
|
|
|
|
res.json({
|
|
success: true,
|
|
data: {
|
|
token: jwt,
|
|
roomName: roomName,
|
|
wsUrl: LIVEKIT_URL,
|
|
identity: identity,
|
|
},
|
|
});
|
|
} catch (error) {
|
|
console.error('Token generation error:', error);
|
|
res.status(500).json({ success: false, error: error.message });
|
|
}
|
|
});
|
|
|
|
const PORT = process.env.PORT || 3001;
|
|
app.listen(PORT, () => {
|
|
console.log(`Julia Token Server running on port ${PORT}`);
|
|
console.log(`LiveKit URL: ${LIVEKIT_URL}`);
|
|
console.log(`Agent: ${AGENT_NAME}`);
|
|
});
|