@glydeunity/voice-sdk 1.3.6 → 1.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/glyde-chat.umd.js +271 -0
- package/dist/glyde-chat.umd.js.map +1 -0
- package/dist/index.d.ts +857 -16
- package/dist/voice-sdk.es.js +1784 -75
- package/dist/voice-sdk.es.js.map +1 -0
- package/package.json +28 -7
- package/dist/voice-sdk.umd.js +0 -140
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"voice-sdk.es.js","sources":["../src/GlydeVoice.ts","../src/core/GlydeText.ts","../src/hooks/useVoiceAgent.ts","../src/hooks/useTextChat.ts","../src/ui/icons.tsx","../src/ui/styles.ts","../src/components/VoiceChat.tsx","../src/components/TextChat.tsx","../src/components/ChatWidget.tsx","../src/cdn/auto-init.ts"],"sourcesContent":["/**\n * GlydeVoice SDK - Voice Agent Client for GLYDE Unity\n * \n * Provides voice interaction capabilities with GLYDE AI agents through Deepgram Voice API.\n * Supports multiple authentication methods: publishableKey, apiKey, and JWT token.\n * \n * @example\n * // Using publishable key (external apps)\n * const voice = new GlydeVoice({\n * publishableKey: 'pk_...',\n * contextType: 'screening',\n * contextId: 'application-uuid'\n * });\n * \n * @example\n * // Using JWT token (GLYDEBuddy Teams app)\n * const voice = new GlydeVoice({\n * authToken: userSession.accessToken,\n * contextType: 'recruiter'\n * });\n */\n\n/**\n * Inline AudioWorklet processor code for capturing microphone audio.\n * Converts Float32 samples to Int16 (linear16) PCM for Deepgram.\n * Inlined as a string to be loaded via blob URL, avoiding CORS issues.\n */\nconst AUDIO_CAPTURE_PROCESSOR_CODE = `\nclass AudioCaptureProcessor extends AudioWorkletProcessor {\n constructor() {\n super();\n this.bufferSize = 4096;\n this.buffer = new Float32Array(this.bufferSize);\n this.bufferIndex = 0;\n }\n\n process(inputs) {\n const input = inputs[0];\n if (!input || !input[0]) return true;\n\n const samples = input[0];\n \n for (let i = 0; i < samples.length; i++) {\n this.buffer[this.bufferIndex++] = samples[i];\n \n if (this.bufferIndex >= this.bufferSize) {\n const pcm16 = new Int16Array(this.bufferSize);\n for (let j = 0; j < this.bufferSize; j++) {\n const s = Math.max(-1, Math.min(1, this.buffer[j]));\n pcm16[j] = s < 0 ? s * 0x8000 : s * 0x7FFF;\n }\n \n this.port.postMessage(pcm16.buffer, [pcm16.buffer]);\n this.bufferIndex = 0;\n }\n }\n\n return true;\n }\n}\n\nregisterProcessor('audio-capture-processor', AudioCaptureProcessor);\n`;\n\n/**\n * Inline AudioWorklet processor code for real-time audio playback.\n * Maintains a ring buffer for continuous streaming with instant clear capability.\n * Inlined as a string to be loaded via blob URL, avoiding CORS issues.\n */\nconst AUDIO_PLAYBACK_PROCESSOR_CODE = `\nclass AudioPlaybackProcessor extends AudioWorkletProcessor {\n constructor() {\n super();\n \n this.bufferSize = 48000 * 15;\n this.buffer = new Float32Array(this.bufferSize);\n this.writeIndex = 0;\n this.readIndex = 0;\n this.samplesAvailable = 0;\n this.isPlaying = false;\n \n this.port.onmessage = (event) => {\n const { type, data } = event.data;\n \n switch (type) {\n case 'audio':\n const audioData = data instanceof Float32Array ? data : new Float32Array(data);\n this.writeAudio(audioData);\n break;\n case 'clear':\n this.clearBuffer();\n break;\n }\n };\n }\n\n writeAudio(samples) {\n if (!samples || samples.length === 0) return;\n \n const samplesToWrite = samples.length;\n \n if (this.samplesAvailable + samplesToWrite > this.bufferSize) {\n const overflow = (this.samplesAvailable + samplesToWrite) - this.bufferSize;\n this.readIndex = (this.readIndex + overflow) % this.bufferSize;\n this.samplesAvailable -= overflow;\n }\n \n for (let i = 0; i < samplesToWrite; i++) {\n this.buffer[this.writeIndex] = samples[i];\n this.writeIndex = (this.writeIndex + 1) % this.bufferSize;\n }\n \n this.samplesAvailable += samplesToWrite;\n this.isPlaying = true;\n }\n\n clearBuffer() {\n this.readIndex = 0;\n this.writeIndex = 0;\n this.samplesAvailable = 0;\n this.isPlaying = false;\n this.port.postMessage({ type: 'cleared' });\n }\n\n process(inputs, outputs) {\n const output = outputs[0];\n if (!output || !output[0]) return true;\n \n const outputChannel = output[0];\n const samplesToRead = outputChannel.length;\n \n if (this.samplesAvailable >= samplesToRead) {\n for (let i = 0; i < samplesToRead; i++) {\n outputChannel[i] = this.buffer[this.readIndex];\n this.readIndex = (this.readIndex + 1) % this.bufferSize;\n }\n this.samplesAvailable -= samplesToRead;\n } else if (this.samplesAvailable > 0) {\n let i = 0;\n while (this.samplesAvailable > 0 && i < samplesToRead) {\n outputChannel[i] = this.buffer[this.readIndex];\n this.readIndex = (this.readIndex + 1) % this.bufferSize;\n this.samplesAvailable--;\n i++;\n }\n while (i < samplesToRead) {\n outputChannel[i] = 0;\n i++;\n }\n \n if (this.isPlaying) {\n this.isPlaying = false;\n this.port.postMessage({ type: 'bufferEmpty' });\n }\n } else {\n for (let i = 0; i < samplesToRead; i++) {\n outputChannel[i] = 0;\n }\n this.isPlaying = false;\n }\n \n return true;\n }\n}\n\nregisterProcessor('audio-playback-processor', AudioPlaybackProcessor);\n`;\n\n/**\n * Voice context types supported by the voice agent\n */\nexport type VoiceContextType = 'screening' | 'recruiter' | 'custom' | 'phone';\n\n/**\n * Voice events emitted by the agent\n */\nexport interface VoiceEvent {\n type: 'open' | 'close' | 'error' | 'ready' | 'user_speaking' | 'agent_speaking' | 'microphone_ready' | 'transcript' | 'agent_audio';\n payload?: unknown;\n}\n\n/**\n * Deepgram agent configuration for LLM and voice settings\n */\nexport interface DeepgramAgentConfig {\n tags?: string[];\n think?: {\n provider?: {\n type: string;\n model?: string;\n };\n functions?: Array<{\n name: string;\n description: string;\n parameters: unknown;\n endpoint?: {\n url: string;\n method?: string;\n headers?: Record<string, string>;\n };\n }>;\n };\n speak?: {\n provider?: {\n type: string;\n model?: string;\n };\n };\n listen?: {\n provider?: {\n type: string;\n model?: string;\n version?: string;\n };\n };\n}\n\n/**\n * MCP Tool definition for voice agent\n */\nexport interface MCPTool {\n name: string;\n description: string;\n inputSchema?: unknown;\n}\n\n/**\n * Function call request from Deepgram Voice Agent\n * @see https://developers.deepgram.com/docs/voice-agent-function-call-request\n */\n/**\n * Individual function call within a FunctionCallRequest\n * @see https://developers.deepgram.com/docs/voice-agent-function-call-request\n */\nexport interface FunctionCall {\n /** Unique identifier for the function call */\n id: string;\n /** Name of the function to execute */\n name: string;\n /** JSON string containing function arguments */\n arguments: string;\n /** If true, client must execute and respond; if false, server handles it */\n client_side?: boolean;\n}\n\n/**\n * Function call request message from Deepgram Voice Agent\n * Contains an array of functions to be executed\n * @see https://developers.deepgram.com/docs/voice-agent-function-call-request\n */\nexport interface FunctionCallRequest {\n type: 'FunctionCallRequest';\n /** Array of function calls to execute */\n functions: FunctionCall[];\n}\n\n/**\n * Function call response to send back to Deepgram\n * @see https://developers.deepgram.com/docs/voice-agent-function-call-response\n */\n/**\n * Function call response to send back to Deepgram Voice Agent\n * @see https://developers.deepgram.com/docs/voice-agent-function-call-response\n */\nexport interface FunctionCallResponse {\n type: 'FunctionCallResponse';\n /** Unique identifier of the original function call */\n id: string;\n /** Name of the function that was executed */\n name: string;\n /** Text summary or JSON result of the function's output */\n content: string;\n}\n\n/**\n * Job opportunity result from search\n */\nexport interface JobOpportunity {\n job_uuid: string;\n title: string;\n location?: string;\n department?: string;\n salary_range?: string;\n employment_type?: string;\n description_snippet?: string;\n match_score?: number;\n}\n\n/**\n * Voice configuration response from Unity API\n */\nexport interface VoiceConfig {\n system_prompt: string;\n available_tools: MCPTool[];\n deepgram_config: DeepgramAgentConfig;\n context: {\n type: VoiceContextType;\n id: string | null;\n };\n}\n\n/**\n * Configuration options for GlydeVoice\n */\nexport interface GlydeVoiceConfig {\n // Authentication (one required)\n /** Publishable key for external apps (Screen) */\n publishableKey?: string;\n /** API key for programmatic access */\n apiKey?: string;\n /** JWT token for GLYDEBuddy passthrough (Teams app) */\n authToken?: string;\n\n // Context\n /** Voice context type - determines which prompt and tools to use */\n contextType: VoiceContextType;\n /** Context identifier (e.g., application_uuid) - required for screening */\n contextId?: string;\n\n // Connection\n /** Unity API base URL - defaults to https://api.glydeunity.com */\n unityBaseUrl?: string;\n\n // UI (optional)\n /** DOM element to render the widget UI (optional) */\n container?: HTMLElement | string;\n\n // Callbacks\n /** Event callback for voice agent events */\n onEvent?: (event: VoiceEvent) => void;\n /** Transcript callback for conversation text */\n onTranscript?: (text: string, role: 'user' | 'agent') => void;\n\n // Conversation history\n /** Previous conversation history to continue the conversation */\n conversationHistory?: Array<{ role: 'user' | 'agent'; content: string }>;\n\n // Optional overrides (if not provided, fetched from /api/unity/voice/config)\n /** Override system prompt (skips config fetch) */\n systemPrompt?: string;\n /** Override Deepgram configuration */\n deepgramConfig?: DeepgramAgentConfig;\n}\n\n/**\n * GlydeVoice - Voice Agent Client\n * \n * Connects to Deepgram Voice Agent API for bidirectional voice conversation.\n * Uses wss://agent.deepgram.com/agent WebSocket endpoint which:\n * - Receives user audio (microphone)\n * - Transcribes speech to text (STT)\n * - Sends to LLM for response\n * - Converts response to speech (TTS)\n * - Streams audio back to user\n * \n * Audio Architecture:\n * - Microphone capture: AudioWorklet (audio-capture-processor.js) at 48kHz\n * - Playback: AudioWorklet (audio-playback-processor.js) with ring buffer\n * - Ring buffer enables instant interruption (clear buffer when user speaks)\n */\nexport class GlydeVoice {\n private config: GlydeVoiceConfig;\n private unityUrl: string;\n private active = false;\n private serverConfig: VoiceConfig | null = null;\n\n // WebSocket and Audio\n private ws: WebSocket | null = null;\n private audioContext: AudioContext | null = null;\n private mediaStream: MediaStream | null = null;\n private captureWorkletNode: AudioWorkletNode | null = null;\n private playbackWorkletNode: AudioWorkletNode | null = null;\n private isMuted = false;\n\n // Audio settings\n private readonly outputSampleRate = 24000; // Deepgram TTS output rate\n private readonly inputSampleRate = 48000; // Microphone input rate\n\n // Agent state\n private isAgentSpeaking = false;\n private agentAudioDoneReceived = false;\n\n // Conversation history\n private conversationHistory: Array<{ role: 'user' | 'agent'; content: string }> = [];\n\n // Session context for function calls (passed to backend for data controls)\n private sessionContext: {\n clientUuid?: string;\n contextId?: string;\n contextType?: VoiceContextType;\n currentJobUuid?: string;\n } = {};\n\n /**\n * Create a new GlydeVoice instance\n * @param config - Configuration options\n */\n constructor(config: GlydeVoiceConfig) {\n this.config = config;\n this.unityUrl = config.unityBaseUrl || 'https://api.glydeunity.com';\n\n // Store conversation history if provided\n if (config.conversationHistory) {\n this.conversationHistory = config.conversationHistory;\n }\n\n // Validate authentication\n if (!config.publishableKey && !config.apiKey && !config.authToken) {\n console.warn('[GlydeVoice] No authentication method provided. One of publishableKey, apiKey, or authToken is required.');\n }\n }\n\n /**\n * Get authentication headers based on configured auth method\n * Supports publishableKey, apiKey, and JWT token (authToken)\n * @returns Headers object with appropriate authentication\n */\n private getAuthHeaders(): Record<string, string> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json'\n };\n\n if (this.config.publishableKey) {\n headers['x-publishable-key'] = this.config.publishableKey;\n }\n\n if (this.config.apiKey) {\n headers['x-api-key'] = this.config.apiKey;\n }\n\n // JWT passthrough for GLYDEBuddy\n if (this.config.authToken) {\n headers['Authorization'] = `Bearer ${this.config.authToken}`;\n }\n\n return headers;\n }\n\n /**\n * Fetch voice configuration from Unity API\n * @returns Voice configuration including system prompt, tools, and Deepgram settings\n */\n private async fetchConfig(): Promise<VoiceConfig> {\n const configUrl = `${this.unityUrl}/api/unity/voice/config/${this.config.contextType}`;\n const configPath = this.config.contextId\n ? `${configUrl}/${this.config.contextId}`\n : configUrl;\n\n const response = await fetch(configPath, {\n method: 'GET',\n headers: this.getAuthHeaders()\n });\n\n if (!response.ok) {\n const error = await response.json();\n throw new Error(error.error?.message || error.message || 'Failed to fetch voice config');\n }\n\n const { data } = await response.json();\n return data as VoiceConfig;\n }\n\n /**\n * Initialize and start the voice session\n */\n async start(): Promise<void> {\n if (this.active) return;\n this.active = true;\n\n try {\n // 1. Fetch config from Unity (unless system prompt is overridden)\n if (!this.config.systemPrompt) {\n this.serverConfig = await this.fetchConfig();\n console.log('[GlydeVoice] Fetched config:', this.serverConfig);\n }\n\n // 2. Authenticate and get ephemeral Deepgram token\n // Pass system_prompt and deepgram_config overrides if provided\n const authBody: Record<string, unknown> = {\n context_id: this.config.contextId,\n domain: typeof window !== 'undefined' ? window.location.hostname : 'localhost'\n };\n\n // Include overrides in auth request for trusted apps to use server-side\n if (this.config.systemPrompt) {\n authBody.system_prompt = this.config.systemPrompt;\n }\n if (this.config.deepgramConfig) {\n authBody.deepgram_config = this.config.deepgramConfig;\n }\n\n const authResponse = await fetch(`${this.unityUrl}/api/unity/voice/auth`, {\n method: 'POST',\n headers: this.getAuthHeaders(),\n body: JSON.stringify(authBody)\n });\n\n if (!authResponse.ok) {\n const error = await authResponse.json();\n throw new Error(error.error?.message || error.message || 'Failed to authenticate voice session');\n }\n\n const { data } = await authResponse.json();\n const { token: deepgramToken, agent_config, deepgram_config: serverDeepgramConfig } = data;\n\n // Set session context for function calls (client_uuid, job context, etc.)\n this.setSessionContext({\n clientUuid: agent_config?.client_uuid,\n contextId: this.config.contextId,\n contextType: this.config.contextType,\n currentJobUuid: agent_config?.job_uuid\n });\n\n // Use priority: client override > server response > server config > default\n let systemPrompt = this.config.systemPrompt ||\n agent_config.instructions ||\n this.serverConfig?.system_prompt ||\n 'You are a helpful AI assistant.';\n \n // If there's conversation history, prepend it to the prompt to provide context\n if (this.conversationHistory && this.conversationHistory.length > 0) {\n const historyText = this.conversationHistory.map(msg => {\n const role = msg.role === 'agent' ? 'Assistant' : 'User';\n return `${role}: ${msg.content}`;\n }).join('\\n');\n \n systemPrompt = `Previous conversation context:\\n${historyText}\\n\\nIMPORTANT: This is a continuation of a previous conversation. When the user starts speaking, you must first greet them warmly and acknowledge that you're continuing the conversation. Say something like \"Welcome back! I'm glad you're continuing our conversation. How can I help you today?\" or similar, then continue naturally based on the previous context.\\n\\n${systemPrompt}`;\n }\n\n // 3. Initialize audio system before connecting to WebSocket\n await this.initializeAudio();\n\n // 4. Connect to Deepgram Voice Agent WebSocket\n let agentUrl = 'wss://agent.deepgram.com/v1/agent/converse';\n\n // Get Deepgram config with priority: client override > auth response > server config > defaults\n const deepgramConfig = this.config.deepgramConfig ||\n serverDeepgramConfig ||\n this.serverConfig?.deepgram_config;\n\n // Append tags to WebSocket URL if present\n if (deepgramConfig?.tags && deepgramConfig.tags.length > 0) {\n const params = new URLSearchParams();\n deepgramConfig.tags.forEach((tag: string) => params.append('tag', tag));\n agentUrl += `?${params.toString()}`;\n }\n\n // Use 'bearer' subprotocol for JWT tokens from /v1/auth/grant\n this.ws = new WebSocket(agentUrl, ['bearer', deepgramToken]);\n\n this.ws.onopen = () => {\n // Use server-provided Deepgram config (functions are defined server-side)\n // Only provide minimal fallback for audio settings if server config is missing\n const finalDeepgramConfig = deepgramConfig || {\n think: { provider: { type: 'open_ai', model: 'gpt-4.1-nano' } },\n speak: { provider: { type: 'deepgram', model: 'aura-2-thalia-en' } },\n listen: { provider: { type: 'deepgram', version: 'v2', model: 'flux-general-en' } }\n };\n\n // Configure settings based on Deepgram Voice Agent API\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const settings: any = {\n type: 'Settings',\n audio: {\n input: {\n encoding: 'linear16',\n sample_rate: this.inputSampleRate\n },\n output: {\n encoding: 'linear16',\n sample_rate: this.outputSampleRate,\n container: 'none'\n }\n },\n agent: {\n language: 'en',\n speak: finalDeepgramConfig.speak || {\n provider: { type: 'deepgram', model: 'aura-2-thalia-en' }\n },\n listen: finalDeepgramConfig.listen || {\n provider: { type: 'deepgram', version: 'v2', model: 'flux-general-en' }\n },\n think: {\n provider: finalDeepgramConfig.think?.provider || { type: 'open_ai', model: 'gpt-4.1-nano' },\n // Functions come from server config - no client-side defaults\n ...(finalDeepgramConfig.think?.functions && { functions: finalDeepgramConfig.think.functions })\n },\n // Only show greeting if there's no previous conversation history\n // When resuming a conversation, skip the greeting to continue naturally\n ...(!this.conversationHistory || this.conversationHistory.length === 0 \n ? { greeting: \"Hi! I'm excited you chose to speak with me. Are you ready to start?\" }\n : {})\n }\n };\n\n // Add usage tags to settings if present\n if (finalDeepgramConfig.tags && finalDeepgramConfig.tags.length > 0) {\n settings.tags = finalDeepgramConfig.tags;\n }\n\n this.ws!.send(JSON.stringify(settings));\n this.emit({ type: 'open', payload: { config: agent_config, serverConfig: this.serverConfig } });\n };\n\n // Store system prompt for use after settings are applied\n const agentInstructions = systemPrompt;\n\n // Handle messages from Deepgram\n this.ws.onmessage = (event) => {\n if (typeof event.data === 'string') {\n try {\n const msg = JSON.parse(event.data);\n if (msg.type === 'SettingsApplied') {\n // Send the system prompt\n const updatePrompt = {\n type: 'UpdatePrompt',\n prompt: agentInstructions\n };\n this.ws!.send(JSON.stringify(updatePrompt));\n \n // Start microphone after a short delay to allow prompt to be processed\n // Use setTimeout as fallback in case PromptUpdated doesn't arrive\n setTimeout(() => {\n if (!this.mediaStream) {\n // Only start if microphone hasn't been started yet\n this.startMicrophone().catch(err => {\n console.error('[GlydeVoice] Failed to start microphone:', err);\n });\n }\n }, 500);\n }\n \n if (msg.type === 'PromptUpdated') {\n // If microphone hasn't started yet, start it now\n if (!this.mediaStream) {\n this.startMicrophone().catch(err => {\n console.error('[GlydeVoice] Failed to start microphone:', err);\n });\n }\n }\n } catch {\n // Not JSON, pass through\n }\n this.handleTextMessage(event.data);\n } else if (event.data instanceof Blob) {\n this.handleAudioData(event.data);\n } else if (event.data instanceof ArrayBuffer) {\n this.handleAudioBuffer(event.data);\n }\n };\n\n this.ws.onerror = (error) => {\n console.error('[GlydeVoice] WebSocket error:', error);\n this.emit({ type: 'error', payload: error });\n };\n\n this.ws.onclose = () => {\n this.cleanup();\n this.emit({ type: 'close' });\n };\n\n // Render UI if container is specified\n this.renderUI();\n\n } catch (error) {\n console.error('[GlydeVoice] Error starting session:', error);\n this.active = false;\n this.emit({ type: 'error', payload: error });\n throw error;\n }\n }\n\n /**\n * Create a blob URL from inline JavaScript code for AudioWorklet modules.\n * This avoids CORS issues when the SDK is loaded from a different origin than the page.\n * @param code - The JavaScript code to convert to a blob URL\n * @returns A blob URL that can be used with audioWorklet.addModule()\n */\n private createWorkletBlobUrl(code: string): string {\n const blob = new Blob([code], { type: 'application/javascript' });\n return URL.createObjectURL(blob);\n }\n\n /**\n * Initialize the audio system with both capture and playback worklets.\n * Uses inline blob URLs to avoid CORS issues when SDK is embedded in external apps.\n */\n private async initializeAudio(): Promise<void> {\n // Create a single AudioContext for both capture and playback\n this.audioContext = new AudioContext({ sampleRate: this.inputSampleRate });\n\n // Create blob URLs from inline worklet code (avoids CORS issues)\n const captureWorkletUrl = this.createWorkletBlobUrl(AUDIO_CAPTURE_PROCESSOR_CODE);\n const playbackWorkletUrl = this.createWorkletBlobUrl(AUDIO_PLAYBACK_PROCESSOR_CODE);\n\n try {\n // Load both AudioWorklet modules from blob URLs\n await Promise.all([\n this.audioContext.audioWorklet.addModule(captureWorkletUrl),\n this.audioContext.audioWorklet.addModule(playbackWorkletUrl)\n ]);\n } finally {\n // Clean up blob URLs after modules are loaded\n URL.revokeObjectURL(captureWorkletUrl);\n URL.revokeObjectURL(playbackWorkletUrl);\n }\n\n // Create the playback worklet node\n this.playbackWorkletNode = new AudioWorkletNode(this.audioContext, 'audio-playback-processor');\n this.playbackWorkletNode.connect(this.audioContext.destination);\n\n // Handle messages from playback worklet\n this.playbackWorkletNode.port.onmessage = (event) => {\n const { type } = event.data;\n if (type === 'cleared' || type === 'bufferEmpty') {\n this.isAgentSpeaking = false;\n this.agentAudioDoneReceived = false;\n this.emit({ type: 'agent_speaking', payload: false });\n }\n };\n }\n\n /**\n * Handle text messages from the Voice Agent\n */\n private handleTextMessage(data: string): void {\n try {\n const message = JSON.parse(data);\n\n switch (message.type) {\n case 'Welcome':\n this.emit({ type: 'ready' });\n break;\n\n case 'SettingsApplied':\n // Handled in onmessage\n break;\n\n case 'PromptUpdated':\n // Handled in onmessage\n break;\n\n case 'UserStartedSpeaking':\n this.emit({ type: 'user_speaking', payload: true });\n // Always clear the playback buffer when user starts speaking (interruption)\n this.clearPlaybackBuffer();\n this.isAgentSpeaking = false;\n this.agentAudioDoneReceived = false;\n break;\n\n case 'UserStoppedSpeaking':\n this.emit({ type: 'user_speaking', payload: false });\n break;\n\n case 'ConversationText':\n // Only process non-empty content\n if (message.content && message.content.trim()) {\n // Normalize role: Deepgram sends 'assistant', we use 'agent'\n const normalizedRole = message.role === 'assistant' ? 'agent' : 'user';\n if (this.config.onTranscript) {\n this.config.onTranscript(message.content, normalizedRole as 'user' | 'agent');\n }\n this.emit({ type: 'transcript', payload: { text: message.content, role: normalizedRole } });\n this.saveTranscript(message.content, message.role);\n }\n break;\n\n case 'AgentStartedSpeaking':\n this.isAgentSpeaking = true;\n this.agentAudioDoneReceived = false;\n this.emit({ type: 'agent_speaking', payload: true });\n break;\n\n case 'AgentAudioDone':\n this.agentAudioDoneReceived = true;\n // Don't set isAgentSpeaking = false here - buffer is still playing\n break;\n\n case 'Error':\n console.error('[GlydeVoice] Agent error:', message);\n this.emit({ type: 'error', payload: message });\n break;\n\n case 'FunctionCallRequest':\n // Handle client-side function call from Deepgram Voice Agent\n this.handleFunctionCallRequest(message as FunctionCallRequest);\n break;\n\n // Ignore: History, PromptUpdated, and other message types\n }\n } catch (e) {\n console.error('[GlydeVoice] Failed to parse message:', e);\n }\n }\n\n /**\n * Handle binary audio data (Blob) from agent TTS\n */\n private async handleAudioData(blob: Blob): Promise<void> {\n const arrayBuffer = await blob.arrayBuffer();\n this.handleAudioBuffer(arrayBuffer);\n }\n\n /**\n * Handle binary audio buffer from agent TTS\n * Deepgram sends linear16 PCM at 24kHz, we need to resample to 48kHz for playback\n */\n private handleAudioBuffer(buffer: ArrayBuffer): void {\n if (!this.playbackWorkletNode || !this.audioContext) return;\n\n // Ensure AudioContext is running (browser autoplay policy)\n if (this.audioContext.state === 'suspended') {\n this.audioContext.resume();\n }\n\n const byteLength = buffer.byteLength;\n if (byteLength === 0) return;\n\n // Ensure even byte length for Int16Array\n const validByteLength = byteLength - (byteLength % 2);\n if (validByteLength === 0) return;\n\n const alignedBuffer = validByteLength === byteLength\n ? buffer\n : buffer.slice(0, validByteLength);\n\n // Convert Int16 PCM to Float32\n const pcm16 = new Int16Array(alignedBuffer);\n const float32_24k = new Float32Array(pcm16.length);\n for (let i = 0; i < pcm16.length; i++) {\n float32_24k[i] = pcm16[i] / 32768.0;\n }\n\n // Resample from 24kHz to 48kHz (2x upsampling with linear interpolation)\n const float32_48k = this.resample24kTo48k(float32_24k);\n\n // Mark agent as speaking when we receive audio (if not already done)\n if (!this.isAgentSpeaking && !this.agentAudioDoneReceived) {\n this.isAgentSpeaking = true;\n this.emit({ type: 'agent_speaking', payload: true });\n }\n\n // Send to playback worklet - transfer the buffer for efficiency\n const audioData = new Float32Array(float32_48k);\n this.playbackWorkletNode.port.postMessage({\n type: 'audio',\n data: audioData\n }, [audioData.buffer]);\n }\n\n /**\n * Resample audio from 24kHz to 48kHz using linear interpolation\n */\n private resample24kTo48k(input: Float32Array): Float32Array {\n const outputLength = input.length * 2;\n const output = new Float32Array(outputLength);\n\n for (let i = 0; i < input.length - 1; i++) {\n const sample = input[i];\n const nextSample = input[i + 1];\n output[i * 2] = sample;\n output[i * 2 + 1] = (sample + nextSample) / 2;\n }\n\n // Handle last sample\n const lastIdx = input.length - 1;\n output[lastIdx * 2] = input[lastIdx];\n output[lastIdx * 2 + 1] = input[lastIdx];\n\n return output;\n }\n\n /**\n * Clear the playback buffer (for interruption handling)\n */\n private clearPlaybackBuffer(): void {\n if (this.playbackWorkletNode) {\n this.playbackWorkletNode.port.postMessage({ type: 'clear' });\n }\n }\n\n /**\n * Start capturing microphone audio using AudioWorklet\n */\n private async startMicrophone(): Promise<void> {\n if (!this.audioContext) {\n throw new Error('Audio context not initialized');\n }\n\n try {\n this.mediaStream = await navigator.mediaDevices.getUserMedia({\n audio: {\n channelCount: 1,\n sampleRate: this.inputSampleRate,\n echoCancellation: true,\n noiseSuppression: true\n }\n });\n\n const source = this.audioContext.createMediaStreamSource(this.mediaStream);\n\n // Create capture worklet node\n this.captureWorkletNode = new AudioWorkletNode(this.audioContext, 'audio-capture-processor');\n\n // Handle audio data from the capture worklet\n this.captureWorkletNode.port.onmessage = (event) => {\n if (!this.active || !this.ws || this.ws.readyState !== WebSocket.OPEN || this.isMuted) {\n return;\n }\n this.ws.send(event.data);\n };\n\n // Connect: microphone -> capture worklet\n source.connect(this.captureWorkletNode);\n\n this.emit({ type: 'microphone_ready' });\n\n } catch (err) {\n console.error('[GlydeVoice] Microphone error:', err);\n throw err;\n }\n }\n\n /**\n * Save transcript to Unity backend\n */\n private async saveTranscript(content: string, role: string): Promise<void> {\n if (!this.config.contextId || !content) return;\n\n try {\n await fetch(`${this.unityUrl}/api/unity/voice/transcript`, {\n method: 'POST',\n headers: this.getAuthHeaders(),\n body: JSON.stringify({\n context_id: this.config.contextId,\n content,\n role: role === 'assistant' ? 'assistant' : 'user'\n })\n });\n } catch {\n // Silently fail - transcript saving is not critical\n }\n }\n\n /**\n * Toggle mute state\n * @param muted - Whether to mute the microphone\n */\n setMuted(muted: boolean): void {\n this.isMuted = muted;\n }\n\n /**\n * Get current mute state\n */\n getMuted(): boolean {\n return this.isMuted;\n }\n\n /**\n * Check if the voice agent is currently active\n */\n isActive(): boolean {\n return this.active;\n }\n\n /**\n * Get the current server configuration\n */\n getServerConfig(): VoiceConfig | null {\n return this.serverConfig;\n }\n\n /**\n * Stop the voice session\n */\n stop(): void {\n this.active = false;\n this.cleanup();\n }\n\n /**\n * Cleanup resources\n */\n private cleanup(): void {\n if (this.captureWorkletNode) {\n this.captureWorkletNode.disconnect();\n this.captureWorkletNode.port.close();\n this.captureWorkletNode = null;\n }\n\n if (this.playbackWorkletNode) {\n this.playbackWorkletNode.disconnect();\n this.playbackWorkletNode.port.close();\n this.playbackWorkletNode = null;\n }\n\n if (this.mediaStream) {\n this.mediaStream.getTracks().forEach(track => track.stop());\n this.mediaStream = null;\n }\n\n if (this.audioContext) {\n this.audioContext.close();\n this.audioContext = null;\n }\n\n if (this.ws) {\n if (this.ws.readyState === WebSocket.OPEN) {\n this.ws.close();\n }\n this.ws = null;\n }\n }\n\n /**\n * Emit event to callback\n */\n private emit(event: VoiceEvent): void {\n if (this.config.onEvent) {\n this.config.onEvent(event);\n }\n }\n\n /**\n * Render a simple UI widget (optional)\n */\n private renderUI(): void {\n if (!this.config.container) return;\n\n const container = typeof this.config.container === 'string'\n ? document.querySelector(this.config.container)\n : this.config.container;\n\n if (container) {\n container.innerHTML = `\n <div style=\"padding: 20px; border: 1px solid #ccc; border-radius: 8px; background: #fff;\">\n <h3>Glyde Voice Agent</h3>\n <p>Status: Active</p>\n <p>Context: ${this.config.contextType}</p>\n <button onclick=\"this.closest('div').remove()\">Close</button>\n </div>\n `;\n }\n }\n\n /**\n * Handle a function call request from Deepgram Voice Agent\n * Routes function execution through the Unity voice function endpoint for proper authentication\n * \n * Deepgram sends an array of functions in each request, so we process each one\n * and send individual responses back.\n * \n * @param request - The function call request from Deepgram containing functions array\n * @see https://developers.deepgram.com/docs/voice-agents-function-calling\n */\n private async handleFunctionCallRequest(request: FunctionCallRequest): Promise<void> {\n // Process each function call in the request\n for (const func of request.functions) {\n console.log('[GlydeVoice] Function call request:', func.name, func.arguments);\n\n // Parse arguments from JSON string\n let input: Record<string, unknown> = {};\n try {\n input = func.arguments ? JSON.parse(func.arguments) : {};\n } catch (parseError) {\n console.warn('[GlydeVoice] Failed to parse function arguments:', parseError);\n }\n\n let output: string;\n\n try {\n // Handle end_conversation locally (no server call needed)\n if (func.name === 'end_conversation') {\n output = await this.handleEndConversation(input);\n } else {\n // Route other functions through Unity voice function endpoint\n // This ensures proper authentication and data controls\n output = await this.executeVoiceFunction(func.name, func.id, input);\n }\n } catch (error) {\n console.error(`[GlydeVoice] Function call error:`, error);\n output = JSON.stringify({ \n error: 'Function execution failed', \n details: error instanceof Error ? error.message : String(error)\n });\n }\n\n // Send the function call response back to Deepgram\n // Uses 'id', 'name', 'content' per Deepgram's expected format\n const response: FunctionCallResponse = {\n type: 'FunctionCallResponse',\n id: func.id,\n name: func.name,\n content: output\n };\n\n if (this.ws && this.ws.readyState === WebSocket.OPEN) {\n this.ws!.send(JSON.stringify(response));\n console.log('[GlydeVoice] Function response sent:', func.name);\n } else {\n console.error('[GlydeVoice] Cannot send function response - WebSocket not open');\n }\n }\n }\n\n /**\n * Execute a voice function through the Unity API with proper authentication\n * Uses the dedicated /api/unity/voice/function endpoint which handles\n * publishable key authentication and data controls\n * \n * @param functionName - Name of the function to execute\n * @param functionCallId - Unique ID for tracking\n * @param input - Function input parameters\n * @returns JSON string with function result\n */\n private async executeVoiceFunction(\n functionName: string, \n functionCallId: string, \n input: Record<string, unknown>\n ): Promise<string> {\n console.log('[GlydeVoice] Executing voice function via Unity API:', functionName);\n\n try {\n const response = await fetch(`${this.unityUrl}/api/unity/voice/function`, {\n method: 'POST',\n headers: this.getAuthHeaders(),\n body: JSON.stringify({\n function_name: functionName,\n function_call_id: functionCallId,\n input,\n context: {\n context_id: this.sessionContext.contextId,\n context_type: this.sessionContext.contextType,\n current_job_uuid: this.sessionContext.currentJobUuid\n }\n })\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n throw new Error(errorData.error?.message || `Function call failed: ${response.status}`);\n }\n\n const result = await response.json();\n \n if (result.success && result.data?.output) {\n // Return the output as JSON string for Deepgram\n return typeof result.data.output === 'string' \n ? result.data.output \n : JSON.stringify(result.data.output);\n } else {\n throw new Error('Invalid response from voice function endpoint');\n }\n } catch (error) {\n console.error('[GlydeVoice] Voice function error:', error);\n return JSON.stringify({\n success: false,\n error: error instanceof Error ? error.message : 'Function execution failed',\n fallback_message: 'I apologize, but I\\'m having trouble with that request right now. Is there something else I can help you with?'\n });\n }\n }\n\n /**\n * Handle the end_conversation function locally\n * Gracefully ends the voice session (no server call needed)\n * \n * @param input - Function parameters including the trigger phrase\n * @returns Acknowledgment string for the agent\n */\n private async handleEndConversation(input: Record<string, unknown>): Promise<string> {\n const trigger = input.item as string || 'user request';\n console.log(`[GlydeVoice] End conversation triggered by: ${trigger}`);\n \n // Schedule the stop after a brief delay to allow goodbye message\n setTimeout(() => {\n this.stop();\n }, 2000);\n\n return JSON.stringify({\n success: true,\n message: 'Conversation ending. Say goodbye to the user.',\n trigger_phrase: trigger\n });\n }\n\n /**\n * Set session context for function calls\n * Called internally after authentication to provide job context for function routing\n * Context is passed to the backend voice function endpoint for proper data controls\n * \n * @param context - Session context with contextId, contextType, and job details\n */\n public setSessionContext(context: {\n clientUuid?: string;\n contextId?: string;\n contextType?: VoiceContextType;\n currentJobUuid?: string;\n }): void {\n this.sessionContext = { ...this.sessionContext, ...context };\n console.log('[GlydeVoice] Session context updated:', {\n hasContextId: !!context.contextId,\n contextType: context.contextType,\n hasJobUuid: !!context.currentJobUuid\n });\n }\n}\n","/**\n * GlydeText - Text Chat Client for GLYDE Unity\n * \n * Provides text-based chat interaction with GLYDE AI agents through the Unity API.\n * Supports the same authentication methods as GlydeVoice.\n * \n * @example\n * const textChat = new GlydeText({\n * publishableKey: 'pk_...',\n * contextId: 'application-uuid'\n * });\n * \n * const response = await textChat.sendMessage('Hello!');\n */\n\nimport type { GlydeTextConfig, TextChatEvent, ChatMessage } from './types';\n\n/**\n * GlydeText - Text Chat Client\n * \n * Connects to GLYDE Unity API for text-based conversations.\n * Uses the screening chat endpoints for candidate interactions.\n */\nexport class GlydeText {\n private config: GlydeTextConfig;\n private unityUrl: string;\n private history: ChatMessage[] = [];\n private isTyping = false;\n private initialized = false;\n\n /**\n * Create a new GlydeText instance\n * @param config - Configuration options\n */\n constructor(config: GlydeTextConfig) {\n this.config = config;\n this.unityUrl = config.unityBaseUrl || 'https://api.glydeunity.com';\n\n // Validate authentication\n if (!config.publishableKey && !config.apiKey && !config.authToken) {\n console.warn('[GlydeText] No authentication method provided. One of publishableKey, apiKey, or authToken is required.');\n }\n }\n\n /**\n * Get authentication headers based on configured auth method\n * @returns Headers object with appropriate authentication\n */\n private getAuthHeaders(): Record<string, string> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json'\n };\n\n if (this.config.publishableKey) {\n headers['x-publishable-key'] = this.config.publishableKey;\n }\n\n if (this.config.apiKey) {\n headers['x-api-key'] = this.config.apiKey;\n }\n\n if (this.config.authToken) {\n headers['Authorization'] = `Bearer ${this.config.authToken}`;\n }\n\n return headers;\n }\n\n /**\n * Emit event to callback\n */\n private emit(event: TextChatEvent): void {\n if (this.config.onEvent) {\n this.config.onEvent(event);\n }\n }\n\n /**\n * Set typing state and notify callback\n */\n private setTyping(isTyping: boolean): void {\n this.isTyping = isTyping;\n if (this.config.onTyping) {\n this.config.onTyping(isTyping);\n }\n }\n\n /**\n * Initialize the chat session and load existing history\n * @returns The loaded message history\n */\n async initialize(): Promise<ChatMessage[]> {\n if (!this.config.contextId) {\n throw new Error('contextId is required for text chat initialization');\n }\n\n this.setTyping(true);\n\n try {\n const response = await fetch(`${this.unityUrl}/api/unity/screening/start`, {\n method: 'POST',\n headers: this.getAuthHeaders(),\n body: JSON.stringify({ application_uuid: this.config.contextId })\n });\n\n if (!response.ok) {\n const error = await response.json().catch(() => ({}));\n throw new Error(error.error?.message || error.message || 'Failed to initialize chat');\n }\n\n const data = await response.json();\n \n if (data.messages) {\n this.history = data.messages;\n }\n\n this.initialized = true;\n this.emit({ type: 'ready' });\n this.emit({ type: 'history_loaded', payload: this.history });\n\n return this.history;\n\n } catch (error) {\n console.error('[GlydeText] Initialization error:', error);\n this.emit({ type: 'error', payload: error });\n throw error;\n\n } finally {\n this.setTyping(false);\n }\n }\n\n /**\n * Send a message and get the agent's response\n * @param message - The message content to send\n * @returns The agent's response message\n */\n async sendMessage(message: string): Promise<ChatMessage> {\n if (!this.config.contextId) {\n throw new Error('contextId is required for sending messages');\n }\n\n if (!message.trim()) {\n throw new Error('Message cannot be empty');\n }\n\n // Auto-initialize if not done\n if (!this.initialized) {\n await this.initialize();\n }\n\n // Add user message to local history immediately\n const userMessage: ChatMessage = {\n role: 'user',\n content: message.trim(),\n created: new Date().toISOString()\n };\n\n this.history.push(userMessage);\n \n if (this.config.onMessage) {\n this.config.onMessage(userMessage);\n }\n this.emit({ type: 'message', payload: userMessage });\n\n this.setTyping(true);\n\n try {\n const response = await fetch(`${this.unityUrl}/api/unity/screening/chat`, {\n method: 'POST',\n headers: this.getAuthHeaders(),\n body: JSON.stringify({\n application_uuid: this.config.contextId,\n message: message.trim()\n })\n });\n\n if (!response.ok) {\n const error = await response.json().catch(() => ({}));\n throw new Error(error.error?.message || error.message || 'Failed to send message');\n }\n\n const data = await response.json();\n\n // Update with history from server to ensure sync\n if (data.history?.messages) {\n this.history = data.history.messages;\n }\n\n // Find and return the assistant's response (last assistant message)\n const assistantMessage = [...this.history].reverse().find(m => m.role === 'assistant');\n\n if (assistantMessage) {\n if (this.config.onMessage) {\n this.config.onMessage(assistantMessage);\n }\n this.emit({ type: 'message', payload: assistantMessage });\n return assistantMessage;\n }\n\n // Fallback if no assistant message found\n const fallbackMessage: ChatMessage = {\n role: 'assistant',\n content: data.response || 'I received your message.',\n created: new Date().toISOString()\n };\n\n return fallbackMessage;\n\n } catch (error) {\n console.error('[GlydeText] Send message error:', error);\n this.emit({ type: 'error', payload: error });\n throw error;\n\n } finally {\n this.setTyping(false);\n }\n }\n\n /**\n * Get the current conversation history\n * @returns Array of chat messages\n */\n getHistory(): ChatMessage[] {\n return [...this.history];\n }\n\n /**\n * Clear the local conversation history\n * Note: This does not clear server-side history\n */\n clearHistory(): void {\n this.history = [];\n this.initialized = false;\n }\n\n /**\n * Check if the chat is currently waiting for a response\n */\n getIsTyping(): boolean {\n return this.isTyping;\n }\n\n /**\n * Check if the chat has been initialized\n */\n getIsInitialized(): boolean {\n return this.initialized;\n }\n}\n","/**\n * GLYDE Voice SDK - useVoiceAgent Hook\n * \n * React hook for managing voice agent lifecycle and state.\n * \n * @example\n * const { status, transcripts, start, stop, mute } = useVoiceAgent({\n * publishableKey: 'pk_...',\n * contextType: 'screening',\n * contextId: 'application-uuid'\n * });\n */\n\nimport { useState, useRef, useCallback, useEffect } from 'react';\nimport { GlydeVoice } from '../GlydeVoice';\nimport type { GlydeVoiceConfig, VoiceEvent, Transcript } from '../core/types';\n\n/**\n * Voice agent status\n */\nexport type VoiceAgentStatus = 'idle' | 'connecting' | 'active' | 'error';\n\n/**\n * Voice agent hook configuration\n */\nexport interface UseVoiceAgentConfig extends Omit<GlydeVoiceConfig, 'onEvent' | 'onTranscript'> {\n /** Auto-start the voice agent on mount */\n autoStart?: boolean;\n}\n\n/**\n * Voice agent hook return value\n */\nexport interface UseVoiceAgentReturn {\n /** Current status of the voice agent */\n status: VoiceAgentStatus;\n /** Conversation transcripts */\n transcripts: Transcript[];\n /** Whether the user is currently speaking */\n isUserSpeaking: boolean;\n /** Whether the agent is currently speaking */\n isAgentSpeaking: boolean;\n /** Whether the microphone is muted */\n isMuted: boolean;\n /** Error message if status is 'error' */\n errorMessage: string | null;\n /** Start the voice session */\n start: () => Promise<void>;\n /** Stop the voice session */\n stop: () => void;\n /** Toggle mute state */\n toggleMute: () => void;\n /** Set mute state */\n setMuted: (muted: boolean) => void;\n /** Clear transcripts */\n clearTranscripts: () => void;\n /** The underlying GlydeVoice instance */\n voiceAgent: GlydeVoice | null;\n}\n\n/**\n * React hook for managing voice agent state and lifecycle\n * \n * @param config - Voice agent configuration\n * @returns Voice agent state and control methods\n */\nexport function useVoiceAgent(config: UseVoiceAgentConfig): UseVoiceAgentReturn {\n const [status, setStatus] = useState<VoiceAgentStatus>('idle');\n const [transcripts, setTranscripts] = useState<Transcript[]>([]);\n const [isUserSpeaking, setIsUserSpeaking] = useState(false);\n const [isAgentSpeaking, setIsAgentSpeaking] = useState(false);\n const [isMuted, setIsMuted] = useState(false);\n const [errorMessage, setErrorMessage] = useState<string | null>(null);\n \n const voiceAgentRef = useRef<GlydeVoice | null>(null);\n\n /**\n * Handle voice events from the SDK\n */\n const handleVoiceEvent = useCallback((event: VoiceEvent) => {\n switch (event.type) {\n case 'ready':\n setStatus('active');\n break;\n case 'close':\n setStatus('idle');\n setIsUserSpeaking(false);\n setIsAgentSpeaking(false);\n break;\n case 'error':\n setStatus('error');\n setErrorMessage(\n typeof event.payload === 'object' && event.payload !== null && 'message' in event.payload\n ? String((event.payload as { message: string }).message)\n : 'Connection error'\n );\n break;\n case 'user_speaking':\n setIsUserSpeaking(Boolean(event.payload));\n break;\n case 'agent_speaking':\n setIsAgentSpeaking(Boolean(event.payload));\n break;\n }\n }, []);\n\n /**\n * Handle transcript from the SDK\n */\n const handleTranscript = useCallback((text: string, role: 'user' | 'agent') => {\n setTranscripts(prev => [...prev, {\n role,\n content: text,\n timestamp: new Date()\n }]);\n }, []);\n\n /**\n * Start the voice session\n */\n const start = useCallback(async () => {\n setStatus('connecting');\n setErrorMessage(null);\n\n try {\n const agent = new GlydeVoice({\n ...config,\n onEvent: handleVoiceEvent,\n onTranscript: handleTranscript\n });\n\n voiceAgentRef.current = agent;\n await agent.start();\n \n } catch (error) {\n console.error('[useVoiceAgent] Failed to start:', error);\n setStatus('error');\n setErrorMessage(error instanceof Error ? error.message : 'Failed to connect');\n }\n }, [config, handleVoiceEvent, handleTranscript]);\n\n /**\n * Stop the voice session\n */\n const stop = useCallback(() => {\n voiceAgentRef.current?.stop();\n voiceAgentRef.current = null;\n setStatus('idle');\n setIsUserSpeaking(false);\n setIsAgentSpeaking(false);\n }, []);\n\n /**\n * Toggle mute state\n */\n const toggleMute = useCallback(() => {\n const newMuted = !isMuted;\n setIsMuted(newMuted);\n voiceAgentRef.current?.setMuted(newMuted);\n }, [isMuted]);\n\n /**\n * Set mute state directly\n */\n const setMutedState = useCallback((muted: boolean) => {\n setIsMuted(muted);\n voiceAgentRef.current?.setMuted(muted);\n }, []);\n\n /**\n * Clear transcripts\n */\n const clearTranscripts = useCallback(() => {\n setTranscripts([]);\n }, []);\n\n /**\n * Cleanup on unmount\n */\n useEffect(() => {\n return () => {\n voiceAgentRef.current?.stop();\n };\n }, []);\n\n /**\n * Auto-start if configured\n */\n useEffect(() => {\n if (config.autoStart && status === 'idle') {\n start();\n }\n }, [config.autoStart, status, start]);\n\n return {\n status,\n transcripts,\n isUserSpeaking,\n isAgentSpeaking,\n isMuted,\n errorMessage,\n start,\n stop,\n toggleMute,\n setMuted: setMutedState,\n clearTranscripts,\n voiceAgent: voiceAgentRef.current,\n };\n}\n","/**\n * GLYDE Voice SDK - useTextChat Hook\n * \n * React hook for managing text chat state and lifecycle.\n * \n * @example\n * const { messages, isLoading, sendMessage, clearHistory } = useTextChat({\n * publishableKey: 'pk_...',\n * contextId: 'application-uuid'\n * });\n */\n\nimport { useState, useRef, useCallback, useEffect } from 'react';\nimport { GlydeText } from '../core/GlydeText';\nimport type { GlydeTextConfig, ChatMessage } from '../core/types';\n\n/**\n * Text chat status\n */\nexport type TextChatStatus = 'idle' | 'loading' | 'ready' | 'error';\n\n/**\n * Text chat hook configuration\n */\nexport interface UseTextChatConfig extends Omit<GlydeTextConfig, 'onEvent' | 'onMessage' | 'onTyping'> {\n /** Auto-initialize the chat on mount */\n autoInit?: boolean;\n}\n\n/**\n * Text chat hook return value\n */\nexport interface UseTextChatReturn {\n /** Current status of the text chat */\n status: TextChatStatus;\n /** Chat message history */\n messages: ChatMessage[];\n /** Whether the agent is typing/processing */\n isLoading: boolean;\n /** Error message if status is 'error' */\n errorMessage: string | null;\n /** Initialize the chat session */\n initialize: () => Promise<void>;\n /** Send a message */\n sendMessage: (message: string) => Promise<void>;\n /** Clear local message history */\n clearHistory: () => void;\n /** The underlying GlydeText instance */\n textChat: GlydeText | null;\n}\n\n/**\n * React hook for managing text chat state and lifecycle\n * \n * @param config - Text chat configuration\n * @returns Text chat state and control methods\n */\nexport function useTextChat(config: UseTextChatConfig): UseTextChatReturn {\n const [status, setStatus] = useState<TextChatStatus>('idle');\n const [messages, setMessages] = useState<ChatMessage[]>([]);\n const [isLoading, setIsLoading] = useState(false);\n const [errorMessage, setErrorMessage] = useState<string | null>(null);\n \n const textChatRef = useRef<GlydeText | null>(null);\n const initializedRef = useRef(false);\n\n /**\n * Get or create GlydeText instance\n */\n const getTextChat = useCallback(() => {\n if (!textChatRef.current) {\n textChatRef.current = new GlydeText({\n ...config,\n onTyping: setIsLoading,\n });\n }\n return textChatRef.current;\n }, [config]);\n\n /**\n * Initialize the chat session\n */\n const initialize = useCallback(async () => {\n if (initializedRef.current) return;\n \n setStatus('loading');\n setErrorMessage(null);\n\n try {\n const chat = getTextChat();\n const history = await chat.initialize();\n setMessages(history);\n setStatus('ready');\n initializedRef.current = true;\n \n } catch (error) {\n console.error('[useTextChat] Initialization error:', error);\n setStatus('error');\n setErrorMessage(error instanceof Error ? error.message : 'Failed to initialize chat');\n }\n }, [getTextChat]);\n\n /**\n * Send a message\n */\n const sendMessage = useCallback(async (message: string) => {\n if (!message.trim()) return;\n \n setErrorMessage(null);\n\n try {\n const chat = getTextChat();\n \n // Add user message to UI immediately\n const userMessage: ChatMessage = {\n role: 'user',\n content: message.trim(),\n created: new Date().toISOString()\n };\n setMessages(prev => [...prev, userMessage]);\n \n // Send to server and get response\n await chat.sendMessage(message);\n \n // Update with full history from server\n const history = chat.getHistory();\n setMessages(history);\n\n // Ensure status is ready after first successful message\n if (status !== 'ready') {\n setStatus('ready');\n initializedRef.current = true;\n }\n \n } catch (error) {\n console.error('[useTextChat] Send message error:', error);\n setErrorMessage(error instanceof Error ? error.message : 'Failed to send message');\n }\n }, [getTextChat, status]);\n\n /**\n * Clear local message history\n */\n const clearHistory = useCallback(() => {\n textChatRef.current?.clearHistory();\n setMessages([]);\n initializedRef.current = false;\n setStatus('idle');\n }, []);\n\n /**\n * Auto-initialize if configured\n */\n useEffect(() => {\n if (config.autoInit && !initializedRef.current && config.contextId) {\n initialize();\n }\n }, [config.autoInit, config.contextId, initialize]);\n\n /**\n * Cleanup on unmount\n */\n useEffect(() => {\n return () => {\n textChatRef.current = null;\n };\n }, []);\n\n return {\n status,\n messages,\n isLoading,\n errorMessage,\n initialize,\n sendMessage,\n clearHistory,\n textChat: textChatRef.current,\n };\n}\n","/**\n * GLYDE Voice SDK - SVG Icon Components\n * \n * Inline SVG icons to avoid external dependencies like lucide-react.\n * These icons are bundled with the SDK for CDN usage.\n * \n * @packageDocumentation\n */\n\nimport React from 'react';\n\ninterface IconProps {\n size?: number;\n color?: string;\n className?: string;\n}\n\n/**\n * Microphone icon\n */\nexport const MicIcon: React.FC<IconProps> = ({ size = 24, color = 'currentColor', className }) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke={color}\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n >\n <path d=\"M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z\" />\n <path d=\"M19 10v2a7 7 0 0 1-14 0v-2\" />\n <line x1=\"12\" x2=\"12\" y1=\"19\" y2=\"22\" />\n </svg>\n);\n\n/**\n * Microphone off / muted icon\n */\nexport const MicOffIcon: React.FC<IconProps> = ({ size = 24, color = 'currentColor', className }) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke={color}\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n >\n <line x1=\"2\" x2=\"22\" y1=\"2\" y2=\"22\" />\n <path d=\"M18.89 13.23A7.12 7.12 0 0 0 19 12v-2\" />\n <path d=\"M5 10v2a7 7 0 0 0 12 5\" />\n <path d=\"M15 9.34V5a3 3 0 0 0-5.68-1.33\" />\n <path d=\"M9 9v3a3 3 0 0 0 5.12 2.12\" />\n <line x1=\"12\" x2=\"12\" y1=\"19\" y2=\"22\" />\n </svg>\n);\n\n/**\n * Phone icon\n */\nexport const PhoneIcon: React.FC<IconProps> = ({ size = 24, color = 'currentColor', className }) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke={color}\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n >\n <path d=\"M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z\" />\n </svg>\n);\n\n/**\n * Phone off / end call icon\n */\nexport const PhoneOffIcon: React.FC<IconProps> = ({ size = 24, color = 'currentColor', className }) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke={color}\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n >\n <path d=\"M10.68 13.31a16 16 0 0 0 3.41 2.6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7 2 2 0 0 1 1.72 2v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.42 19.42 0 0 1-3.33-2.67m-2.67-3.34a19.79 19.79 0 0 1-3.07-8.63A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91\" />\n <line x1=\"22\" x2=\"2\" y1=\"2\" y2=\"22\" />\n </svg>\n);\n\n/**\n * Message / chat icon\n */\nexport const MessageIcon: React.FC<IconProps> = ({ size = 24, color = 'currentColor', className }) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke={color}\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n >\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\" />\n </svg>\n);\n\n/**\n * Send icon\n */\nexport const SendIcon: React.FC<IconProps> = ({ size = 24, color = 'currentColor', className }) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke={color}\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n >\n <line x1=\"22\" x2=\"11\" y1=\"2\" y2=\"13\" />\n <polygon points=\"22 2 15 22 11 13 2 9 22 2\" />\n </svg>\n);\n\n/**\n * User icon\n */\nexport const UserIcon: React.FC<IconProps> = ({ size = 24, color = 'currentColor', className }) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke={color}\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n >\n <path d=\"M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2\" />\n <circle cx=\"12\" cy=\"7\" r=\"4\" />\n </svg>\n);\n\n/**\n * Bot / AI icon\n */\nexport const BotIcon: React.FC<IconProps> = ({ size = 24, color = 'currentColor', className }) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke={color}\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n >\n <path d=\"M12 8V4H8\" />\n <rect width=\"16\" height=\"12\" x=\"4\" y=\"8\" rx=\"2\" />\n <path d=\"M2 14h2\" />\n <path d=\"M20 14h2\" />\n <path d=\"M15 13v2\" />\n <path d=\"M9 13v2\" />\n </svg>\n);\n\n/**\n * Activity / live indicator icon\n */\nexport const ActivityIcon: React.FC<IconProps> = ({ size = 24, color = 'currentColor', className }) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke={color}\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n >\n <polyline points=\"22 12 18 12 15 21 9 3 6 12 2 12\" />\n </svg>\n);\n\n/**\n * Volume X / muted speaker icon\n */\nexport const VolumeXIcon: React.FC<IconProps> = ({ size = 24, color = 'currentColor', className }) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke={color}\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n >\n <polygon points=\"11 5 6 9 2 9 2 15 6 15 11 19 11 5\" />\n <line x1=\"22\" x2=\"16\" y1=\"9\" y2=\"15\" />\n <line x1=\"16\" x2=\"22\" y1=\"9\" y2=\"15\" />\n </svg>\n);\n\n/**\n * X / close icon\n */\nexport const XIcon: React.FC<IconProps> = ({ size = 24, color = 'currentColor', className }) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke={color}\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n >\n <line x1=\"18\" x2=\"6\" y1=\"6\" y2=\"18\" />\n <line x1=\"6\" x2=\"18\" y1=\"6\" y2=\"18\" />\n </svg>\n);\n\n/**\n * Minimize icon\n */\nexport const MinimizeIcon: React.FC<IconProps> = ({ size = 24, color = 'currentColor', className }) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke={color}\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n >\n <path d=\"M8 3v3a2 2 0 0 1-2 2H3\" />\n <path d=\"M21 8h-3a2 2 0 0 1-2-2V3\" />\n <path d=\"M3 16h3a2 2 0 0 1 2 2v3\" />\n <path d=\"M16 21v-3a2 2 0 0 1 2-2h3\" />\n </svg>\n);\n\n/**\n * Loader / spinner icon\n */\nexport const LoaderIcon: React.FC<IconProps> = ({ size = 24, color = 'currentColor', className }) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke={color}\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n style={{ animation: 'spin 1s linear infinite' }}\n >\n <path d=\"M21 12a9 9 0 1 1-6.219-8.56\" />\n </svg>\n);\n","/**\n * GLYDE Voice SDK - CSS-in-JS Styles\n * \n * Centralized styles for all UI components.\n * Uses CSS custom properties for theming.\n * \n * @packageDocumentation\n */\n\n/**\n * Theme color definitions\n */\nexport const themeColors = {\n light: {\n // Primary colors (purple/magenta)\n primary: '#c026d3',\n primaryHover: '#a21caf',\n primaryLight: '#fdf4ff',\n primaryText: '#ffffff',\n\n // Secondary colors (blue/cyan for text chat)\n secondary: '#0284c7',\n secondaryHover: '#0369a1',\n secondaryLight: '#f0f9ff',\n secondaryText: '#ffffff',\n\n // Success/active colors (green)\n success: '#059669',\n successLight: '#dcfce7',\n successText: '#166534',\n\n // Error colors (red)\n error: '#ef4444',\n errorHover: '#dc2626',\n errorLight: '#fef2f2',\n errorText: '#b91c1c',\n\n // Neutral colors\n background: '#ffffff',\n surface: '#f9fafb',\n border: '#e5e7eb',\n borderLight: '#f3f4f6',\n text: '#1f2937',\n textSecondary: '#6b7280',\n textMuted: '#9ca3af',\n },\n dark: {\n // Primary colors\n primary: '#d946ef',\n primaryHover: '#c026d3',\n primaryLight: '#3b0764',\n primaryText: '#ffffff',\n\n // Secondary colors\n secondary: '#38bdf8',\n secondaryHover: '#0ea5e9',\n secondaryLight: '#0c4a6e',\n secondaryText: '#ffffff',\n\n // Success colors\n success: '#34d399',\n successLight: '#064e3b',\n successText: '#a7f3d0',\n\n // Error colors\n error: '#f87171',\n errorHover: '#ef4444',\n errorLight: '#450a0a',\n errorText: '#fecaca',\n\n // Neutral colors\n background: '#111827',\n surface: '#1f2937',\n border: '#374151',\n borderLight: '#4b5563',\n text: '#f9fafb',\n textSecondary: '#d1d5db',\n textMuted: '#9ca3af',\n }\n};\n\n/**\n * Get CSS variables for a theme\n */\nexport function getThemeCSSVariables(theme: 'light' | 'dark'): string {\n const colors = themeColors[theme];\n return `\n --glyde-primary: ${colors.primary};\n --glyde-primary-hover: ${colors.primaryHover};\n --glyde-primary-light: ${colors.primaryLight};\n --glyde-primary-text: ${colors.primaryText};\n --glyde-secondary: ${colors.secondary};\n --glyde-secondary-hover: ${colors.secondaryHover};\n --glyde-secondary-light: ${colors.secondaryLight};\n --glyde-secondary-text: ${colors.secondaryText};\n --glyde-success: ${colors.success};\n --glyde-success-light: ${colors.successLight};\n --glyde-success-text: ${colors.successText};\n --glyde-error: ${colors.error};\n --glyde-error-hover: ${colors.errorHover};\n --glyde-error-light: ${colors.errorLight};\n --glyde-error-text: ${colors.errorText};\n --glyde-background: ${colors.background};\n --glyde-surface: ${colors.surface};\n --glyde-border: ${colors.border};\n --glyde-border-light: ${colors.borderLight};\n --glyde-text: ${colors.text};\n --glyde-text-secondary: ${colors.textSecondary};\n --glyde-text-muted: ${colors.textMuted};\n `;\n}\n\n/**\n * Global CSS styles to inject\n */\nexport const globalStyles = `\n @keyframes glyde-pulse {\n 0%, 100% { opacity: 1; transform: scale(1); }\n 50% { opacity: 0.5; transform: scale(1.2); }\n }\n\n @keyframes glyde-spin {\n to { transform: rotate(360deg); }\n }\n\n @keyframes glyde-fade-in {\n from { opacity: 0; transform: translateY(10px); }\n to { opacity: 1; transform: translateY(0); }\n }\n\n @keyframes glyde-slide-up {\n from { opacity: 0; transform: translateY(20px); }\n to { opacity: 1; transform: translateY(0); }\n }\n\n @keyframes glyde-bounce {\n 0%, 100% { transform: translateY(0); }\n 50% { transform: translateY(-5px); }\n }\n\n .glyde-widget-root {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n font-size: 14px;\n line-height: 1.5;\n color: var(--glyde-text);\n box-sizing: border-box;\n }\n\n .glyde-widget-root *, .glyde-widget-root *::before, .glyde-widget-root *::after {\n box-sizing: border-box;\n }\n\n .glyde-spinner {\n width: 32px;\n height: 32px;\n border: 3px solid var(--glyde-border);\n border-top-color: var(--glyde-primary);\n border-radius: 50%;\n animation: glyde-spin 1s linear infinite;\n }\n\n .glyde-pulse-dot {\n animation: glyde-pulse 1.5s infinite;\n }\n\n .glyde-fade-in {\n animation: glyde-fade-in 0.3s ease-out;\n }\n\n .glyde-slide-up {\n animation: glyde-slide-up 0.3s ease-out;\n }\n`;\n\n/**\n * Component-specific style objects (for inline styles)\n */\nexport const componentStyles = {\n // Floating widget button\n floatingButton: {\n position: 'fixed' as const,\n width: '60px',\n height: '60px',\n borderRadius: '50%',\n border: 'none',\n cursor: 'pointer',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n boxShadow: '0 4px 12px rgba(0, 0, 0, 0.15)',\n transition: 'transform 0.2s, box-shadow 0.2s',\n zIndex: 9999,\n },\n\n // Widget panel\n widgetPanel: {\n position: 'fixed' as const,\n width: '380px',\n height: '600px',\n borderRadius: '16px',\n boxShadow: '0 10px 40px rgba(0, 0, 0, 0.2)',\n display: 'flex',\n flexDirection: 'column' as const,\n overflow: 'hidden',\n zIndex: 9998,\n },\n\n // Card container\n card: {\n background: 'var(--glyde-background)',\n borderRadius: '12px',\n boxShadow: '0 4px 6px rgba(0, 0, 0, 0.1)',\n overflow: 'hidden',\n },\n\n // Header\n header: {\n padding: '16px 20px',\n borderBottom: '1px solid var(--glyde-border)',\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n },\n\n // Mode selector\n modeSelector: {\n display: 'flex',\n gap: '8px',\n padding: '4px',\n background: 'var(--glyde-surface)',\n borderRadius: '8px',\n },\n\n modeSelectorButton: {\n padding: '8px 16px',\n border: 'none',\n borderRadius: '6px',\n cursor: 'pointer',\n display: 'flex',\n alignItems: 'center',\n gap: '6px',\n fontSize: '14px',\n fontWeight: 500,\n transition: 'all 0.2s',\n },\n\n // Transcript area\n transcriptArea: {\n flex: 1,\n overflowY: 'auto' as const,\n padding: '16px',\n background: 'var(--glyde-surface)',\n },\n\n // Message bubble\n messageBubble: {\n maxWidth: '80%',\n padding: '10px 14px',\n borderRadius: '12px',\n boxShadow: '0 1px 3px rgba(0, 0, 0, 0.1)',\n },\n\n messageBubbleUser: {\n background: 'var(--glyde-primary)',\n color: 'var(--glyde-primary-text)',\n borderTopRightRadius: '4px',\n },\n\n messageBubbleAgent: {\n background: 'var(--glyde-background)',\n color: 'var(--glyde-text)',\n borderTopLeftRadius: '4px',\n },\n\n // Controls area\n controlsArea: {\n padding: '16px',\n borderTop: '1px solid var(--glyde-border)',\n background: 'var(--glyde-background)',\n },\n\n // Speaking indicators\n speakingIndicator: {\n display: 'flex',\n alignItems: 'center',\n gap: '6px',\n fontSize: '13px',\n },\n\n speakingDot: {\n width: '8px',\n height: '8px',\n borderRadius: '50%',\n transition: 'background-color 0.2s',\n },\n\n // Buttons\n primaryButton: {\n padding: '12px 24px',\n background: 'var(--glyde-primary)',\n color: 'var(--glyde-primary-text)',\n border: 'none',\n borderRadius: '8px',\n fontSize: '15px',\n fontWeight: 600,\n cursor: 'pointer',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: '8px',\n transition: 'background-color 0.2s, transform 0.1s',\n },\n\n secondaryButton: {\n padding: '10px 20px',\n background: 'var(--glyde-surface)',\n color: 'var(--glyde-text)',\n border: '1px solid var(--glyde-border)',\n borderRadius: '8px',\n fontSize: '14px',\n fontWeight: 500,\n cursor: 'pointer',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: '6px',\n transition: 'background-color 0.2s',\n },\n\n dangerButton: {\n padding: '12px 24px',\n background: 'var(--glyde-error)',\n color: 'white',\n border: 'none',\n borderRadius: '24px',\n fontSize: '15px',\n fontWeight: 600,\n cursor: 'pointer',\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n transition: 'background-color 0.2s',\n },\n\n iconButton: {\n width: '44px',\n height: '44px',\n padding: '0',\n border: 'none',\n borderRadius: '50%',\n cursor: 'pointer',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n transition: 'background-color 0.2s',\n },\n\n // Input field\n inputField: {\n flex: 1,\n padding: '12px 16px',\n borderRadius: '8px',\n border: '1px solid var(--glyde-border)',\n background: 'var(--glyde-background)',\n color: 'var(--glyde-text)',\n fontSize: '14px',\n outline: 'none',\n transition: 'border-color 0.2s',\n },\n\n // Status badge\n statusBadge: {\n padding: '4px 10px',\n borderRadius: '20px',\n fontSize: '12px',\n fontWeight: 500,\n display: 'flex',\n alignItems: 'center',\n gap: '4px',\n },\n\n statusBadgeLive: {\n background: 'var(--glyde-success-light)',\n color: 'var(--glyde-success-text)',\n },\n\n statusBadgeConnecting: {\n background: 'var(--glyde-primary-light)',\n color: 'var(--glyde-primary)',\n },\n};\n\n/**\n * Get position styles for floating widget\n */\nexport function getPositionStyles(position: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left', offset = 20): { button: React.CSSProperties; panel: React.CSSProperties } {\n const positions = {\n 'bottom-right': {\n button: { bottom: offset, right: offset },\n panel: { bottom: offset + 70, right: offset },\n },\n 'bottom-left': {\n button: { bottom: offset, left: offset },\n panel: { bottom: offset + 70, left: offset },\n },\n 'top-right': {\n button: { top: offset, right: offset },\n panel: { top: offset + 70, right: offset },\n },\n 'top-left': {\n button: { top: offset, left: offset },\n panel: { top: offset + 70, left: offset },\n },\n };\n\n return positions[position];\n}\n\n/**\n * Inject global styles into the document\n */\nexport function injectGlobalStyles(theme: 'light' | 'dark' = 'light'): void {\n const styleId = 'glyde-widget-styles';\n \n // Check if styles are already injected\n if (document.getElementById(styleId)) {\n return;\n }\n\n const styleElement = document.createElement('style');\n styleElement.id = styleId;\n styleElement.textContent = `\n :root {\n ${getThemeCSSVariables(theme)}\n }\n\n ${globalStyles}\n `;\n\n document.head.appendChild(styleElement);\n}\n\n/**\n * Update theme CSS variables\n */\nexport function updateTheme(theme: 'light' | 'dark'): void {\n const styleId = 'glyde-widget-styles';\n const styleElement = document.getElementById(styleId);\n \n if (styleElement) {\n styleElement.textContent = `\n :root {\n ${getThemeCSSVariables(theme)}\n }\n\n ${globalStyles}\n `;\n } else {\n injectGlobalStyles(theme);\n }\n}\n","/**\n * GLYDE Voice SDK - VoiceChat Component\n * \n * Full voice chat UI component with transcript display, speaking indicators,\n * and call controls.\n * \n * @example\n * <VoiceChat\n * publishableKey=\"pk_...\"\n * contextType=\"screening\"\n * contextId=\"application-uuid\"\n * unityApiUrl=\"https://api.glydeunity.com\"\n * />\n */\n\nimport React, { useRef, useEffect } from 'react';\nimport { useVoiceAgent } from '../hooks/useVoiceAgent';\nimport type { VoiceContextType, Transcript } from '../core/types';\nimport { MicIcon, PhoneOffIcon, VolumeXIcon, ActivityIcon, MessageIcon } from '../ui/icons';\nimport { componentStyles } from '../ui/styles';\n\n/**\n * VoiceChat component props\n */\nexport interface VoiceChatProps {\n /** Application UUID (context ID for screening) */\n contextId: string;\n /** Publishable key for authentication */\n publishableKey?: string;\n /** API key for authentication */\n apiKey?: string;\n /** JWT auth token for GLYDEBuddy passthrough */\n authToken?: string;\n /** Unity API URL */\n unityApiUrl?: string;\n /** Voice context type */\n contextType?: VoiceContextType;\n /** Fixed height for the component */\n height?: string | number;\n /** Callback when transcript is added */\n onTranscript?: (text: string, role: 'user' | 'agent') => void;\n /** Callback when call ends */\n onCallEnd?: () => void;\n /** Callback when error occurs */\n onError?: (error: Error) => void;\n}\n\n/**\n * VoiceChat Component\n * \n * Provides a complete voice chat interface with:\n * - Start/stop call controls\n * - Real-time transcript display\n * - Speaking indicators (user and agent)\n * - Mute/unmute toggle\n */\nexport const VoiceChat: React.FC<VoiceChatProps> = ({\n contextId,\n publishableKey,\n apiKey,\n authToken,\n unityApiUrl = 'https://api.glydeunity.com',\n contextType = 'screening',\n height = '600px',\n onTranscript,\n onCallEnd,\n onError,\n}) => {\n const transcriptEndRef = useRef<HTMLDivElement>(null);\n\n const {\n status,\n transcripts,\n isUserSpeaking,\n isAgentSpeaking,\n isMuted,\n errorMessage,\n start,\n stop,\n toggleMute,\n clearTranscripts,\n } = useVoiceAgent({\n publishableKey,\n apiKey,\n authToken,\n contextType,\n contextId,\n unityBaseUrl: unityApiUrl,\n });\n\n // Auto-scroll transcripts\n useEffect(() => {\n transcriptEndRef.current?.scrollIntoView({ behavior: 'smooth' });\n }, [transcripts]);\n\n // Notify parent of transcripts\n useEffect(() => {\n if (onTranscript && transcripts.length > 0) {\n const latest = transcripts[transcripts.length - 1];\n onTranscript(latest.content, latest.role as 'user' | 'agent');\n }\n }, [transcripts, onTranscript]);\n\n // Notify parent of errors\n useEffect(() => {\n if (status === 'error' && errorMessage && onError) {\n onError(new Error(errorMessage));\n }\n }, [status, errorMessage, onError]);\n\n /**\n * Get context type display name\n */\n const getContextTypeDisplay = () => {\n switch (contextType) {\n case 'screening': return 'Screening Interview';\n case 'recruiter': return 'Recruiter Copilot';\n case 'custom': return 'Custom Agent';\n case 'phone': return 'Phone Agent';\n default: return 'Voice Interview';\n }\n };\n\n /**\n * Handle start call\n */\n const handleStartCall = async () => {\n clearTranscripts();\n await start();\n };\n\n /**\n * Handle end call\n */\n const handleEndCall = () => {\n stop();\n onCallEnd?.();\n };\n\n return (\n <div style={{ \n background: 'var(--glyde-background, white)', \n borderRadius: '12px', \n boxShadow: '0 4px 6px rgba(0,0,0,0.1)',\n height: typeof height === 'number' ? `${height}px` : height,\n display: 'flex',\n flexDirection: 'column',\n overflow: 'hidden',\n }}>\n {/* Header */}\n <div style={{ \n padding: '16px 20px', \n borderBottom: '1px solid var(--glyde-border, #e5e7eb)',\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center'\n }}>\n <div>\n <h2 style={{ margin: 0, fontSize: '1.1rem', fontWeight: 600, color: 'var(--glyde-text, #1f2937)' }}>\n {getContextTypeDisplay()}\n </h2>\n <small style={{ color: 'var(--glyde-text-secondary, #6b7280)', fontSize: '0.8rem' }}>\n {authToken ? 'JWT Auth' : publishableKey ? 'Publishable Key' : 'API Key'}\n </small>\n </div>\n {status === 'active' && (\n <div style={{ \n ...componentStyles.statusBadge,\n ...componentStyles.statusBadgeLive,\n }}>\n <ActivityIcon size={14} /> Live\n </div>\n )}\n </div>\n\n {/* Main Content */}\n <div style={{ flex: 1, display: 'flex', flexDirection: 'column', overflow: 'hidden' }}>\n {status === 'idle' || status === 'error' ? (\n /* Idle State */\n <div style={{ \n flex: 1, \n display: 'flex', \n flexDirection: 'column', \n alignItems: 'center', \n justifyContent: 'center',\n padding: '40px'\n }}>\n <div style={{ \n width: '100px', \n height: '100px', \n borderRadius: '50%', \n background: 'var(--glyde-primary-light, #fdf4ff)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n marginBottom: '24px'\n }}>\n <MicIcon size={48} color=\"var(--glyde-primary, #c026d3)\" />\n </div>\n <h3 style={{ marginBottom: '8px', color: 'var(--glyde-text, #1f2937)' }}>\n Ready for {getContextTypeDisplay()}?\n </h3>\n <p style={{ \n color: 'var(--glyde-text-secondary, #666)', \n marginBottom: '24px', \n textAlign: 'center', \n maxWidth: '280px' \n }}>\n {contextType === 'screening' \n ? 'The AI recruiter will speak with you. Make sure your microphone is ready.'\n : contextType === 'recruiter'\n ? 'The AI copilot will assist you with recruiting tasks.'\n : 'The AI agent will speak with you. Make sure your microphone is ready.'\n }\n </p>\n <button \n onClick={handleStartCall}\n style={{\n ...componentStyles.primaryButton,\n padding: '14px 36px',\n borderRadius: '30px',\n boxShadow: '0 4px 12px rgba(192, 38, 211, 0.3)',\n }}\n >\n Start {contextType === 'screening' ? 'Interview' : 'Call'}\n </button>\n {errorMessage && (\n <p style={{ color: 'var(--glyde-error, #ef4444)', marginTop: '16px', fontSize: '0.9rem' }}>\n {errorMessage}\n </p>\n )}\n </div>\n ) : (\n /* Active/Connecting State */\n <>\n {/* Transcript Area */}\n <div style={{ \n flex: 1, \n overflowY: 'auto', \n padding: '16px',\n background: 'var(--glyde-surface, #f9fafb)'\n }}>\n {status === 'connecting' && (\n <div style={{ textAlign: 'center', color: 'var(--glyde-text-secondary, #6b7280)', padding: '40px' }}>\n <div className=\"glyde-spinner\" style={{ margin: '0 auto 12px' }} />\n Connecting to AI Agent...\n </div>\n )}\n \n {transcripts.length === 0 && status === 'active' && (\n <div style={{ textAlign: 'center', color: 'var(--glyde-text-muted, #9ca3af)', padding: '40px' }}>\n <MessageIcon size={32} color=\"var(--glyde-text-muted, #9ca3af)\" />\n <p style={{ marginTop: '8px' }}>Start speaking - the AI will respond</p>\n </div>\n )}\n\n {transcripts.map((t, i) => (\n <TranscriptMessage key={i} transcript={t} contextType={contextType} />\n ))}\n <div ref={transcriptEndRef} />\n </div>\n\n {/* Status & Controls */}\n <div style={{ \n padding: '16px', \n borderTop: '1px solid var(--glyde-border, #e5e7eb)',\n background: 'var(--glyde-background, white)'\n }}>\n {/* Speaking Indicators */}\n <SpeakingIndicators \n isUserSpeaking={isUserSpeaking} \n isAgentSpeaking={isAgentSpeaking} \n />\n\n {/* Control Buttons */}\n <div style={{ display: 'flex', justifyContent: 'center', gap: '12px', marginTop: '16px' }}>\n <button \n onClick={toggleMute}\n style={{\n ...componentStyles.iconButton,\n background: isMuted ? 'var(--glyde-error-light, #fecaca)' : 'var(--glyde-secondary-light, #e0f2fe)',\n }}\n title={isMuted ? 'Unmute' : 'Mute'}\n >\n {isMuted \n ? <VolumeXIcon size={20} color=\"var(--glyde-error, #dc2626)\" /> \n : <MicIcon size={20} color=\"var(--glyde-secondary, #0ea5e9)\" />\n }\n </button>\n <button \n onClick={handleEndCall}\n style={componentStyles.dangerButton}\n >\n <PhoneOffIcon size={18} color=\"white\" /> End Call\n </button>\n </div>\n </div>\n </>\n )}\n </div>\n\n {/* Inline styles for animations */}\n <style>{`\n @keyframes glyde-pulse {\n 0%, 100% { opacity: 1; transform: scale(1); }\n 50% { opacity: 0.5; transform: scale(1.2); }\n }\n .glyde-spinner {\n width: 32px;\n height: 32px;\n border: 3px solid var(--glyde-border, #e5e7eb);\n border-top-color: var(--glyde-primary, #c026d3);\n border-radius: 50%;\n animation: spin 1s linear infinite;\n }\n @keyframes spin {\n to { transform: rotate(360deg); }\n }\n `}</style>\n </div>\n );\n};\n\n/**\n * Transcript message component\n */\nconst TranscriptMessage: React.FC<{ transcript: Transcript; contextType: VoiceContextType }> = ({ \n transcript, \n contextType \n}) => {\n const isUser = transcript.role === 'user';\n \n return (\n <div style={{\n marginBottom: '12px',\n display: 'flex',\n justifyContent: isUser ? 'flex-end' : 'flex-start'\n }}>\n <div style={{\n ...componentStyles.messageBubble,\n ...(isUser ? componentStyles.messageBubbleUser : componentStyles.messageBubbleAgent),\n }}>\n <div style={{ fontSize: '0.75rem', opacity: 0.7, marginBottom: '4px' }}>\n {isUser ? 'You' : contextType === 'recruiter' ? 'AI Copilot' : 'AI Recruiter'}\n </div>\n {transcript.content}\n </div>\n </div>\n );\n};\n\n/**\n * Speaking indicators component\n */\nconst SpeakingIndicators: React.FC<{ isUserSpeaking: boolean; isAgentSpeaking: boolean }> = ({\n isUserSpeaking,\n isAgentSpeaking,\n}) => (\n <div style={{ \n display: 'flex', \n justifyContent: 'center', \n gap: '20px',\n }}>\n <div style={{ \n ...componentStyles.speakingIndicator,\n color: isUserSpeaking ? 'var(--glyde-primary, #c026d3)' : 'var(--glyde-text-muted, #9ca3af)'\n }}>\n <div style={{\n ...componentStyles.speakingDot,\n background: isUserSpeaking ? 'var(--glyde-primary, #c026d3)' : 'var(--glyde-border, #d1d5db)',\n animation: isUserSpeaking ? 'glyde-pulse 1s infinite' : 'none'\n }} />\n You\n </div>\n <div style={{ \n ...componentStyles.speakingIndicator,\n color: isAgentSpeaking ? 'var(--glyde-success, #059669)' : 'var(--glyde-text-muted, #9ca3af)'\n }}>\n <div style={{\n ...componentStyles.speakingDot,\n background: isAgentSpeaking ? 'var(--glyde-success, #059669)' : 'var(--glyde-border, #d1d5db)',\n animation: isAgentSpeaking ? 'glyde-pulse 1s infinite' : 'none'\n }} />\n AI Agent\n </div>\n </div>\n);\n\nexport default VoiceChat;\n","/**\n * GLYDE Voice SDK - TextChat Component\n * \n * Full text chat UI component with message display, input field,\n * and loading indicators.\n * \n * @example\n * <TextChat\n * publishableKey=\"pk_...\"\n * contextId=\"application-uuid\"\n * unityApiUrl=\"https://api.glydeunity.com\"\n * />\n */\n\nimport React, { useState, useRef, useEffect } from 'react';\nimport { useTextChat } from '../hooks/useTextChat';\nimport type { ChatMessage } from '../core/types';\nimport { SendIcon, UserIcon, BotIcon } from '../ui/icons';\nimport { componentStyles } from '../ui/styles';\n\n/**\n * TextChat component props\n */\nexport interface TextChatProps {\n /** Application UUID (context ID for screening) */\n contextId: string;\n /** Publishable key for authentication */\n publishableKey?: string;\n /** API key for authentication */\n apiKey?: string;\n /** JWT auth token for GLYDEBuddy passthrough */\n authToken?: string;\n /** Unity API URL */\n unityApiUrl?: string;\n /** Fixed height for the component */\n height?: string | number;\n /** Header title */\n title?: string;\n /** Placeholder text for input */\n placeholder?: string;\n /** Auto-initialize chat on mount */\n autoInit?: boolean;\n /** Callback when message is sent */\n onMessage?: (message: ChatMessage) => void;\n /** Callback when error occurs */\n onError?: (error: Error) => void;\n}\n\n/**\n * TextChat Component\n * \n * Provides a complete text chat interface with:\n * - Message history display\n * - Text input with send button\n * - Loading indicators\n * - Auto-scroll to latest messages\n */\nexport const TextChat: React.FC<TextChatProps> = ({\n contextId,\n publishableKey,\n apiKey,\n authToken,\n unityApiUrl = 'https://api.glydeunity.com',\n height = '600px',\n title = 'AI Chat',\n placeholder = 'Type your message...',\n autoInit = true,\n onMessage,\n onError,\n}) => {\n const [inputValue, setInputValue] = useState('');\n const messagesEndRef = useRef<HTMLDivElement>(null);\n\n const {\n status,\n messages,\n isLoading,\n errorMessage,\n sendMessage,\n } = useTextChat({\n publishableKey,\n apiKey,\n authToken,\n contextId,\n unityBaseUrl: unityApiUrl,\n autoInit,\n });\n\n // Auto-scroll to bottom\n useEffect(() => {\n messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });\n }, [messages]);\n\n // Notify parent of errors\n useEffect(() => {\n if (status === 'error' && errorMessage && onError) {\n onError(new Error(errorMessage));\n }\n }, [status, errorMessage, onError]);\n\n /**\n * Handle send message\n */\n const handleSend = async () => {\n if (!inputValue.trim() || isLoading) return;\n\n const messageText = inputValue.trim();\n setInputValue('');\n \n await sendMessage(messageText);\n \n // Notify parent\n if (onMessage) {\n onMessage({ role: 'user', content: messageText });\n }\n };\n\n /**\n * Handle key press (Enter to send)\n */\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault();\n handleSend();\n }\n };\n\n return (\n <div style={{ \n background: 'var(--glyde-background, white)', \n borderRadius: '12px', \n boxShadow: '0 4px 6px rgba(0,0,0,0.1)',\n height: typeof height === 'number' ? `${height}px` : height,\n display: 'flex',\n flexDirection: 'column',\n overflow: 'hidden',\n }}>\n {/* Header */}\n <div style={{ \n padding: '16px 20px', \n borderBottom: '1px solid var(--glyde-border, #eee)',\n background: 'var(--glyde-secondary, #0284c7)',\n color: 'white',\n borderTopLeftRadius: '12px',\n borderTopRightRadius: '12px'\n }}>\n <h2 style={{ margin: 0, fontSize: '1.1rem', fontWeight: 600 }}>{title}</h2>\n </div>\n\n {/* Messages Area */}\n <div style={{ \n flex: 1, \n overflowY: 'auto', \n padding: '20px',\n display: 'flex',\n flexDirection: 'column',\n gap: '15px',\n background: 'var(--glyde-background, white)',\n }}>\n {status === 'loading' && messages.length === 0 && (\n <div style={{ textAlign: 'center', color: 'var(--glyde-text-muted, #94a3b8)', padding: '20px' }}>\n <div className=\"glyde-spinner\" style={{ margin: '0 auto 12px' }} />\n Loading conversation...\n </div>\n )}\n\n {messages.map((msg, idx) => (\n <ChatMessageBubble key={idx} message={msg} />\n ))}\n \n {isLoading && (\n <div style={{ color: 'var(--glyde-text-muted, #94a3b8)', fontSize: '0.9rem', marginLeft: '42px' }}>\n <TypingIndicator />\n </div>\n )}\n \n <div ref={messagesEndRef} />\n </div>\n\n {/* Input Area */}\n <div style={{ padding: '16px 20px', borderTop: '1px solid var(--glyde-border, #eee)' }}>\n {errorMessage && (\n <p style={{ \n color: 'var(--glyde-error, #ef4444)', \n fontSize: '0.85rem', \n marginBottom: '10px' \n }}>\n {errorMessage}\n </p>\n )}\n <div style={{ display: 'flex', gap: '10px' }}>\n <input\n type=\"text\"\n value={inputValue}\n onChange={(e) => setInputValue(e.target.value)}\n onKeyDown={handleKeyDown}\n placeholder={placeholder}\n style={{ \n ...componentStyles.inputField,\n flex: 1,\n }}\n disabled={isLoading}\n />\n <button \n onClick={handleSend}\n disabled={isLoading || !inputValue.trim()}\n style={{ \n ...componentStyles.iconButton,\n background: 'var(--glyde-secondary, #0284c7)', \n width: '48px',\n height: '48px',\n opacity: isLoading || !inputValue.trim() ? 0.5 : 1,\n cursor: isLoading || !inputValue.trim() ? 'not-allowed' : 'pointer',\n }}\n >\n <SendIcon size={20} color=\"white\" />\n </button>\n </div>\n </div>\n\n {/* Inline styles */}\n <style>{`\n .glyde-spinner {\n width: 24px;\n height: 24px;\n border: 2px solid var(--glyde-border, #e5e7eb);\n border-top-color: var(--glyde-secondary, #0284c7);\n border-radius: 50%;\n animation: spin 1s linear infinite;\n }\n @keyframes spin {\n to { transform: rotate(360deg); }\n }\n @keyframes typing-dot {\n 0%, 60%, 100% { opacity: 0.3; }\n 30% { opacity: 1; }\n }\n `}</style>\n </div>\n );\n};\n\n/**\n * Chat message bubble component\n */\nconst ChatMessageBubble: React.FC<{ message: ChatMessage }> = ({ message }) => {\n const isUser = message.role === 'user';\n \n return (\n <div style={{ \n display: 'flex', \n gap: '10px', \n flexDirection: isUser ? 'row-reverse' : 'row',\n alignItems: 'flex-start'\n }}>\n {/* Avatar */}\n <div style={{ \n width: '32px', \n height: '32px', \n borderRadius: '50%', \n background: isUser ? 'var(--glyde-primary-light, #e0e7ff)' : 'var(--glyde-secondary-light, #f0f9ff)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n flexShrink: 0,\n }}>\n {isUser \n ? <UserIcon size={18} color=\"var(--glyde-primary, #4338ca)\" /> \n : <BotIcon size={18} color=\"var(--glyde-secondary, #0284c7)\" />\n }\n </div>\n \n {/* Message */}\n <div style={{ \n padding: '12px 16px', \n borderRadius: '12px', \n background: isUser ? 'var(--glyde-primary, #4338ca)' : 'var(--glyde-surface, #f1f5f9)',\n color: isUser ? 'white' : 'var(--glyde-text, #1e293b)',\n maxWidth: '70%',\n borderTopRightRadius: isUser ? '4px' : '12px',\n borderTopLeftRadius: isUser ? '12px' : '4px',\n lineHeight: 1.5,\n }}>\n {message.content}\n </div>\n </div>\n );\n};\n\n/**\n * Typing indicator component\n */\nconst TypingIndicator: React.FC = () => (\n <div style={{ display: 'flex', alignItems: 'center', gap: '4px' }}>\n <span>Typing</span>\n <span style={{ display: 'flex', gap: '2px' }}>\n {[0, 1, 2].map((i) => (\n <span\n key={i}\n style={{\n width: '4px',\n height: '4px',\n borderRadius: '50%',\n background: 'var(--glyde-text-muted, #94a3b8)',\n animation: `typing-dot 1.4s infinite`,\n animationDelay: `${i * 0.2}s`,\n }}\n />\n ))}\n </span>\n </div>\n);\n\nexport default TextChat;\n","/**\n * GLYDE Voice SDK - ChatWidget Component\n * \n * Floating chat widget with voice/text mode selection.\n * This is the main component for CDN auto-inject usage.\n * \n * @example\n * <ChatWidget\n * publishableKey=\"pk_...\"\n * contextId=\"application-uuid\"\n * unityApiUrl=\"https://api.glydeunity.com\"\n * position=\"bottom-right\"\n * />\n */\n\nimport React, { useState, useEffect } from 'react';\nimport { VoiceChat } from './VoiceChat';\nimport { TextChat } from './TextChat';\nimport type { ChatWidgetConfig, ChatMode, VoiceContextType } from '../core/types';\nimport { MicIcon, MessageIcon, XIcon, MinimizeIcon } from '../ui/icons';\nimport { componentStyles, getPositionStyles, injectGlobalStyles } from '../ui/styles';\n\n/**\n * ChatWidget component props (extends ChatWidgetConfig)\n */\nexport interface ChatWidgetProps extends ChatWidgetConfig {\n /** Initial expanded state */\n initialExpanded?: boolean;\n}\n\n/**\n * ChatWidget Component\n * \n * A floating chat widget that provides:\n * - Voice and text chat modes\n * - Mode selection toggle\n * - Floating button to open/close\n * - Configurable position\n * - Theme support\n */\nexport const ChatWidget: React.FC<ChatWidgetProps> = ({\n publishableKey,\n apiKey,\n authToken,\n contextId,\n unityBaseUrl = 'https://api.glydeunity.com',\n contextType = 'screening',\n defaultMode = 'voice',\n position = 'bottom-right',\n theme = 'light',\n allowModeSwitch = true,\n container,\n onReady,\n onModeChange,\n onTranscript,\n onError,\n initialExpanded = false,\n}) => {\n const [isExpanded, setIsExpanded] = useState(initialExpanded);\n const [mode, setMode] = useState<ChatMode>(defaultMode);\n\n // Inject global styles on mount\n useEffect(() => {\n const themeMode = theme === 'auto' \n ? (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light')\n : theme;\n injectGlobalStyles(themeMode);\n }, [theme]);\n\n // Notify when ready\n useEffect(() => {\n onReady?.();\n }, [onReady]);\n\n // Get position styles\n const positionStyles = getPositionStyles(position);\n\n /**\n * Handle mode change\n */\n const handleModeChange = (newMode: ChatMode) => {\n setMode(newMode);\n onModeChange?.(newMode);\n };\n\n /**\n * Handle transcript from either voice or text chat\n */\n const handleTranscript = (text: string, role: 'user' | 'agent') => {\n onTranscript?.(text, role);\n };\n\n /**\n * Handle error from either voice or text chat\n */\n const handleError = (error: Error) => {\n onError?.(error);\n };\n\n // If container is specified, render inline instead of floating\n if (container) {\n return (\n <InlineWidget\n publishableKey={publishableKey}\n apiKey={apiKey}\n authToken={authToken}\n contextId={contextId}\n unityBaseUrl={unityBaseUrl}\n contextType={contextType}\n mode={mode}\n allowModeSwitch={allowModeSwitch}\n onModeChange={handleModeChange}\n onTranscript={handleTranscript}\n onError={handleError}\n />\n );\n }\n\n return (\n <div className=\"glyde-widget-root\">\n {/* Floating Button */}\n {!isExpanded && (\n <button\n onClick={() => setIsExpanded(true)}\n style={{\n ...componentStyles.floatingButton,\n ...positionStyles.button,\n background: 'linear-gradient(135deg, var(--glyde-primary, #c026d3) 0%, var(--glyde-secondary, #7c3aed) 100%)',\n }}\n aria-label=\"Open chat\"\n >\n <MicIcon size={28} color=\"white\" />\n </button>\n )}\n\n {/* Expanded Panel */}\n {isExpanded && (\n <div\n style={{\n ...componentStyles.widgetPanel,\n ...positionStyles.panel,\n background: 'var(--glyde-background, white)',\n }}\n className=\"glyde-slide-up\"\n >\n {/* Header with close button */}\n <div style={{\n ...componentStyles.header,\n background: 'linear-gradient(135deg, var(--glyde-primary, #c026d3) 0%, var(--glyde-secondary, #7c3aed) 100%)',\n color: 'white',\n borderTopLeftRadius: '16px',\n borderTopRightRadius: '16px',\n }}>\n <div>\n <h3 style={{ margin: 0, fontSize: '1rem', fontWeight: 600 }}>\n GLYDE Assistant\n </h3>\n <small style={{ opacity: 0.8, fontSize: '0.75rem' }}>\n {contextType === 'screening' ? 'Candidate Screening' : 'AI Assistant'}\n </small>\n </div>\n <div style={{ display: 'flex', gap: '8px' }}>\n <button\n onClick={() => setIsExpanded(false)}\n style={{\n ...componentStyles.iconButton,\n background: 'rgba(255,255,255,0.2)',\n width: '32px',\n height: '32px',\n }}\n aria-label=\"Minimize\"\n >\n <MinimizeIcon size={16} color=\"white\" />\n </button>\n <button\n onClick={() => setIsExpanded(false)}\n style={{\n ...componentStyles.iconButton,\n background: 'rgba(255,255,255,0.2)',\n width: '32px',\n height: '32px',\n }}\n aria-label=\"Close\"\n >\n <XIcon size={16} color=\"white\" />\n </button>\n </div>\n </div>\n\n {/* Mode Selector */}\n {allowModeSwitch && (\n <div style={{\n padding: '12px 16px',\n borderBottom: '1px solid var(--glyde-border, #e5e7eb)',\n }}>\n <ModeSelector mode={mode} onModeChange={handleModeChange} />\n </div>\n )}\n\n {/* Chat Content */}\n <div style={{ flex: 1, display: 'flex', flexDirection: 'column', overflow: 'hidden' }}>\n {mode === 'voice' ? (\n <VoiceChat\n publishableKey={publishableKey}\n apiKey={apiKey}\n authToken={authToken}\n contextId={contextId || ''}\n unityApiUrl={unityBaseUrl}\n contextType={contextType}\n height=\"100%\"\n onTranscript={handleTranscript}\n onError={handleError}\n />\n ) : (\n <TextChat\n publishableKey={publishableKey}\n apiKey={apiKey}\n authToken={authToken}\n contextId={contextId || ''}\n unityApiUrl={unityBaseUrl}\n height=\"100%\"\n title=\"Text Chat\"\n onError={handleError}\n />\n )}\n </div>\n </div>\n )}\n </div>\n );\n};\n\n/**\n * Mode selector component\n */\nconst ModeSelector: React.FC<{\n mode: ChatMode;\n onModeChange: (mode: ChatMode) => void;\n}> = ({ mode, onModeChange }) => (\n <div style={componentStyles.modeSelector}>\n <button\n onClick={() => onModeChange('voice')}\n style={{\n ...componentStyles.modeSelectorButton,\n background: mode === 'voice' ? 'var(--glyde-primary, #c026d3)' : 'transparent',\n color: mode === 'voice' ? 'white' : 'var(--glyde-text, #1f2937)',\n }}\n >\n <MicIcon size={16} /> Voice\n </button>\n <button\n onClick={() => onModeChange('text')}\n style={{\n ...componentStyles.modeSelectorButton,\n background: mode === 'text' ? 'var(--glyde-secondary, #0284c7)' : 'transparent',\n color: mode === 'text' ? 'white' : 'var(--glyde-text, #1f2937)',\n }}\n >\n <MessageIcon size={16} /> Text\n </button>\n </div>\n);\n\n/**\n * Inline widget (non-floating) for custom container usage\n */\nconst InlineWidget: React.FC<{\n publishableKey?: string;\n apiKey?: string;\n authToken?: string;\n contextId?: string;\n unityBaseUrl: string;\n contextType: VoiceContextType;\n mode: ChatMode;\n allowModeSwitch: boolean;\n onModeChange: (mode: ChatMode) => void;\n onTranscript?: (text: string, role: 'user' | 'agent') => void;\n onError?: (error: Error) => void;\n}> = ({\n publishableKey,\n apiKey,\n authToken,\n contextId,\n unityBaseUrl,\n contextType,\n mode,\n allowModeSwitch,\n onModeChange,\n onTranscript,\n onError,\n}) => {\n const [currentMode, setCurrentMode] = useState<ChatMode>(mode);\n\n const handleModeChange = (newMode: ChatMode) => {\n setCurrentMode(newMode);\n onModeChange(newMode);\n };\n\n return (\n <div className=\"glyde-widget-root\" style={{ height: '100%', display: 'flex', flexDirection: 'column' }}>\n {/* Mode Selector */}\n {allowModeSwitch && (\n <div style={{\n padding: '12px 16px',\n borderBottom: '1px solid var(--glyde-border, #e5e7eb)',\n background: 'var(--glyde-background, white)',\n }}>\n <ModeSelector mode={currentMode} onModeChange={handleModeChange} />\n </div>\n )}\n\n {/* Chat Content */}\n <div style={{ flex: 1, overflow: 'hidden' }}>\n {currentMode === 'voice' ? (\n <VoiceChat\n publishableKey={publishableKey}\n apiKey={apiKey}\n authToken={authToken}\n contextId={contextId || ''}\n unityApiUrl={unityBaseUrl}\n contextType={contextType}\n height=\"100%\"\n onTranscript={onTranscript}\n onError={onError}\n />\n ) : (\n <TextChat\n publishableKey={publishableKey}\n apiKey={apiKey}\n authToken={authToken}\n contextId={contextId || ''}\n unityApiUrl={unityBaseUrl}\n height=\"100%\"\n title=\"Text Chat\"\n onError={onError}\n />\n )}\n </div>\n </div>\n );\n};\n\nexport default ChatWidget;\n","/**\n * GLYDE Voice SDK - CDN Auto-Initialization\n * \n * Provides static methods for CDN usage and auto-initialization from data attributes.\n * \n * @example\n * // Via script tag\n * <script src=\"https://cdn.glyde.com/voice-sdk/v1.4.0/glyde-chat.umd.js\"></script>\n * <script>\n * GlydeChat.init({\n * publishableKey: 'pk_...',\n * contextId: 'uuid...',\n * unityBaseUrl: 'https://api.glydeunity.com'\n * });\n * </script>\n * \n * @example\n * // Via data attributes (auto-init)\n * <script \n * src=\"https://cdn.glyde.com/voice-sdk/v1.4.0/glyde-chat.umd.js\"\n * data-publishable-key=\"pk_...\"\n * data-context-id=\"uuid...\"\n * data-auto-init=\"true\"\n * ></script>\n */\n\nimport React from 'react';\nimport { createRoot, Root } from 'react-dom/client';\nimport { ChatWidget } from '../components/ChatWidget';\nimport type { ChatWidgetConfig, ChatMode, WidgetPosition, ThemeMode, VoiceContextType } from '../core/types';\nimport { injectGlobalStyles } from '../ui/styles';\n\n/**\n * Active widget instance tracking\n */\nlet activeRoot: Root | null = null;\nlet activeContainer: HTMLElement | null = null;\n\n/**\n * GlydeChat - CDN entry point\n * \n * Provides static methods for initializing and controlling the chat widget.\n */\nexport const GlydeChat = {\n /**\n * Initialize the chat widget\n * \n * @param config - Widget configuration\n * @returns Control object for the widget\n */\n init(config: ChatWidgetConfig) {\n // Validate required fields\n if (!config.publishableKey && !config.apiKey && !config.authToken) {\n console.error('[GlydeChat] Authentication required: provide publishableKey, apiKey, or authToken');\n return null;\n }\n\n // Inject global styles\n const themeMode = config.theme === 'auto' \n ? (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light')\n : (config.theme || 'light');\n injectGlobalStyles(themeMode);\n\n // Clean up existing widget if any\n if (activeRoot && activeContainer) {\n activeRoot.unmount();\n activeContainer.remove();\n activeRoot = null;\n activeContainer = null;\n }\n\n // Create container element\n const container = document.createElement('div');\n container.id = 'glyde-chat-widget';\n container.className = 'glyde-widget-root';\n document.body.appendChild(container);\n activeContainer = container;\n\n // Create React root and render\n const root = createRoot(container);\n activeRoot = root;\n\n root.render(\n React.createElement(ChatWidget, {\n ...config,\n initialExpanded: false,\n })\n );\n\n console.log('[GlydeChat] Widget initialized');\n\n // Return control object\n return {\n /**\n * Destroy the widget\n */\n destroy() {\n if (activeRoot && activeContainer) {\n activeRoot.unmount();\n activeContainer.remove();\n activeRoot = null;\n activeContainer = null;\n console.log('[GlydeChat] Widget destroyed');\n }\n },\n\n /**\n * Update widget configuration\n */\n update(newConfig: Partial<ChatWidgetConfig>) {\n if (activeRoot) {\n activeRoot.render(\n React.createElement(ChatWidget, {\n ...config,\n ...newConfig,\n })\n );\n }\n },\n };\n },\n\n /**\n * Render widget into a specific container (non-floating)\n * \n * @param container - DOM element or selector\n * @param config - Widget configuration\n */\n render(container: HTMLElement | string, config: ChatWidgetConfig) {\n const element = typeof container === 'string' \n ? document.querySelector(container) \n : container;\n\n if (!element) {\n console.error('[GlydeChat] Container not found:', container);\n return null;\n }\n\n // Inject global styles\n const themeMode = config.theme === 'auto' \n ? (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light')\n : (config.theme || 'light');\n injectGlobalStyles(themeMode);\n\n // Create React root and render\n const root = createRoot(element);\n\n root.render(\n React.createElement(ChatWidget, {\n ...config,\n container: element as HTMLElement,\n })\n );\n\n return {\n destroy() {\n root.unmount();\n },\n update(newConfig: Partial<ChatWidgetConfig>) {\n root.render(\n React.createElement(ChatWidget, {\n ...config,\n ...newConfig,\n container: element as HTMLElement,\n })\n );\n },\n };\n },\n\n /**\n * Check if the SDK is loaded and ready\n */\n isReady(): boolean {\n return true;\n },\n\n /**\n * Get SDK version\n */\n get version(): string {\n return '__SDK_VERSION__'; // Replaced at build time\n },\n};\n\n/**\n * Auto-initialize from script tag data attributes\n * \n * Auto-init triggers when:\n * - data-auto-init=\"true\" is explicitly set, OR\n * - data-publishable-key, data-api-key, or data-auth-token is present\n * \n * To disable auto-init, set data-auto-init=\"false\"\n */\nfunction autoInit() {\n // Find the script tag that loaded this SDK\n const scripts = document.querySelectorAll('script[src*=\"glyde-chat\"]');\n const currentScript = scripts[scripts.length - 1];\n\n if (!currentScript) {\n console.log('[GlydeChat] No script tag found for auto-init');\n return;\n }\n\n // Check for explicit disable\n const autoInitAttr = currentScript.getAttribute('data-auto-init');\n if (autoInitAttr === 'false') {\n console.log('[GlydeChat] Auto-init disabled via data-auto-init=\"false\"');\n return;\n }\n\n // Parse configuration from data attributes\n const publishableKey = currentScript.getAttribute('data-publishable-key') || undefined;\n const apiKey = currentScript.getAttribute('data-api-key') || undefined;\n const authToken = currentScript.getAttribute('data-auth-token') || undefined;\n\n // Auto-init if explicit flag OR if auth credentials are provided\n const hasAuth = publishableKey || apiKey || authToken;\n const explicitAutoInit = autoInitAttr === 'true';\n\n if (!hasAuth && !explicitAutoInit) {\n console.log('[GlydeChat] Auto-init skipped: no authentication data attributes found. Call GlydeChat.init() manually.');\n return;\n }\n\n if (!hasAuth) {\n console.warn('[GlydeChat] Auto-init skipped: no authentication provided (publishableKey, apiKey, or authToken required)');\n return;\n }\n\n const config: ChatWidgetConfig = {\n publishableKey,\n apiKey,\n authToken,\n contextId: currentScript.getAttribute('data-context-id') || undefined,\n unityBaseUrl: currentScript.getAttribute('data-unity-url') || 'https://api.glydeunity.com',\n contextType: (currentScript.getAttribute('data-context-type') as VoiceContextType) || 'screening',\n defaultMode: (currentScript.getAttribute('data-default-mode') as ChatMode) || 'voice',\n position: (currentScript.getAttribute('data-position') as WidgetPosition) || 'bottom-right',\n theme: (currentScript.getAttribute('data-theme') as ThemeMode) || 'light',\n allowModeSwitch: currentScript.getAttribute('data-allow-mode-switch') !== 'false',\n };\n\n console.log('[GlydeChat] Auto-initializing with config:', {\n hasPublishableKey: !!config.publishableKey,\n hasApiKey: !!config.apiKey,\n hasAuthToken: !!config.authToken,\n contextId: config.contextId,\n defaultMode: config.defaultMode,\n position: config.position,\n theme: config.theme,\n });\n\n // Initialize when DOM is ready\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', () => GlydeChat.init(config));\n } else {\n GlydeChat.init(config);\n }\n}\n\n// Auto-initialize when loaded\nif (typeof window !== 'undefined') {\n // Expose GlydeChat globally\n (window as unknown as Record<string, unknown>).GlydeChat = GlydeChat;\n \n // Attempt auto-init\n autoInit();\n}\n\nexport default GlydeChat;\n"],"names":["AUDIO_CAPTURE_PROCESSOR_CODE","AUDIO_PLAYBACK_PROCESSOR_CODE","GlydeVoice","config","headers","configUrl","configPath","response","error","data","authBody","authResponse","deepgramToken","agent_config","serverDeepgramConfig","systemPrompt","msg","agentUrl","deepgramConfig","params","tag","finalDeepgramConfig","settings","agentInstructions","event","updatePrompt","err","code","blob","captureWorkletUrl","playbackWorkletUrl","type","message","normalizedRole","e","arrayBuffer","buffer","byteLength","validByteLength","alignedBuffer","pcm16","float32_24k","i","float32_48k","audioData","input","outputLength","output","sample","nextSample","lastIdx","source","content","role","muted","track","container","request","func","parseError","functionName","functionCallId","errorData","result","trigger","context","GlydeText","isTyping","userMessage","assistantMessage","m","useVoiceAgent","status","setStatus","useState","transcripts","setTranscripts","isUserSpeaking","setIsUserSpeaking","isAgentSpeaking","setIsAgentSpeaking","isMuted","setIsMuted","errorMessage","setErrorMessage","voiceAgentRef","useRef","handleVoiceEvent","useCallback","handleTranscript","text","prev","start","agent","stop","toggleMute","newMuted","setMutedState","clearTranscripts","useEffect","useTextChat","messages","setMessages","isLoading","setIsLoading","textChatRef","initializedRef","getTextChat","initialize","history","sendMessage","chat","clearHistory","MicIcon","size","color","className","jsxs","jsx","MicOffIcon","PhoneIcon","PhoneOffIcon","MessageIcon","SendIcon","UserIcon","BotIcon","ActivityIcon","VolumeXIcon","XIcon","MinimizeIcon","LoaderIcon","themeColors","getThemeCSSVariables","theme","colors","globalStyles","componentStyles","getPositionStyles","position","offset","injectGlobalStyles","styleId","styleElement","updateTheme","VoiceChat","contextId","publishableKey","apiKey","authToken","unityApiUrl","contextType","height","onTranscript","onCallEnd","onError","transcriptEndRef","latest","getContextTypeDisplay","handleStartCall","handleEndCall","Fragment","t","TranscriptMessage","SpeakingIndicators","transcript","isUser","TextChat","title","placeholder","autoInit","onMessage","inputValue","setInputValue","messagesEndRef","handleSend","messageText","handleKeyDown","idx","ChatMessageBubble","TypingIndicator","ChatWidget","unityBaseUrl","defaultMode","allowModeSwitch","onReady","onModeChange","initialExpanded","isExpanded","setIsExpanded","mode","setMode","themeMode","positionStyles","handleModeChange","newMode","handleError","InlineWidget","ModeSelector","currentMode","setCurrentMode","activeRoot","activeContainer","GlydeChat","root","createRoot","React","newConfig","element","scripts","currentScript","autoInitAttr","hasAuth"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@glydeunity/voice-sdk",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "GLYDE Voice Agent SDK - AI-powered voice interactions for web applications",
|
|
3
|
+
"version": "1.4.1",
|
|
4
|
+
"description": "GLYDE Voice Agent SDK - AI-powered voice and text chat interactions for web applications",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"main": "./dist/
|
|
6
|
+
"main": "./dist/glyde-chat.umd.js",
|
|
7
7
|
"module": "./dist/voice-sdk.es.js",
|
|
8
8
|
"types": "./dist/index.d.ts",
|
|
9
9
|
"exports": {
|
|
10
10
|
".": {
|
|
11
11
|
"types": "./dist/index.d.ts",
|
|
12
12
|
"import": "./dist/voice-sdk.es.js",
|
|
13
|
-
"require": "./dist/
|
|
13
|
+
"require": "./dist/glyde-chat.umd.js"
|
|
14
14
|
}
|
|
15
15
|
},
|
|
16
16
|
"files": [
|
|
@@ -20,8 +20,12 @@
|
|
|
20
20
|
"scripts": {
|
|
21
21
|
"dev": "vite",
|
|
22
22
|
"build": "tsc && vite build",
|
|
23
|
+
"build:watch": "tsc --watch & vite build --watch",
|
|
24
|
+
"build:esm": "BUILD_FORMAT=esm tsc && vite build",
|
|
25
|
+
"build:umd": "BUILD_FORMAT=umd tsc && vite build",
|
|
23
26
|
"preview": "vite preview",
|
|
24
|
-
"clean": "rm -rf dist"
|
|
27
|
+
"clean": "rm -rf dist",
|
|
28
|
+
"typecheck": "tsc --noEmit"
|
|
25
29
|
},
|
|
26
30
|
"keywords": [
|
|
27
31
|
"voice",
|
|
@@ -32,7 +36,10 @@
|
|
|
32
36
|
"recruitment",
|
|
33
37
|
"chatbot",
|
|
34
38
|
"voice-agent",
|
|
35
|
-
"glyde"
|
|
39
|
+
"glyde",
|
|
40
|
+
"text-chat",
|
|
41
|
+
"react",
|
|
42
|
+
"widget"
|
|
36
43
|
],
|
|
37
44
|
"author": "GLYDE Inc.",
|
|
38
45
|
"license": "MIT",
|
|
@@ -46,6 +53,9 @@
|
|
|
46
53
|
},
|
|
47
54
|
"homepage": "https://github.com/Glyde-Inc/voice-agent-sdk#readme",
|
|
48
55
|
"devDependencies": {
|
|
56
|
+
"@types/react": "^19.0.0",
|
|
57
|
+
"@types/react-dom": "^19.0.0",
|
|
58
|
+
"@vitejs/plugin-react": "^4.4.1",
|
|
49
59
|
"typescript": "^5.9.3",
|
|
50
60
|
"vite": "^7.3.0",
|
|
51
61
|
"vite-plugin-dts": "^4.5.4"
|
|
@@ -54,10 +64,21 @@
|
|
|
54
64
|
"react": "^18.0.0 || ^19.0.0",
|
|
55
65
|
"react-dom": "^18.0.0 || ^19.0.0"
|
|
56
66
|
},
|
|
67
|
+
"peerDependenciesMeta": {
|
|
68
|
+
"react": {
|
|
69
|
+
"optional": true
|
|
70
|
+
},
|
|
71
|
+
"react-dom": {
|
|
72
|
+
"optional": true
|
|
73
|
+
}
|
|
74
|
+
},
|
|
57
75
|
"dependencies": {
|
|
58
76
|
"@deepgram/sdk": "^4.11.3"
|
|
59
77
|
},
|
|
60
78
|
"engines": {
|
|
61
79
|
"node": ">=22.0.0"
|
|
62
|
-
}
|
|
80
|
+
},
|
|
81
|
+
"sideEffects": [
|
|
82
|
+
"./dist/glyde-chat.umd.js"
|
|
83
|
+
]
|
|
63
84
|
}
|