@glydeunity/voice-sdk 1.3.5 → 1.4.0

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.
@@ -0,0 +1,265 @@
1
+ (function(c,l){typeof exports=="object"&&typeof module<"u"?l(exports,require("react"),require("react/jsx-runtime"),require("react-dom/client")):typeof define=="function"&&define.amd?define(["exports","react","react/jsx-runtime","react-dom/client"],l):(c=typeof globalThis<"u"?globalThis:c||self,l(c.GlydeChat={},c.React,c.jsxRuntime,c.ReactDOM))})(this,(function(c,l,t,V){"use strict";const oe=`
2
+ class AudioCaptureProcessor extends AudioWorkletProcessor {
3
+ constructor() {
4
+ super();
5
+ this.bufferSize = 4096;
6
+ this.buffer = new Float32Array(this.bufferSize);
7
+ this.bufferIndex = 0;
8
+ }
9
+
10
+ process(inputs) {
11
+ const input = inputs[0];
12
+ if (!input || !input[0]) return true;
13
+
14
+ const samples = input[0];
15
+
16
+ for (let i = 0; i < samples.length; i++) {
17
+ this.buffer[this.bufferIndex++] = samples[i];
18
+
19
+ if (this.bufferIndex >= this.bufferSize) {
20
+ const pcm16 = new Int16Array(this.bufferSize);
21
+ for (let j = 0; j < this.bufferSize; j++) {
22
+ const s = Math.max(-1, Math.min(1, this.buffer[j]));
23
+ pcm16[j] = s < 0 ? s * 0x8000 : s * 0x7FFF;
24
+ }
25
+
26
+ this.port.postMessage(pcm16.buffer, [pcm16.buffer]);
27
+ this.bufferIndex = 0;
28
+ }
29
+ }
30
+
31
+ return true;
32
+ }
33
+ }
34
+
35
+ registerProcessor('audio-capture-processor', AudioCaptureProcessor);
36
+ `,ie=`
37
+ class AudioPlaybackProcessor extends AudioWorkletProcessor {
38
+ constructor() {
39
+ super();
40
+
41
+ this.bufferSize = 48000 * 15;
42
+ this.buffer = new Float32Array(this.bufferSize);
43
+ this.writeIndex = 0;
44
+ this.readIndex = 0;
45
+ this.samplesAvailable = 0;
46
+ this.isPlaying = false;
47
+
48
+ this.port.onmessage = (event) => {
49
+ const { type, data } = event.data;
50
+
51
+ switch (type) {
52
+ case 'audio':
53
+ const audioData = data instanceof Float32Array ? data : new Float32Array(data);
54
+ this.writeAudio(audioData);
55
+ break;
56
+ case 'clear':
57
+ this.clearBuffer();
58
+ break;
59
+ }
60
+ };
61
+ }
62
+
63
+ writeAudio(samples) {
64
+ if (!samples || samples.length === 0) return;
65
+
66
+ const samplesToWrite = samples.length;
67
+
68
+ if (this.samplesAvailable + samplesToWrite > this.bufferSize) {
69
+ const overflow = (this.samplesAvailable + samplesToWrite) - this.bufferSize;
70
+ this.readIndex = (this.readIndex + overflow) % this.bufferSize;
71
+ this.samplesAvailable -= overflow;
72
+ }
73
+
74
+ for (let i = 0; i < samplesToWrite; i++) {
75
+ this.buffer[this.writeIndex] = samples[i];
76
+ this.writeIndex = (this.writeIndex + 1) % this.bufferSize;
77
+ }
78
+
79
+ this.samplesAvailable += samplesToWrite;
80
+ this.isPlaying = true;
81
+ }
82
+
83
+ clearBuffer() {
84
+ this.readIndex = 0;
85
+ this.writeIndex = 0;
86
+ this.samplesAvailable = 0;
87
+ this.isPlaying = false;
88
+ this.port.postMessage({ type: 'cleared' });
89
+ }
90
+
91
+ process(inputs, outputs) {
92
+ const output = outputs[0];
93
+ if (!output || !output[0]) return true;
94
+
95
+ const outputChannel = output[0];
96
+ const samplesToRead = outputChannel.length;
97
+
98
+ if (this.samplesAvailable >= samplesToRead) {
99
+ for (let i = 0; i < samplesToRead; i++) {
100
+ outputChannel[i] = this.buffer[this.readIndex];
101
+ this.readIndex = (this.readIndex + 1) % this.bufferSize;
102
+ }
103
+ this.samplesAvailable -= samplesToRead;
104
+ } else if (this.samplesAvailable > 0) {
105
+ let i = 0;
106
+ while (this.samplesAvailable > 0 && i < samplesToRead) {
107
+ outputChannel[i] = this.buffer[this.readIndex];
108
+ this.readIndex = (this.readIndex + 1) % this.bufferSize;
109
+ this.samplesAvailable--;
110
+ i++;
111
+ }
112
+ while (i < samplesToRead) {
113
+ outputChannel[i] = 0;
114
+ i++;
115
+ }
116
+
117
+ if (this.isPlaying) {
118
+ this.isPlaying = false;
119
+ this.port.postMessage({ type: 'bufferEmpty' });
120
+ }
121
+ } else {
122
+ for (let i = 0; i < samplesToRead; i++) {
123
+ outputChannel[i] = 0;
124
+ }
125
+ this.isPlaying = false;
126
+ }
127
+
128
+ return true;
129
+ }
130
+ }
131
+
132
+ registerProcessor('audio-playback-processor', AudioPlaybackProcessor);
133
+ `;class ${config;unityUrl;active=!1;serverConfig=null;ws=null;audioContext=null;mediaStream=null;captureWorkletNode=null;playbackWorkletNode=null;isMuted=!1;outputSampleRate=24e3;inputSampleRate=48e3;isAgentSpeaking=!1;agentAudioDoneReceived=!1;sessionContext={};constructor(e){this.config=e,this.unityUrl=e.unityBaseUrl||"https://api.glydeunity.com",!e.publishableKey&&!e.apiKey&&!e.authToken&&console.warn("[GlydeVoice] No authentication method provided. One of publishableKey, apiKey, or authToken is required.")}getAuthHeaders(){const e={"Content-Type":"application/json"};return this.config.publishableKey&&(e["x-publishable-key"]=this.config.publishableKey),this.config.apiKey&&(e["x-api-key"]=this.config.apiKey),this.config.authToken&&(e.Authorization=`Bearer ${this.config.authToken}`),e}async fetchConfig(){const e=`${this.unityUrl}/api/unity/voice/config/${this.config.contextType}`,r=this.config.contextId?`${e}/${this.config.contextId}`:e,i=await fetch(r,{method:"GET",headers:this.getAuthHeaders()});if(!i.ok){const n=await i.json();throw new Error(n.error?.message||n.message||"Failed to fetch voice config")}const{data:s}=await i.json();return s}async start(){if(!this.active){this.active=!0;try{this.config.systemPrompt||(this.serverConfig=await this.fetchConfig(),console.log("[GlydeVoice] Fetched config:",this.serverConfig));const e={context_id:this.config.contextId,domain:typeof window<"u"?window.location.hostname:"localhost"};this.config.systemPrompt&&(e.system_prompt=this.config.systemPrompt),this.config.deepgramConfig&&(e.deepgram_config=this.config.deepgramConfig);const r=await fetch(`${this.unityUrl}/api/unity/voice/auth`,{method:"POST",headers:this.getAuthHeaders(),body:JSON.stringify(e)});if(!r.ok){const a=await r.json();throw new Error(a.error?.message||a.message||"Failed to authenticate voice session")}const{data:i}=await r.json(),{token:s,agent_config:n,deepgram_config:h}=i;this.setSessionContext({clientUuid:n?.client_uuid,contextId:this.config.contextId,contextType:this.config.contextType,currentJobUuid:n?.job_uuid});const y=this.config.systemPrompt||n.instructions||this.serverConfig?.system_prompt||"You are a helpful AI assistant.";await this.initializeAudio();let f="wss://agent.deepgram.com/v1/agent/converse";const p=this.config.deepgramConfig||h||this.serverConfig?.deepgram_config;if(p?.tags&&p.tags.length>0){const a=new URLSearchParams;p.tags.forEach(g=>a.append("tag",g)),f+=`?${a.toString()}`}this.ws=new WebSocket(f,["bearer",s]),this.ws.onopen=()=>{const a=p||{think:{provider:{type:"open_ai",model:"gpt-4.1-nano"}},speak:{provider:{type:"deepgram",model:"aura-2-thalia-en"}},listen:{provider:{type:"deepgram",version:"v2",model:"flux-general-en"}}},g={type:"Settings",audio:{input:{encoding:"linear16",sample_rate:this.inputSampleRate},output:{encoding:"linear16",sample_rate:this.outputSampleRate,container:"none"}},agent:{language:"en",speak:a.speak||{provider:{type:"deepgram",model:"aura-2-thalia-en"}},listen:a.listen||{provider:{type:"deepgram",version:"v2",model:"flux-general-en"}},think:{provider:a.think?.provider||{type:"open_ai",model:"gpt-4.1-nano"},...a.think?.functions&&{functions:a.think.functions}},greeting:"Hi! I'm excited you chose to speak with me. Are you ready to start?"}};a.tags&&a.tags.length>0&&(g.tags=a.tags),this.ws.send(JSON.stringify(g)),this.emit({type:"open",payload:{config:n,serverConfig:this.serverConfig}})};const b=y;this.ws.onmessage=a=>{if(typeof a.data=="string"){try{if(JSON.parse(a.data).type==="SettingsApplied"){const v={type:"UpdatePrompt",prompt:b};this.ws.send(JSON.stringify(v)),this.startMicrophone()}}catch{}this.handleTextMessage(a.data)}else a.data instanceof Blob?this.handleAudioData(a.data):a.data instanceof ArrayBuffer&&this.handleAudioBuffer(a.data)},this.ws.onerror=a=>{console.error("[GlydeVoice] WebSocket error:",a),this.emit({type:"error",payload:a})},this.ws.onclose=()=>{this.cleanup(),this.emit({type:"close"})},this.renderUI()}catch(e){throw console.error("[GlydeVoice] Error starting session:",e),this.active=!1,this.emit({type:"error",payload:e}),e}}}createWorkletBlobUrl(e){const r=new Blob([e],{type:"application/javascript"});return URL.createObjectURL(r)}async initializeAudio(){this.audioContext=new AudioContext({sampleRate:this.inputSampleRate});const e=this.createWorkletBlobUrl(oe),r=this.createWorkletBlobUrl(ie);try{await Promise.all([this.audioContext.audioWorklet.addModule(e),this.audioContext.audioWorklet.addModule(r)])}finally{URL.revokeObjectURL(e),URL.revokeObjectURL(r)}this.playbackWorkletNode=new AudioWorkletNode(this.audioContext,"audio-playback-processor"),this.playbackWorkletNode.connect(this.audioContext.destination),this.playbackWorkletNode.port.onmessage=i=>{const{type:s}=i.data;(s==="cleared"||s==="bufferEmpty")&&(this.isAgentSpeaking=!1,this.agentAudioDoneReceived=!1,this.emit({type:"agent_speaking",payload:!1}))}}handleTextMessage(e){try{const r=JSON.parse(e);switch(r.type){case"Welcome":this.emit({type:"ready"});break;case"SettingsApplied":break;case"UserStartedSpeaking":this.emit({type:"user_speaking",payload:!0}),this.clearPlaybackBuffer(),this.isAgentSpeaking=!1,this.agentAudioDoneReceived=!1;break;case"UserStoppedSpeaking":this.emit({type:"user_speaking",payload:!1});break;case"ConversationText":if(r.content&&r.content.trim()){const i=r.role==="assistant"?"agent":"user";this.config.onTranscript&&this.config.onTranscript(r.content,i),this.emit({type:"transcript",payload:{text:r.content,role:i}}),this.saveTranscript(r.content,r.role)}break;case"AgentStartedSpeaking":this.isAgentSpeaking=!0,this.agentAudioDoneReceived=!1,this.emit({type:"agent_speaking",payload:!0});break;case"AgentAudioDone":this.agentAudioDoneReceived=!0;break;case"Error":console.error("[GlydeVoice] Agent error:",r),this.emit({type:"error",payload:r});break;case"FunctionCallRequest":this.handleFunctionCallRequest(r);break}}catch(r){console.error("[GlydeVoice] Failed to parse message:",r)}}async handleAudioData(e){const r=await e.arrayBuffer();this.handleAudioBuffer(r)}handleAudioBuffer(e){if(!this.playbackWorkletNode||!this.audioContext)return;this.audioContext.state==="suspended"&&this.audioContext.resume();const r=e.byteLength;if(r===0)return;const i=r-r%2;if(i===0)return;const s=i===r?e:e.slice(0,i),n=new Int16Array(s),h=new Float32Array(n.length);for(let p=0;p<n.length;p++)h[p]=n[p]/32768;const y=this.resample24kTo48k(h);!this.isAgentSpeaking&&!this.agentAudioDoneReceived&&(this.isAgentSpeaking=!0,this.emit({type:"agent_speaking",payload:!0}));const f=new Float32Array(y);this.playbackWorkletNode.port.postMessage({type:"audio",data:f},[f.buffer])}resample24kTo48k(e){const r=e.length*2,i=new Float32Array(r);for(let n=0;n<e.length-1;n++){const h=e[n],y=e[n+1];i[n*2]=h,i[n*2+1]=(h+y)/2}const s=e.length-1;return i[s*2]=e[s],i[s*2+1]=e[s],i}clearPlaybackBuffer(){this.playbackWorkletNode&&this.playbackWorkletNode.port.postMessage({type:"clear"})}async startMicrophone(){if(!this.audioContext)throw new Error("Audio context not initialized");try{this.mediaStream=await navigator.mediaDevices.getUserMedia({audio:{channelCount:1,sampleRate:this.inputSampleRate,echoCancellation:!0,noiseSuppression:!0}});const e=this.audioContext.createMediaStreamSource(this.mediaStream);this.captureWorkletNode=new AudioWorkletNode(this.audioContext,"audio-capture-processor"),this.captureWorkletNode.port.onmessage=r=>{!this.active||!this.ws||this.ws.readyState!==WebSocket.OPEN||this.isMuted||this.ws.send(r.data)},e.connect(this.captureWorkletNode),this.emit({type:"microphone_ready"})}catch(e){throw console.error("[GlydeVoice] Microphone error:",e),e}}async saveTranscript(e,r){if(!(!this.config.contextId||!e))try{await fetch(`${this.unityUrl}/api/unity/voice/transcript`,{method:"POST",headers:this.getAuthHeaders(),body:JSON.stringify({context_id:this.config.contextId,content:e,role:r==="assistant"?"assistant":"user"})})}catch{}}setMuted(e){this.isMuted=e}getMuted(){return this.isMuted}isActive(){return this.active}getServerConfig(){return this.serverConfig}stop(){this.active=!1,this.cleanup()}cleanup(){this.captureWorkletNode&&(this.captureWorkletNode.disconnect(),this.captureWorkletNode.port.close(),this.captureWorkletNode=null),this.playbackWorkletNode&&(this.playbackWorkletNode.disconnect(),this.playbackWorkletNode.port.close(),this.playbackWorkletNode=null),this.mediaStream&&(this.mediaStream.getTracks().forEach(e=>e.stop()),this.mediaStream=null),this.audioContext&&(this.audioContext.close(),this.audioContext=null),this.ws&&(this.ws.readyState===WebSocket.OPEN&&this.ws.close(),this.ws=null)}emit(e){this.config.onEvent&&this.config.onEvent(e)}renderUI(){if(!this.config.container)return;const e=typeof this.config.container=="string"?document.querySelector(this.config.container):this.config.container;e&&(e.innerHTML=`
134
+ <div style="padding: 20px; border: 1px solid #ccc; border-radius: 8px; background: #fff;">
135
+ <h3>Glyde Voice Agent</h3>
136
+ <p>Status: Active</p>
137
+ <p>Context: ${this.config.contextType}</p>
138
+ <button onclick="this.closest('div').remove()">Close</button>
139
+ </div>
140
+ `)}async handleFunctionCallRequest(e){for(const r of e.functions){console.log("[GlydeVoice] Function call request:",r.name,r.arguments);let i={};try{i=r.arguments?JSON.parse(r.arguments):{}}catch(h){console.warn("[GlydeVoice] Failed to parse function arguments:",h)}let s;try{r.name==="end_conversation"?s=await this.handleEndConversation(i):s=await this.executeVoiceFunction(r.name,r.id,i)}catch(h){console.error("[GlydeVoice] Function call error:",h),s=JSON.stringify({error:"Function execution failed",details:h instanceof Error?h.message:String(h)})}const n={type:"FunctionCallResponse",id:r.id,name:r.name,content:s};this.ws&&this.ws.readyState===WebSocket.OPEN?(this.ws.send(JSON.stringify(n)),console.log("[GlydeVoice] Function response sent:",r.name)):console.error("[GlydeVoice] Cannot send function response - WebSocket not open")}}async executeVoiceFunction(e,r,i){console.log("[GlydeVoice] Executing voice function via Unity API:",e);try{const s=await fetch(`${this.unityUrl}/api/unity/voice/function`,{method:"POST",headers:this.getAuthHeaders(),body:JSON.stringify({function_name:e,function_call_id:r,input:i,context:{context_id:this.sessionContext.contextId,context_type:this.sessionContext.contextType,current_job_uuid:this.sessionContext.currentJobUuid}})});if(!s.ok){const h=await s.json().catch(()=>({}));throw new Error(h.error?.message||`Function call failed: ${s.status}`)}const n=await s.json();if(n.success&&n.data?.output)return typeof n.data.output=="string"?n.data.output:JSON.stringify(n.data.output);throw new Error("Invalid response from voice function endpoint")}catch(s){return console.error("[GlydeVoice] Voice function error:",s),JSON.stringify({success:!1,error:s instanceof Error?s.message:"Function execution failed",fallback_message:"I apologize, but I'm having trouble with that request right now. Is there something else I can help you with?"})}}async handleEndConversation(e){const r=e.item||"user request";return console.log(`[GlydeVoice] End conversation triggered by: ${r}`),setTimeout(()=>{this.stop()},2e3),JSON.stringify({success:!0,message:"Conversation ending. Say goodbye to the user.",trigger_phrase:r})}setSessionContext(e){this.sessionContext={...this.sessionContext,...e},console.log("[GlydeVoice] Session context updated:",{hasContextId:!!e.contextId,contextType:e.contextType,hasJobUuid:!!e.currentJobUuid})}}class F{config;unityUrl;history=[];isTyping=!1;initialized=!1;constructor(e){this.config=e,this.unityUrl=e.unityBaseUrl||"https://api.glydeunity.com",!e.publishableKey&&!e.apiKey&&!e.authToken&&console.warn("[GlydeText] No authentication method provided. One of publishableKey, apiKey, or authToken is required.")}getAuthHeaders(){const e={"Content-Type":"application/json"};return this.config.publishableKey&&(e["x-publishable-key"]=this.config.publishableKey),this.config.apiKey&&(e["x-api-key"]=this.config.apiKey),this.config.authToken&&(e.Authorization=`Bearer ${this.config.authToken}`),e}emit(e){this.config.onEvent&&this.config.onEvent(e)}setTyping(e){this.isTyping=e,this.config.onTyping&&this.config.onTyping(e)}async initialize(){if(!this.config.contextId)throw new Error("contextId is required for text chat initialization");this.setTyping(!0);try{const e=await fetch(`${this.unityUrl}/api/unity/screening/start`,{method:"POST",headers:this.getAuthHeaders(),body:JSON.stringify({application_uuid:this.config.contextId})});if(!e.ok){const i=await e.json().catch(()=>({}));throw new Error(i.error?.message||i.message||"Failed to initialize chat")}const r=await e.json();return r.messages&&(this.history=r.messages),this.initialized=!0,this.emit({type:"ready"}),this.emit({type:"history_loaded",payload:this.history}),this.history}catch(e){throw console.error("[GlydeText] Initialization error:",e),this.emit({type:"error",payload:e}),e}finally{this.setTyping(!1)}}async sendMessage(e){if(!this.config.contextId)throw new Error("contextId is required for sending messages");if(!e.trim())throw new Error("Message cannot be empty");this.initialized||await this.initialize();const r={role:"user",content:e.trim(),created:new Date().toISOString()};this.history.push(r),this.config.onMessage&&this.config.onMessage(r),this.emit({type:"message",payload:r}),this.setTyping(!0);try{const i=await fetch(`${this.unityUrl}/api/unity/screening/chat`,{method:"POST",headers:this.getAuthHeaders(),body:JSON.stringify({application_uuid:this.config.contextId,message:e.trim()})});if(!i.ok){const y=await i.json().catch(()=>({}));throw new Error(y.error?.message||y.message||"Failed to send message")}const s=await i.json();s.history?.messages&&(this.history=s.history.messages);const n=[...this.history].reverse().find(y=>y.role==="assistant");return n?(this.config.onMessage&&this.config.onMessage(n),this.emit({type:"message",payload:n}),n):{role:"assistant",content:s.response||"I received your message.",created:new Date().toISOString()}}catch(i){throw console.error("[GlydeText] Send message error:",i),this.emit({type:"error",payload:i}),i}finally{this.setTyping(!1)}}getHistory(){return[...this.history]}clearHistory(){this.history=[],this.initialized=!1}getIsTyping(){return this.isTyping}getIsInitialized(){return this.initialized}}function G(o){const[e,r]=l.useState("idle"),[i,s]=l.useState([]),[n,h]=l.useState(!1),[y,f]=l.useState(!1),[p,b]=l.useState(!1),[a,g]=l.useState(null),v=l.useRef(null),k=l.useCallback(d=>{switch(d.type){case"ready":r("active");break;case"close":r("idle"),h(!1),f(!1);break;case"error":r("error"),g(typeof d.payload=="object"&&d.payload!==null&&"message"in d.payload?String(d.payload.message):"Connection error");break;case"user_speaking":h(!!d.payload);break;case"agent_speaking":f(!!d.payload);break}},[]),m=l.useCallback((d,M)=>{s(E=>[...E,{role:M,content:d,timestamp:new Date}])},[]),u=l.useCallback(async()=>{r("connecting"),g(null);try{const d=new $({...o,onEvent:k,onTranscript:m});v.current=d,await d.start()}catch(d){console.error("[useVoiceAgent] Failed to start:",d),r("error"),g(d instanceof Error?d.message:"Failed to connect")}},[o,k,m]),w=l.useCallback(()=>{v.current?.stop(),v.current=null,r("idle"),h(!1),f(!1)},[]),C=l.useCallback(()=>{const d=!p;b(d),v.current?.setMuted(d)},[p]),I=l.useCallback(d=>{b(d),v.current?.setMuted(d)},[]),T=l.useCallback(()=>{s([])},[]);return l.useEffect(()=>()=>{v.current?.stop()},[]),l.useEffect(()=>{o.autoStart&&e==="idle"&&u()},[o.autoStart,e,u]),{status:e,transcripts:i,isUserSpeaking:n,isAgentSpeaking:y,isMuted:p,errorMessage:a,start:u,stop:w,toggleMute:C,setMuted:I,clearTranscripts:T,voiceAgent:v.current}}function H(o){const[e,r]=l.useState("idle"),[i,s]=l.useState([]),[n,h]=l.useState(!1),[y,f]=l.useState(null),p=l.useRef(null),b=l.useRef(!1),a=l.useCallback(()=>(p.current||(p.current=new F({...o,onTyping:h})),p.current),[o]),g=l.useCallback(async()=>{if(!b.current){r("loading"),f(null);try{const u=await a().initialize();s(u),r("ready"),b.current=!0}catch(m){console.error("[useTextChat] Initialization error:",m),r("error"),f(m instanceof Error?m.message:"Failed to initialize chat")}}},[a]),v=l.useCallback(async m=>{if(m.trim()){f(null);try{const u=a(),w={role:"user",content:m.trim(),created:new Date().toISOString()};s(I=>[...I,w]),await u.sendMessage(m);const C=u.getHistory();s(C),e!=="ready"&&(r("ready"),b.current=!0)}catch(u){console.error("[useTextChat] Send message error:",u),f(u instanceof Error?u.message:"Failed to send message")}}},[a,e]),k=l.useCallback(()=>{p.current?.clearHistory(),s([]),b.current=!1,r("idle")},[]);return l.useEffect(()=>{o.autoInit&&!b.current&&o.contextId&&g()},[o.autoInit,o.contextId,g]),l.useEffect(()=>()=>{p.current=null},[]),{status:e,messages:i,isLoading:n,errorMessage:y,initialize:g,sendMessage:v,clearHistory:k,textChat:p.current}}const L=({size:o=24,color:e="currentColor",className:r})=>t.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",width:o,height:o,viewBox:"0 0 24 24",fill:"none",stroke:e,strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:r,children:[t.jsx("path",{d:"M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z"}),t.jsx("path",{d:"M19 10v2a7 7 0 0 1-14 0v-2"}),t.jsx("line",{x1:"12",x2:"12",y1:"19",y2:"22"})]}),se=({size:o=24,color:e="currentColor",className:r})=>t.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",width:o,height:o,viewBox:"0 0 24 24",fill:"none",stroke:e,strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:r,children:[t.jsx("line",{x1:"2",x2:"22",y1:"2",y2:"22"}),t.jsx("path",{d:"M18.89 13.23A7.12 7.12 0 0 0 19 12v-2"}),t.jsx("path",{d:"M5 10v2a7 7 0 0 0 12 5"}),t.jsx("path",{d:"M15 9.34V5a3 3 0 0 0-5.68-1.33"}),t.jsx("path",{d:"M9 9v3a3 3 0 0 0 5.12 2.12"}),t.jsx("line",{x1:"12",x2:"12",y1:"19",y2:"22"})]}),ne=({size:o=24,color:e="currentColor",className:r})=>t.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",width:o,height:o,viewBox:"0 0 24 24",fill:"none",stroke:e,strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:r,children:t.jsx("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"})}),K=({size:o=24,color:e="currentColor",className:r})=>t.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",width:o,height:o,viewBox:"0 0 24 24",fill:"none",stroke:e,strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:r,children:[t.jsx("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"}),t.jsx("line",{x1:"22",x2:"2",y1:"2",y2:"22"})]}),U=({size:o=24,color:e="currentColor",className:r})=>t.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",width:o,height:o,viewBox:"0 0 24 24",fill:"none",stroke:e,strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:r,children:t.jsx("path",{d:"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"})}),J=({size:o=24,color:e="currentColor",className:r})=>t.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",width:o,height:o,viewBox:"0 0 24 24",fill:"none",stroke:e,strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:r,children:[t.jsx("line",{x1:"22",x2:"11",y1:"2",y2:"13"}),t.jsx("polygon",{points:"22 2 15 22 11 13 2 9 22 2"})]}),q=({size:o=24,color:e="currentColor",className:r})=>t.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",width:o,height:o,viewBox:"0 0 24 24",fill:"none",stroke:e,strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:r,children:[t.jsx("path",{d:"M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"}),t.jsx("circle",{cx:"12",cy:"7",r:"4"})]}),Y=({size:o=24,color:e="currentColor",className:r})=>t.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",width:o,height:o,viewBox:"0 0 24 24",fill:"none",stroke:e,strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:r,children:[t.jsx("path",{d:"M12 8V4H8"}),t.jsx("rect",{width:"16",height:"12",x:"4",y:"8",rx:"2"}),t.jsx("path",{d:"M2 14h2"}),t.jsx("path",{d:"M20 14h2"}),t.jsx("path",{d:"M15 13v2"}),t.jsx("path",{d:"M9 13v2"})]}),X=({size:o=24,color:e="currentColor",className:r})=>t.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",width:o,height:o,viewBox:"0 0 24 24",fill:"none",stroke:e,strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:r,children:t.jsx("polyline",{points:"22 12 18 12 15 21 9 3 6 12 2 12"})}),Z=({size:o=24,color:e="currentColor",className:r})=>t.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",width:o,height:o,viewBox:"0 0 24 24",fill:"none",stroke:e,strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:r,children:[t.jsx("polygon",{points:"11 5 6 9 2 9 2 15 6 15 11 19 11 5"}),t.jsx("line",{x1:"22",x2:"16",y1:"9",y2:"15"}),t.jsx("line",{x1:"16",x2:"22",y1:"9",y2:"15"})]}),Q=({size:o=24,color:e="currentColor",className:r})=>t.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",width:o,height:o,viewBox:"0 0 24 24",fill:"none",stroke:e,strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:r,children:[t.jsx("line",{x1:"18",x2:"6",y1:"6",y2:"18"}),t.jsx("line",{x1:"6",x2:"18",y1:"6",y2:"18"})]}),R=({size:o=24,color:e="currentColor",className:r})=>t.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",width:o,height:o,viewBox:"0 0 24 24",fill:"none",stroke:e,strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:r,children:[t.jsx("path",{d:"M8 3v3a2 2 0 0 1-2 2H3"}),t.jsx("path",{d:"M21 8h-3a2 2 0 0 1-2-2V3"}),t.jsx("path",{d:"M3 16h3a2 2 0 0 1 2 2v3"}),t.jsx("path",{d:"M16 21v-3a2 2 0 0 1 2-2h3"})]}),ae=({size:o=24,color:e="currentColor",className:r})=>t.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",width:o,height:o,viewBox:"0 0 24 24",fill:"none",stroke:e,strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:r,style:{animation:"spin 1s linear infinite"},children:t.jsx("path",{d:"M21 12a9 9 0 1 1-6.219-8.56"})}),ee={light:{primary:"#c026d3",primaryHover:"#a21caf",primaryLight:"#fdf4ff",primaryText:"#ffffff",secondary:"#0284c7",secondaryHover:"#0369a1",secondaryLight:"#f0f9ff",secondaryText:"#ffffff",success:"#059669",successLight:"#dcfce7",successText:"#166534",error:"#ef4444",errorHover:"#dc2626",errorLight:"#fef2f2",errorText:"#b91c1c",background:"#ffffff",surface:"#f9fafb",border:"#e5e7eb",borderLight:"#f3f4f6",text:"#1f2937",textSecondary:"#6b7280",textMuted:"#9ca3af"},dark:{primary:"#d946ef",primaryHover:"#c026d3",primaryLight:"#3b0764",primaryText:"#ffffff",secondary:"#38bdf8",secondaryHover:"#0ea5e9",secondaryLight:"#0c4a6e",secondaryText:"#ffffff",success:"#34d399",successLight:"#064e3b",successText:"#a7f3d0",error:"#f87171",errorHover:"#ef4444",errorLight:"#450a0a",errorText:"#fecaca",background:"#111827",surface:"#1f2937",border:"#374151",borderLight:"#4b5563",text:"#f9fafb",textSecondary:"#d1d5db",textMuted:"#9ca3af"}};function P(o){const e=ee[o];return`
141
+ --glyde-primary: ${e.primary};
142
+ --glyde-primary-hover: ${e.primaryHover};
143
+ --glyde-primary-light: ${e.primaryLight};
144
+ --glyde-primary-text: ${e.primaryText};
145
+ --glyde-secondary: ${e.secondary};
146
+ --glyde-secondary-hover: ${e.secondaryHover};
147
+ --glyde-secondary-light: ${e.secondaryLight};
148
+ --glyde-secondary-text: ${e.secondaryText};
149
+ --glyde-success: ${e.success};
150
+ --glyde-success-light: ${e.successLight};
151
+ --glyde-success-text: ${e.successText};
152
+ --glyde-error: ${e.error};
153
+ --glyde-error-hover: ${e.errorHover};
154
+ --glyde-error-light: ${e.errorLight};
155
+ --glyde-error-text: ${e.errorText};
156
+ --glyde-background: ${e.background};
157
+ --glyde-surface: ${e.surface};
158
+ --glyde-border: ${e.border};
159
+ --glyde-border-light: ${e.borderLight};
160
+ --glyde-text: ${e.text};
161
+ --glyde-text-secondary: ${e.textSecondary};
162
+ --glyde-text-muted: ${e.textMuted};
163
+ `}const N=`
164
+ @keyframes glyde-pulse {
165
+ 0%, 100% { opacity: 1; transform: scale(1); }
166
+ 50% { opacity: 0.5; transform: scale(1.2); }
167
+ }
168
+
169
+ @keyframes glyde-spin {
170
+ to { transform: rotate(360deg); }
171
+ }
172
+
173
+ @keyframes glyde-fade-in {
174
+ from { opacity: 0; transform: translateY(10px); }
175
+ to { opacity: 1; transform: translateY(0); }
176
+ }
177
+
178
+ @keyframes glyde-slide-up {
179
+ from { opacity: 0; transform: translateY(20px); }
180
+ to { opacity: 1; transform: translateY(0); }
181
+ }
182
+
183
+ @keyframes glyde-bounce {
184
+ 0%, 100% { transform: translateY(0); }
185
+ 50% { transform: translateY(-5px); }
186
+ }
187
+
188
+ .glyde-widget-root {
189
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
190
+ font-size: 14px;
191
+ line-height: 1.5;
192
+ color: var(--glyde-text);
193
+ box-sizing: border-box;
194
+ }
195
+
196
+ .glyde-widget-root *, .glyde-widget-root *::before, .glyde-widget-root *::after {
197
+ box-sizing: border-box;
198
+ }
199
+
200
+ .glyde-spinner {
201
+ width: 32px;
202
+ height: 32px;
203
+ border: 3px solid var(--glyde-border);
204
+ border-top-color: var(--glyde-primary);
205
+ border-radius: 50%;
206
+ animation: glyde-spin 1s linear infinite;
207
+ }
208
+
209
+ .glyde-pulse-dot {
210
+ animation: glyde-pulse 1.5s infinite;
211
+ }
212
+
213
+ .glyde-fade-in {
214
+ animation: glyde-fade-in 0.3s ease-out;
215
+ }
216
+
217
+ .glyde-slide-up {
218
+ animation: glyde-slide-up 0.3s ease-out;
219
+ }
220
+ `,x={floatingButton:{position:"fixed",width:"60px",height:"60px",borderRadius:"50%",border:"none",cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",boxShadow:"0 4px 12px rgba(0, 0, 0, 0.15)",transition:"transform 0.2s, box-shadow 0.2s",zIndex:9999},widgetPanel:{position:"fixed",width:"380px",height:"600px",borderRadius:"16px",boxShadow:"0 10px 40px rgba(0, 0, 0, 0.2)",display:"flex",flexDirection:"column",overflow:"hidden",zIndex:9998},card:{background:"var(--glyde-background)",borderRadius:"12px",boxShadow:"0 4px 6px rgba(0, 0, 0, 0.1)",overflow:"hidden"},header:{padding:"16px 20px",borderBottom:"1px solid var(--glyde-border)",display:"flex",justifyContent:"space-between",alignItems:"center"},modeSelector:{display:"flex",gap:"8px",padding:"4px",background:"var(--glyde-surface)",borderRadius:"8px"},modeSelectorButton:{padding:"8px 16px",border:"none",borderRadius:"6px",cursor:"pointer",display:"flex",alignItems:"center",gap:"6px",fontSize:"14px",fontWeight:500,transition:"all 0.2s"},transcriptArea:{flex:1,overflowY:"auto",padding:"16px",background:"var(--glyde-surface)"},messageBubble:{maxWidth:"80%",padding:"10px 14px",borderRadius:"12px",boxShadow:"0 1px 3px rgba(0, 0, 0, 0.1)"},messageBubbleUser:{background:"var(--glyde-primary)",color:"var(--glyde-primary-text)",borderTopRightRadius:"4px"},messageBubbleAgent:{background:"var(--glyde-background)",color:"var(--glyde-text)",borderTopLeftRadius:"4px"},controlsArea:{padding:"16px",borderTop:"1px solid var(--glyde-border)",background:"var(--glyde-background)"},speakingIndicator:{display:"flex",alignItems:"center",gap:"6px",fontSize:"13px"},speakingDot:{width:"8px",height:"8px",borderRadius:"50%",transition:"background-color 0.2s"},primaryButton:{padding:"12px 24px",background:"var(--glyde-primary)",color:"var(--glyde-primary-text)",border:"none",borderRadius:"8px",fontSize:"15px",fontWeight:600,cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",gap:"8px",transition:"background-color 0.2s, transform 0.1s"},secondaryButton:{padding:"10px 20px",background:"var(--glyde-surface)",color:"var(--glyde-text)",border:"1px solid var(--glyde-border)",borderRadius:"8px",fontSize:"14px",fontWeight:500,cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",gap:"6px",transition:"background-color 0.2s"},dangerButton:{padding:"12px 24px",background:"var(--glyde-error)",color:"white",border:"none",borderRadius:"24px",fontSize:"15px",fontWeight:600,cursor:"pointer",display:"flex",alignItems:"center",gap:"8px",transition:"background-color 0.2s"},iconButton:{width:"44px",height:"44px",padding:"0",border:"none",borderRadius:"50%",cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",transition:"background-color 0.2s"},inputField:{flex:1,padding:"12px 16px",borderRadius:"8px",border:"1px solid var(--glyde-border)",background:"var(--glyde-background)",color:"var(--glyde-text)",fontSize:"14px",outline:"none",transition:"border-color 0.2s"},statusBadge:{padding:"4px 10px",borderRadius:"20px",fontSize:"12px",fontWeight:500,display:"flex",alignItems:"center",gap:"4px"},statusBadgeLive:{background:"var(--glyde-success-light)",color:"var(--glyde-success-text)"},statusBadgeConnecting:{background:"var(--glyde-primary-light)",color:"var(--glyde-primary)"}};function te(o,e=20){return{"bottom-right":{button:{bottom:e,right:e},panel:{bottom:e+70,right:e}},"bottom-left":{button:{bottom:e,left:e},panel:{bottom:e+70,left:e}},"top-right":{button:{top:e,right:e},panel:{top:e+70,right:e}},"top-left":{button:{top:e,left:e},panel:{top:e+70,left:e}}}[o]}function W(o="light"){const e="glyde-widget-styles";if(document.getElementById(e))return;const r=document.createElement("style");r.id=e,r.textContent=`
221
+ :root {
222
+ ${P(o)}
223
+ }
224
+
225
+ ${N}
226
+ `,document.head.appendChild(r)}function le(o){const r=document.getElementById("glyde-widget-styles");r?r.textContent=`
227
+ :root {
228
+ ${P(o)}
229
+ }
230
+
231
+ ${N}
232
+ `:W(o)}const O=({contextId:o,publishableKey:e,apiKey:r,authToken:i,unityApiUrl:s="https://api.glydeunity.com",contextType:n="screening",height:h="600px",onTranscript:y,onCallEnd:f,onError:p})=>{const b=l.useRef(null),{status:a,transcripts:g,isUserSpeaking:v,isAgentSpeaking:k,isMuted:m,errorMessage:u,start:w,stop:C,toggleMute:I,clearTranscripts:T}=G({publishableKey:e,apiKey:r,authToken:i,contextType:n,contextId:o,unityBaseUrl:s});l.useEffect(()=>{b.current?.scrollIntoView({behavior:"smooth"})},[g]),l.useEffect(()=>{if(y&&g.length>0){const S=g[g.length-1];y(S.content,S.role)}},[g,y]),l.useEffect(()=>{a==="error"&&u&&p&&p(new Error(u))},[a,u,p]);const d=()=>{switch(n){case"screening":return"Screening Interview";case"recruiter":return"Recruiter Copilot";case"custom":return"Custom Agent";case"phone":return"Phone Agent";default:return"Voice Interview"}},M=async()=>{T(),await w()},E=()=>{C(),f?.()};return t.jsxs("div",{style:{background:"var(--glyde-background, white)",borderRadius:"12px",boxShadow:"0 4px 6px rgba(0,0,0,0.1)",height:typeof h=="number"?`${h}px`:h,display:"flex",flexDirection:"column",overflow:"hidden"},children:[t.jsxs("div",{style:{padding:"16px 20px",borderBottom:"1px solid var(--glyde-border, #e5e7eb)",display:"flex",justifyContent:"space-between",alignItems:"center"},children:[t.jsxs("div",{children:[t.jsx("h2",{style:{margin:0,fontSize:"1.1rem",fontWeight:600,color:"var(--glyde-text, #1f2937)"},children:d()}),t.jsx("small",{style:{color:"var(--glyde-text-secondary, #6b7280)",fontSize:"0.8rem"},children:i?"JWT Auth":e?"Publishable Key":"API Key"})]}),a==="active"&&t.jsxs("div",{style:{...x.statusBadge,...x.statusBadgeLive},children:[t.jsx(X,{size:14})," Live"]})]}),t.jsx("div",{style:{flex:1,display:"flex",flexDirection:"column",overflow:"hidden"},children:a==="idle"||a==="error"?t.jsxs("div",{style:{flex:1,display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",padding:"40px"},children:[t.jsx("div",{style:{width:"100px",height:"100px",borderRadius:"50%",background:"var(--glyde-primary-light, #fdf4ff)",display:"flex",alignItems:"center",justifyContent:"center",marginBottom:"24px"},children:t.jsx(L,{size:48,color:"var(--glyde-primary, #c026d3)"})}),t.jsxs("h3",{style:{marginBottom:"8px",color:"var(--glyde-text, #1f2937)"},children:["Ready for ",d(),"?"]}),t.jsx("p",{style:{color:"var(--glyde-text-secondary, #666)",marginBottom:"24px",textAlign:"center",maxWidth:"280px"},children:n==="screening"?"The AI recruiter will speak with you. Make sure your microphone is ready.":n==="recruiter"?"The AI copilot will assist you with recruiting tasks.":"The AI agent will speak with you. Make sure your microphone is ready."}),t.jsxs("button",{onClick:M,style:{...x.primaryButton,padding:"14px 36px",borderRadius:"30px",boxShadow:"0 4px 12px rgba(192, 38, 211, 0.3)"},children:["Start ",n==="screening"?"Interview":"Call"]}),u&&t.jsx("p",{style:{color:"var(--glyde-error, #ef4444)",marginTop:"16px",fontSize:"0.9rem"},children:u})]}):t.jsxs(t.Fragment,{children:[t.jsxs("div",{style:{flex:1,overflowY:"auto",padding:"16px",background:"var(--glyde-surface, #f9fafb)"},children:[a==="connecting"&&t.jsxs("div",{style:{textAlign:"center",color:"var(--glyde-text-secondary, #6b7280)",padding:"40px"},children:[t.jsx("div",{className:"glyde-spinner",style:{margin:"0 auto 12px"}}),"Connecting to AI Agent..."]}),g.length===0&&a==="active"&&t.jsxs("div",{style:{textAlign:"center",color:"var(--glyde-text-muted, #9ca3af)",padding:"40px"},children:[t.jsx(U,{size:32,color:"var(--glyde-text-muted, #9ca3af)"}),t.jsx("p",{style:{marginTop:"8px"},children:"Start speaking - the AI will respond"})]}),g.map((S,D)=>t.jsx(de,{transcript:S,contextType:n},D)),t.jsx("div",{ref:b})]}),t.jsxs("div",{style:{padding:"16px",borderTop:"1px solid var(--glyde-border, #e5e7eb)",background:"var(--glyde-background, white)"},children:[t.jsx(ce,{isUserSpeaking:v,isAgentSpeaking:k}),t.jsxs("div",{style:{display:"flex",justifyContent:"center",gap:"12px",marginTop:"16px"},children:[t.jsx("button",{onClick:I,style:{...x.iconButton,background:m?"var(--glyde-error-light, #fecaca)":"var(--glyde-secondary-light, #e0f2fe)"},title:m?"Unmute":"Mute",children:m?t.jsx(Z,{size:20,color:"var(--glyde-error, #dc2626)"}):t.jsx(L,{size:20,color:"var(--glyde-secondary, #0ea5e9)"})}),t.jsxs("button",{onClick:E,style:x.dangerButton,children:[t.jsx(K,{size:18,color:"white"})," End Call"]})]})]})]})}),t.jsx("style",{children:`
233
+ @keyframes glyde-pulse {
234
+ 0%, 100% { opacity: 1; transform: scale(1); }
235
+ 50% { opacity: 0.5; transform: scale(1.2); }
236
+ }
237
+ .glyde-spinner {
238
+ width: 32px;
239
+ height: 32px;
240
+ border: 3px solid var(--glyde-border, #e5e7eb);
241
+ border-top-color: var(--glyde-primary, #c026d3);
242
+ border-radius: 50%;
243
+ animation: spin 1s linear infinite;
244
+ }
245
+ @keyframes spin {
246
+ to { transform: rotate(360deg); }
247
+ }
248
+ `})]})},de=({transcript:o,contextType:e})=>{const r=o.role==="user";return t.jsx("div",{style:{marginBottom:"12px",display:"flex",justifyContent:r?"flex-end":"flex-start"},children:t.jsxs("div",{style:{...x.messageBubble,...r?x.messageBubbleUser:x.messageBubbleAgent},children:[t.jsx("div",{style:{fontSize:"0.75rem",opacity:.7,marginBottom:"4px"},children:r?"You":e==="recruiter"?"AI Copilot":"AI Recruiter"}),o.content]})})},ce=({isUserSpeaking:o,isAgentSpeaking:e})=>t.jsxs("div",{style:{display:"flex",justifyContent:"center",gap:"20px"},children:[t.jsxs("div",{style:{...x.speakingIndicator,color:o?"var(--glyde-primary, #c026d3)":"var(--glyde-text-muted, #9ca3af)"},children:[t.jsx("div",{style:{...x.speakingDot,background:o?"var(--glyde-primary, #c026d3)":"var(--glyde-border, #d1d5db)",animation:o?"glyde-pulse 1s infinite":"none"}}),"You"]}),t.jsxs("div",{style:{...x.speakingIndicator,color:e?"var(--glyde-success, #059669)":"var(--glyde-text-muted, #9ca3af)"},children:[t.jsx("div",{style:{...x.speakingDot,background:e?"var(--glyde-success, #059669)":"var(--glyde-border, #d1d5db)",animation:e?"glyde-pulse 1s infinite":"none"}}),"AI Agent"]})]}),_=({contextId:o,publishableKey:e,apiKey:r,authToken:i,unityApiUrl:s="https://api.glydeunity.com",height:n="600px",title:h="AI Chat",placeholder:y="Type your message...",autoInit:f=!0,onMessage:p,onError:b})=>{const[a,g]=l.useState(""),v=l.useRef(null),{status:k,messages:m,isLoading:u,errorMessage:w,sendMessage:C}=H({publishableKey:e,apiKey:r,authToken:i,contextId:o,unityBaseUrl:s,autoInit:f});l.useEffect(()=>{v.current?.scrollIntoView({behavior:"smooth"})},[m]),l.useEffect(()=>{k==="error"&&w&&b&&b(new Error(w))},[k,w,b]);const I=async()=>{if(!a.trim()||u)return;const d=a.trim();g(""),await C(d),p&&p({role:"user",content:d})},T=d=>{d.key==="Enter"&&!d.shiftKey&&(d.preventDefault(),I())};return t.jsxs("div",{style:{background:"var(--glyde-background, white)",borderRadius:"12px",boxShadow:"0 4px 6px rgba(0,0,0,0.1)",height:typeof n=="number"?`${n}px`:n,display:"flex",flexDirection:"column",overflow:"hidden"},children:[t.jsx("div",{style:{padding:"16px 20px",borderBottom:"1px solid var(--glyde-border, #eee)",background:"var(--glyde-secondary, #0284c7)",color:"white",borderTopLeftRadius:"12px",borderTopRightRadius:"12px"},children:t.jsx("h2",{style:{margin:0,fontSize:"1.1rem",fontWeight:600},children:h})}),t.jsxs("div",{style:{flex:1,overflowY:"auto",padding:"20px",display:"flex",flexDirection:"column",gap:"15px",background:"var(--glyde-background, white)"},children:[k==="loading"&&m.length===0&&t.jsxs("div",{style:{textAlign:"center",color:"var(--glyde-text-muted, #94a3b8)",padding:"20px"},children:[t.jsx("div",{className:"glyde-spinner",style:{margin:"0 auto 12px"}}),"Loading conversation..."]}),m.map((d,M)=>t.jsx(he,{message:d},M)),u&&t.jsx("div",{style:{color:"var(--glyde-text-muted, #94a3b8)",fontSize:"0.9rem",marginLeft:"42px"},children:t.jsx(pe,{})}),t.jsx("div",{ref:v})]}),t.jsxs("div",{style:{padding:"16px 20px",borderTop:"1px solid var(--glyde-border, #eee)"},children:[w&&t.jsx("p",{style:{color:"var(--glyde-error, #ef4444)",fontSize:"0.85rem",marginBottom:"10px"},children:w}),t.jsxs("div",{style:{display:"flex",gap:"10px"},children:[t.jsx("input",{type:"text",value:a,onChange:d=>g(d.target.value),onKeyDown:T,placeholder:y,style:{...x.inputField,flex:1},disabled:u}),t.jsx("button",{onClick:I,disabled:u||!a.trim(),style:{...x.iconButton,background:"var(--glyde-secondary, #0284c7)",width:"48px",height:"48px",opacity:u||!a.trim()?.5:1,cursor:u||!a.trim()?"not-allowed":"pointer"},children:t.jsx(J,{size:20,color:"white"})})]})]}),t.jsx("style",{children:`
249
+ .glyde-spinner {
250
+ width: 24px;
251
+ height: 24px;
252
+ border: 2px solid var(--glyde-border, #e5e7eb);
253
+ border-top-color: var(--glyde-secondary, #0284c7);
254
+ border-radius: 50%;
255
+ animation: spin 1s linear infinite;
256
+ }
257
+ @keyframes spin {
258
+ to { transform: rotate(360deg); }
259
+ }
260
+ @keyframes typing-dot {
261
+ 0%, 60%, 100% { opacity: 0.3; }
262
+ 30% { opacity: 1; }
263
+ }
264
+ `})]})},he=({message:o})=>{const e=o.role==="user";return t.jsxs("div",{style:{display:"flex",gap:"10px",flexDirection:e?"row-reverse":"row",alignItems:"flex-start"},children:[t.jsx("div",{style:{width:"32px",height:"32px",borderRadius:"50%",background:e?"var(--glyde-primary-light, #e0e7ff)":"var(--glyde-secondary-light, #f0f9ff)",display:"flex",alignItems:"center",justifyContent:"center",flexShrink:0},children:e?t.jsx(q,{size:18,color:"var(--glyde-primary, #4338ca)"}):t.jsx(Y,{size:18,color:"var(--glyde-secondary, #0284c7)"})}),t.jsx("div",{style:{padding:"12px 16px",borderRadius:"12px",background:e?"var(--glyde-primary, #4338ca)":"var(--glyde-surface, #f1f5f9)",color:e?"white":"var(--glyde-text, #1e293b)",maxWidth:"70%",borderTopRightRadius:e?"4px":"12px",borderTopLeftRadius:e?"12px":"4px",lineHeight:1.5},children:o.content})]})},pe=()=>t.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"4px"},children:[t.jsx("span",{children:"Typing"}),t.jsx("span",{style:{display:"flex",gap:"2px"},children:[0,1,2].map(o=>t.jsx("span",{style:{width:"4px",height:"4px",borderRadius:"50%",background:"var(--glyde-text-muted, #94a3b8)",animation:"typing-dot 1.4s infinite",animationDelay:`${o*.2}s`}},o))})]}),z=({publishableKey:o,apiKey:e,authToken:r,contextId:i,unityBaseUrl:s="https://api.glydeunity.com",contextType:n="screening",defaultMode:h="voice",position:y="bottom-right",theme:f="light",allowModeSwitch:p=!0,container:b,onReady:a,onModeChange:g,onTranscript:v,onError:k,initialExpanded:m=!1})=>{const[u,w]=l.useState(m),[C,I]=l.useState(h);l.useEffect(()=>{const S=f==="auto"?window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light":f;W(S)},[f]),l.useEffect(()=>{a?.()},[a]);const T=te(y),d=S=>{I(S),g?.(S)},M=(S,D)=>{v?.(S,D)},E=S=>{k?.(S)};return b?t.jsx(ge,{publishableKey:o,apiKey:e,authToken:r,contextId:i,unityBaseUrl:s,contextType:n,mode:C,allowModeSwitch:p,onModeChange:d,onTranscript:M,onError:E}):t.jsxs("div",{className:"glyde-widget-root",children:[!u&&t.jsx("button",{onClick:()=>w(!0),style:{...x.floatingButton,...T.button,background:"linear-gradient(135deg, var(--glyde-primary, #c026d3) 0%, var(--glyde-secondary, #7c3aed) 100%)"},"aria-label":"Open chat",children:t.jsx(L,{size:28,color:"white"})}),u&&t.jsxs("div",{style:{...x.widgetPanel,...T.panel,background:"var(--glyde-background, white)"},className:"glyde-slide-up",children:[t.jsxs("div",{style:{...x.header,background:"linear-gradient(135deg, var(--glyde-primary, #c026d3) 0%, var(--glyde-secondary, #7c3aed) 100%)",color:"white",borderTopLeftRadius:"16px",borderTopRightRadius:"16px"},children:[t.jsxs("div",{children:[t.jsx("h3",{style:{margin:0,fontSize:"1rem",fontWeight:600},children:"GLYDE Assistant"}),t.jsx("small",{style:{opacity:.8,fontSize:"0.75rem"},children:n==="screening"?"Candidate Screening":"AI Assistant"})]}),t.jsxs("div",{style:{display:"flex",gap:"8px"},children:[t.jsx("button",{onClick:()=>w(!1),style:{...x.iconButton,background:"rgba(255,255,255,0.2)",width:"32px",height:"32px"},"aria-label":"Minimize",children:t.jsx(R,{size:16,color:"white"})}),t.jsx("button",{onClick:()=>w(!1),style:{...x.iconButton,background:"rgba(255,255,255,0.2)",width:"32px",height:"32px"},"aria-label":"Close",children:t.jsx(Q,{size:16,color:"white"})})]})]}),p&&t.jsx("div",{style:{padding:"12px 16px",borderBottom:"1px solid var(--glyde-border, #e5e7eb)"},children:t.jsx(re,{mode:C,onModeChange:d})}),t.jsx("div",{style:{flex:1,display:"flex",flexDirection:"column",overflow:"hidden"},children:C==="voice"?t.jsx(O,{publishableKey:o,apiKey:e,authToken:r,contextId:i||"",unityApiUrl:s,contextType:n,height:"100%",onTranscript:M,onError:E}):t.jsx(_,{publishableKey:o,apiKey:e,authToken:r,contextId:i||"",unityApiUrl:s,height:"100%",title:"Text Chat",onError:E})})]})]})},re=({mode:o,onModeChange:e})=>t.jsxs("div",{style:x.modeSelector,children:[t.jsxs("button",{onClick:()=>e("voice"),style:{...x.modeSelectorButton,background:o==="voice"?"var(--glyde-primary, #c026d3)":"transparent",color:o==="voice"?"white":"var(--glyde-text, #1f2937)"},children:[t.jsx(L,{size:16})," Voice"]}),t.jsxs("button",{onClick:()=>e("text"),style:{...x.modeSelectorButton,background:o==="text"?"var(--glyde-secondary, #0284c7)":"transparent",color:o==="text"?"white":"var(--glyde-text, #1f2937)"},children:[t.jsx(U,{size:16})," Text"]})]}),ge=({publishableKey:o,apiKey:e,authToken:r,contextId:i,unityBaseUrl:s,contextType:n,mode:h,allowModeSwitch:y,onModeChange:f,onTranscript:p,onError:b})=>{const[a,g]=l.useState(h),v=k=>{g(k),f(k)};return t.jsxs("div",{className:"glyde-widget-root",style:{height:"100%",display:"flex",flexDirection:"column"},children:[y&&t.jsx("div",{style:{padding:"12px 16px",borderBottom:"1px solid var(--glyde-border, #e5e7eb)",background:"var(--glyde-background, white)"},children:t.jsx(re,{mode:a,onModeChange:v})}),t.jsx("div",{style:{flex:1,overflow:"hidden"},children:a==="voice"?t.jsx(O,{publishableKey:o,apiKey:e,authToken:r,contextId:i||"",unityApiUrl:s,contextType:n,height:"100%",onTranscript:p,onError:b}):t.jsx(_,{publishableKey:o,apiKey:e,authToken:r,contextId:i||"",unityApiUrl:s,height:"100%",title:"Text Chat",onError:b})})]})};let A=null,B=null;const j={init(o){if(!o.publishableKey&&!o.apiKey&&!o.authToken)return console.error("[GlydeChat] Authentication required: provide publishableKey, apiKey, or authToken"),null;const e=o.theme==="auto"?window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light":o.theme||"light";W(e),A&&B&&(A.unmount(),B.remove(),A=null,B=null);const r=document.createElement("div");r.id="glyde-chat-widget",r.className="glyde-widget-root",document.body.appendChild(r),B=r;const i=V.createRoot(r);return A=i,i.render(l.createElement(z,{...o,initialExpanded:!1})),console.log("[GlydeChat] Widget initialized"),{destroy(){A&&B&&(A.unmount(),B.remove(),A=null,B=null,console.log("[GlydeChat] Widget destroyed"))},update(s){A&&A.render(l.createElement(z,{...o,...s}))}}},render(o,e){const r=typeof o=="string"?document.querySelector(o):o;if(!r)return console.error("[GlydeChat] Container not found:",o),null;const i=e.theme==="auto"?window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light":e.theme||"light";W(i);const s=V.createRoot(r);return s.render(l.createElement(z,{...e,container:r})),{destroy(){s.unmount()},update(n){s.render(l.createElement(z,{...e,...n,container:r}))}}},isReady(){return!0},get version(){return"__SDK_VERSION__"}};function ue(){const o=document.querySelectorAll('script[src*="glyde-chat"]'),e=o[o.length-1];if(!e||e.getAttribute("data-auto-init")!=="true")return;const i={publishableKey:e.getAttribute("data-publishable-key")||void 0,apiKey:e.getAttribute("data-api-key")||void 0,authToken:e.getAttribute("data-auth-token")||void 0,contextId:e.getAttribute("data-context-id")||void 0,unityBaseUrl:e.getAttribute("data-unity-url")||"https://api.glydeunity.com",contextType:e.getAttribute("data-context-type")||"screening",defaultMode:e.getAttribute("data-default-mode")||"voice",position:e.getAttribute("data-position")||"bottom-right",theme:e.getAttribute("data-theme")||"light",allowModeSwitch:e.getAttribute("data-allow-mode-switch")!=="false"};if(!i.publishableKey&&!i.apiKey&&!i.authToken){console.warn("[GlydeChat] Auto-init skipped: no authentication provided");return}document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>j.init(i)):j.init(i)}typeof window<"u"&&(window.GlydeChat=j,ue()),c.ActivityIcon=X,c.BotIcon=Y,c.ChatWidget=z,c.GlydeChat=j,c.GlydeText=F,c.GlydeVoice=$,c.LoaderIcon=ae,c.MessageIcon=U,c.MicIcon=L,c.MicOffIcon=se,c.MinimizeIcon=R,c.PhoneIcon=ne,c.PhoneOffIcon=K,c.SendIcon=J,c.TextChat=_,c.UserIcon=q,c.VoiceChat=O,c.VolumeXIcon=Z,c.XIcon=Q,c.componentStyles=x,c.getPositionStyles=te,c.getThemeCSSVariables=P,c.globalStyles=N,c.injectGlobalStyles=W,c.themeColors=ee,c.updateTheme=le,c.useTextChat=H,c.useVoiceAgent=G,Object.defineProperty(c,Symbol.toStringTag,{value:"Module"})}));
265
+ //# sourceMappingURL=glyde-chat.umd.js.map