@glydeunity/voice-sdk 1.4.0 → 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 +14 -8
- package/dist/glyde-chat.umd.js.map +1 -1
- package/dist/index.d.ts +6 -0
- package/dist/voice-sdk.es.js +313 -272
- package/dist/voice-sdk.es.js.map +1 -1
- package/package.json +4 -3
package/dist/glyde-chat.umd.js
CHANGED
|
@@ -130,14 +130,20 @@ class AudioPlaybackProcessor extends AudioWorkletProcessor {
|
|
|
130
130
|
}
|
|
131
131
|
|
|
132
132
|
registerProcessor('audio-playback-processor', AudioPlaybackProcessor);
|
|
133
|
-
`;class
|
|
133
|
+
`;class D{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;conversationHistory=[];sessionContext={};constructor(e){this.config=e,this.unityUrl=e.unityBaseUrl||"https://api.glydeunity.com",e.conversationHistory&&(this.conversationHistory=e.conversationHistory),!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});let f=this.config.systemPrompt||n.instructions||this.serverConfig?.system_prompt||"You are a helpful AI assistant.";this.conversationHistory&&this.conversationHistory.length>0&&(f=`Previous conversation context:
|
|
134
|
+
${this.conversationHistory.map(g=>`${g.role==="agent"?"Assistant":"User"}: ${g.content}`).join(`
|
|
135
|
+
`)}
|
|
136
|
+
|
|
137
|
+
IMPORTANT: 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.
|
|
138
|
+
|
|
139
|
+
${f}`),await this.initializeAudio();let p="wss://agent.deepgram.com/v1/agent/converse";const u=this.config.deepgramConfig||h||this.serverConfig?.deepgram_config;if(u?.tags&&u.tags.length>0){const a=new URLSearchParams;u.tags.forEach(g=>a.append("tag",g)),p+=`?${a.toString()}`}this.ws=new WebSocket(p,["bearer",s]),this.ws.onopen=()=>{const a=u||{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}},...!this.conversationHistory||this.conversationHistory.length===0?{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 m=f;this.ws.onmessage=a=>{if(typeof a.data=="string"){try{const g=JSON.parse(a.data);if(g.type==="SettingsApplied"){const b={type:"UpdatePrompt",prompt:m};this.ws.send(JSON.stringify(b)),setTimeout(()=>{this.mediaStream||this.startMicrophone().catch(k=>{console.error("[GlydeVoice] Failed to start microphone:",k)})},500)}g.type==="PromptUpdated"&&(this.mediaStream||this.startMicrophone().catch(b=>{console.error("[GlydeVoice] Failed to start microphone:",b)}))}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"PromptUpdated":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 u=0;u<n.length;u++)h[u]=n[u]/32768;const f=this.resample24kTo48k(h);!this.isAgentSpeaking&&!this.agentAudioDoneReceived&&(this.isAgentSpeaking=!0,this.emit({type:"agent_speaking",payload:!0}));const p=new Float32Array(f);this.playbackWorkletNode.port.postMessage({type:"audio",data:p},[p.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],f=e[n+1];i[n*2]=h,i[n*2+1]=(h+f)/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
140
|
<div style="padding: 20px; border: 1px solid #ccc; border-radius: 8px; background: #fff;">
|
|
135
141
|
<h3>Glyde Voice Agent</h3>
|
|
136
142
|
<p>Status: Active</p>
|
|
137
143
|
<p>Context: ${this.config.contextType}</p>
|
|
138
144
|
<button onclick="this.closest('div').remove()">Close</button>
|
|
139
145
|
</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`
|
|
146
|
+
`)}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 G{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 f=await i.json().catch(()=>({}));throw new Error(f.error?.message||f.message||"Failed to send message")}const s=await i.json();s.history?.messages&&(this.history=s.history.messages);const n=[...this.history].reverse().find(f=>f.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 H(o){const[e,r]=l.useState("idle"),[i,s]=l.useState([]),[n,h]=l.useState(!1),[f,p]=l.useState(!1),[u,m]=l.useState(!1),[a,g]=l.useState(null),b=l.useRef(null),k=l.useCallback(d=>{switch(d.type){case"ready":r("active");break;case"close":r("idle"),h(!1),p(!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":p(!!d.payload);break}},[]),v=l.useCallback((d,M)=>{s(E=>[...E,{role:M,content:d,timestamp:new Date}])},[]),y=l.useCallback(async()=>{r("connecting"),g(null);try{const d=new D({...o,onEvent:k,onTranscript:v});b.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,v]),w=l.useCallback(()=>{b.current?.stop(),b.current=null,r("idle"),h(!1),p(!1)},[]),C=l.useCallback(()=>{const d=!u;m(d),b.current?.setMuted(d)},[u]),I=l.useCallback(d=>{m(d),b.current?.setMuted(d)},[]),T=l.useCallback(()=>{s([])},[]);return l.useEffect(()=>()=>{b.current?.stop()},[]),l.useEffect(()=>{o.autoStart&&e==="idle"&&y()},[o.autoStart,e,y]),{status:e,transcripts:i,isUserSpeaking:n,isAgentSpeaking:f,isMuted:u,errorMessage:a,start:y,stop:w,toggleMute:C,setMuted:I,clearTranscripts:T,voiceAgent:b.current}}function F(o){const[e,r]=l.useState("idle"),[i,s]=l.useState([]),[n,h]=l.useState(!1),[f,p]=l.useState(null),u=l.useRef(null),m=l.useRef(!1),a=l.useCallback(()=>(u.current||(u.current=new G({...o,onTyping:h})),u.current),[o]),g=l.useCallback(async()=>{if(!m.current){r("loading"),p(null);try{const y=await a().initialize();s(y),r("ready"),m.current=!0}catch(v){console.error("[useTextChat] Initialization error:",v),r("error"),p(v instanceof Error?v.message:"Failed to initialize chat")}}},[a]),b=l.useCallback(async v=>{if(v.trim()){p(null);try{const y=a(),w={role:"user",content:v.trim(),created:new Date().toISOString()};s(I=>[...I,w]),await y.sendMessage(v);const C=y.getHistory();s(C),e!=="ready"&&(r("ready"),m.current=!0)}catch(y){console.error("[useTextChat] Send message error:",y),p(y instanceof Error?y.message:"Failed to send message")}}},[a,e]),k=l.useCallback(()=>{u.current?.clearHistory(),s([]),m.current=!1,r("idle")},[]);return l.useEffect(()=>{o.autoInit&&!m.current&&o.contextId&&g()},[o.autoInit,o.contextId,g]),l.useEffect(()=>()=>{u.current=null},[]),{status:e,messages:i,isLoading:n,errorMessage:f,initialize:g,sendMessage:b,clearHistory:k,textChat:u.current}}const W=({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"})]}),j=({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 U(o){const e=ee[o];return`
|
|
141
147
|
--glyde-primary: ${e.primary};
|
|
142
148
|
--glyde-primary-hover: ${e.primaryHover};
|
|
143
149
|
--glyde-primary-light: ${e.primaryLight};
|
|
@@ -217,19 +223,19 @@ registerProcessor('audio-playback-processor', AudioPlaybackProcessor);
|
|
|
217
223
|
.glyde-slide-up {
|
|
218
224
|
animation: glyde-slide-up 0.3s ease-out;
|
|
219
225
|
}
|
|
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
|
|
226
|
+
`,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 L(o="light"){const e="glyde-widget-styles";if(document.getElementById(e))return;const r=document.createElement("style");r.id=e,r.textContent=`
|
|
221
227
|
:root {
|
|
222
|
-
${
|
|
228
|
+
${U(o)}
|
|
223
229
|
}
|
|
224
230
|
|
|
225
231
|
${N}
|
|
226
232
|
`,document.head.appendChild(r)}function le(o){const r=document.getElementById("glyde-widget-styles");r?r.textContent=`
|
|
227
233
|
:root {
|
|
228
|
-
${
|
|
234
|
+
${U(o)}
|
|
229
235
|
}
|
|
230
236
|
|
|
231
237
|
${N}
|
|
232
|
-
`:
|
|
238
|
+
`:L(o)}const O=({contextId:o,publishableKey:e,apiKey:r,authToken:i,unityApiUrl:s="https://api.glydeunity.com",contextType:n="screening",height:h="600px",onTranscript:f,onCallEnd:p,onError:u})=>{const m=l.useRef(null),{status:a,transcripts:g,isUserSpeaking:b,isAgentSpeaking:k,isMuted:v,errorMessage:y,start:w,stop:C,toggleMute:I,clearTranscripts:T}=H({publishableKey:e,apiKey:r,authToken:i,contextType:n,contextId:o,unityBaseUrl:s});l.useEffect(()=>{m.current?.scrollIntoView({behavior:"smooth"})},[g]),l.useEffect(()=>{if(f&&g.length>0){const S=g[g.length-1];f(S.content,S.role)}},[g,f]),l.useEffect(()=>{a==="error"&&y&&u&&u(new Error(y))},[a,y,u]);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(),p?.()};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(W,{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"]}),y&&t.jsx("p",{style:{color:"var(--glyde-error, #ef4444)",marginTop:"16px",fontSize:"0.9rem"},children:y})]}):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(j,{size:32,color:"var(--glyde-text-muted, #9ca3af)"}),t.jsx("p",{style:{marginTop:"8px"},children:"Start speaking - the AI will respond"})]}),g.map((S,$)=>t.jsx(de,{transcript:S,contextType:n},$)),t.jsx("div",{ref:m})]}),t.jsxs("div",{style:{padding:"16px",borderTop:"1px solid var(--glyde-border, #e5e7eb)",background:"var(--glyde-background, white)"},children:[t.jsx(ce,{isUserSpeaking:b,isAgentSpeaking:k}),t.jsxs("div",{style:{display:"flex",justifyContent:"center",gap:"12px",marginTop:"16px"},children:[t.jsx("button",{onClick:I,style:{...x.iconButton,background:v?"var(--glyde-error-light, #fecaca)":"var(--glyde-secondary-light, #e0f2fe)"},title:v?"Unmute":"Mute",children:v?t.jsx(Z,{size:20,color:"var(--glyde-error, #dc2626)"}):t.jsx(W,{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
239
|
@keyframes glyde-pulse {
|
|
234
240
|
0%, 100% { opacity: 1; transform: scale(1); }
|
|
235
241
|
50% { opacity: 0.5; transform: scale(1.2); }
|
|
@@ -245,7 +251,7 @@ registerProcessor('audio-playback-processor', AudioPlaybackProcessor);
|
|
|
245
251
|
@keyframes spin {
|
|
246
252
|
to { transform: rotate(360deg); }
|
|
247
253
|
}
|
|
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:
|
|
254
|
+
`})]})},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:f="Type your message...",autoInit:p=!0,onMessage:u,onError:m})=>{const[a,g]=l.useState(""),b=l.useRef(null),{status:k,messages:v,isLoading:y,errorMessage:w,sendMessage:C}=F({publishableKey:e,apiKey:r,authToken:i,contextId:o,unityBaseUrl:s,autoInit:p});l.useEffect(()=>{b.current?.scrollIntoView({behavior:"smooth"})},[v]),l.useEffect(()=>{k==="error"&&w&&m&&m(new Error(w))},[k,w,m]);const I=async()=>{if(!a.trim()||y)return;const d=a.trim();g(""),await C(d),u&&u({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"&&v.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..."]}),v.map((d,M)=>t.jsx(he,{message:d},M)),y&&t.jsx("div",{style:{color:"var(--glyde-text-muted, #94a3b8)",fontSize:"0.9rem",marginLeft:"42px"},children:t.jsx(pe,{})}),t.jsx("div",{ref:b})]}),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:f,style:{...x.inputField,flex:1},disabled:y}),t.jsx("button",{onClick:I,disabled:y||!a.trim(),style:{...x.iconButton,background:"var(--glyde-secondary, #0284c7)",width:"48px",height:"48px",opacity:y||!a.trim()?.5:1,cursor:y||!a.trim()?"not-allowed":"pointer"},children:t.jsx(J,{size:20,color:"white"})})]})]}),t.jsx("style",{children:`
|
|
249
255
|
.glyde-spinner {
|
|
250
256
|
width: 24px;
|
|
251
257
|
height: 24px;
|
|
@@ -261,5 +267,5 @@ registerProcessor('audio-playback-processor', AudioPlaybackProcessor);
|
|
|
261
267
|
0%, 60%, 100% { opacity: 0.3; }
|
|
262
268
|
30% { opacity: 1; }
|
|
263
269
|
}
|
|
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:
|
|
270
|
+
`})]})},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:f="bottom-right",theme:p="light",allowModeSwitch:u=!0,container:m,onReady:a,onModeChange:g,onTranscript:b,onError:k,initialExpanded:v=!1})=>{const[y,w]=l.useState(v),[C,I]=l.useState(h);l.useEffect(()=>{const S=p==="auto"?window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light":p;L(S)},[p]),l.useEffect(()=>{a?.()},[a]);const T=te(f),d=S=>{I(S),g?.(S)},M=(S,$)=>{b?.(S,$)},E=S=>{k?.(S)};return m?t.jsx(ge,{publishableKey:o,apiKey:e,authToken:r,contextId:i,unityBaseUrl:s,contextType:n,mode:C,allowModeSwitch:u,onModeChange:d,onTranscript:M,onError:E}):t.jsxs("div",{className:"glyde-widget-root",children:[!y&&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(W,{size:28,color:"white"})}),y&&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"})})]})]}),u&&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(W,{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(j,{size:16})," Text"]})]}),ge=({publishableKey:o,apiKey:e,authToken:r,contextId:i,unityBaseUrl:s,contextType:n,mode:h,allowModeSwitch:f,onModeChange:p,onTranscript:u,onError:m})=>{const[a,g]=l.useState(h),b=k=>{g(k),p(k)};return t.jsxs("div",{className:"glyde-widget-root",style:{height:"100%",display:"flex",flexDirection:"column"},children:[f&&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:b})}),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:u,onError:m}):t.jsx(_,{publishableKey:o,apiKey:e,authToken:r,contextId:i||"",unityApiUrl:s,height:"100%",title:"Text Chat",onError:m})})]})};let A=null,B=null;const P={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";L(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";L(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){console.log("[GlydeChat] No script tag found for auto-init");return}const r=e.getAttribute("data-auto-init");if(r==="false"){console.log('[GlydeChat] Auto-init disabled via data-auto-init="false"');return}const i=e.getAttribute("data-publishable-key")||void 0,s=e.getAttribute("data-api-key")||void 0,n=e.getAttribute("data-auth-token")||void 0,h=i||s||n;if(!h&&!(r==="true")){console.log("[GlydeChat] Auto-init skipped: no authentication data attributes found. Call GlydeChat.init() manually.");return}if(!h){console.warn("[GlydeChat] Auto-init skipped: no authentication provided (publishableKey, apiKey, or authToken required)");return}const p={publishableKey:i,apiKey:s,authToken:n,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"};console.log("[GlydeChat] Auto-initializing with config:",{hasPublishableKey:!!p.publishableKey,hasApiKey:!!p.apiKey,hasAuthToken:!!p.authToken,contextId:p.contextId,defaultMode:p.defaultMode,position:p.position,theme:p.theme}),document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>P.init(p)):P.init(p)}typeof window<"u"&&(window.GlydeChat=P,ue()),c.ActivityIcon=X,c.BotIcon=Y,c.ChatWidget=z,c.GlydeChat=P,c.GlydeText=G,c.GlydeVoice=D,c.LoaderIcon=ae,c.MessageIcon=j,c.MicIcon=W,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=U,c.globalStyles=N,c.injectGlobalStyles=L,c.themeColors=ee,c.updateTheme=le,c.useTextChat=F,c.useVoiceAgent=H,Object.defineProperty(c,Symbol.toStringTag,{value:"Module"})}));
|
|
265
271
|
//# sourceMappingURL=glyde-chat.umd.js.map
|