diff --git a/src/app/(frontend)/api/gemini-token/route.ts b/src/app/(frontend)/api/gemini-token/route.ts index 46c4981..4a59a7e 100644 --- a/src/app/(frontend)/api/gemini-token/route.ts +++ b/src/app/(frontend)/api/gemini-token/route.ts @@ -4,7 +4,7 @@ import { generateEphemeralToken } from '@/lib/gemini-live'; // ─── Rate Limiting ──────────────────────────────────────────────────────────── const rateLimitMap = new Map(); -const RATE_LIMIT_MS = 30_000; // 1 token per 30 seconds per IP +const RATE_LIMIT_MS = 5_000; // 1 token per 5 seconds per IP // ─── Health Check (GET — no rate limit) ────────────────────────────────────── diff --git a/src/components/configurator/VoiceAgentProvider.tsx b/src/components/configurator/VoiceAgentProvider.tsx index 0890fbd..a72462b 100644 --- a/src/components/configurator/VoiceAgentProvider.tsx +++ b/src/components/configurator/VoiceAgentProvider.tsx @@ -274,10 +274,22 @@ export default function VoiceAgentProvider({ locale, children }: VoiceAgentProvi // Open WebSocket to Gemini Live API const wsUrl = `wss://generativelanguage.googleapis.com/ws/google.ai.generativelanguage.v1beta.GenerativeService.BidiGenerateContent?key=${apiKey}`; + console.log('[VoiceAgent] Connecting to WebSocket...'); const ws = new WebSocket(wsUrl); wsRef.current = ws; + // Timeout if setup doesn't complete within 10 seconds + const setupTimeout = setTimeout(() => { + if (ws.readyState !== WebSocket.CLOSED) { + console.error('[VoiceAgent] Setup timed out after 10s'); + ws.close(); + setStatus('error'); + setErrorMessage('Connection timed out. Please try again.'); + } + }, 10_000); + ws.onopen = () => { + console.log('[VoiceAgent] WebSocket opened, sending config...'); // Send setup message — must use "config" key per Gemini Live API spec ws.send(JSON.stringify({ config: { @@ -314,6 +326,7 @@ export default function VoiceAgentProvider({ locale, children }: VoiceAgentProvi // Setup complete — Gemini sends back a setupComplete message if (msg.setupComplete !== undefined) { console.log('[VoiceAgent] Setup complete, session active'); + clearTimeout(setupTimeout); setStatus('active'); trackAmplitude(); return;