avin-ai 0.1.0 â 0.1.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/avin-ai.js +9 -9
- package/package.json +2 -2
package/dist/avin-ai.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var x=Object.defineProperty;var y=(
|
|
1
|
+
var x=Object.defineProperty;var y=(d,a,p)=>a in d?x(d,a,{enumerable:!0,configurable:!0,writable:!0,value:p}):d[a]=p;var r=(d,a,p)=>y(d,typeof a!="symbol"?a+"":a,p);(function(){"use strict";class d{constructor(n){r(this,"serverUrl");r(this,"agentId");r(this,"callId");r(this,"pc",null);r(this,"dataChannel",null);r(this,"audioElement",null);r(this,"connected",!1);r(this,"onConnected");r(this,"onDisconnected");r(this,"onError");r(this,"onTranscription");if(!n.serverUrl)throw new Error("serverUrl is required");if(!n.agentId)throw new Error("agentId is required");this.serverUrl=n.serverUrl.replace(/\/$/,""),this.agentId=n.agentId,this.callId=this.generateCallId(),this.onConnected=n.onConnected||(()=>{}),this.onDisconnected=n.onDisconnected||(()=>{}),this.onError=n.onError||(t=>console.error("[WebRTC]",t)),this.onTranscription=n.onTranscription||(()=>{})}async connect(){console.log("đĩ [WebRTC] Starting connection...");try{this.pc=new RTCPeerConnection({iceServers:[{urls:"stun:stun.l.google.com:19302"}]}),this.pc.addTransceiver("video",{direction:"recvonly"});const n=await navigator.mediaDevices.getUserMedia({audio:{echoCancellation:!0,noiseSuppression:!0,autoGainControl:!0,sampleRate:{ideal:16e3},channelCount:1}});console.log("đ¤ [WebRTC] Microphone access granted"),n.getTracks().forEach(i=>{this.pc&&this.pc.addTrack(i,n)}),this.dataChannel=this.pc.createDataChannel("control"),this.dataChannel.onopen=()=>console.log("đĄ [WebRTC] DataChannel opened"),this.dataChannel.onmessage=i=>this.handleControlEvent(JSON.parse(i.data)),this.dataChannel.onerror=i=>console.error("â [WebRTC] DataChannel error:",i),this.pc.ontrack=i=>{const s=i.track,h=i.streams[0];console.log(`đĨ [WebRTC] Received ${s.kind} track`),s.kind==="audio"&&(console.log("đ [WebRTC] Setting up audio playback"),this.audioElement=new Audio,this.audioElement.srcObject=h,this.audioElement.play().catch(g=>console.warn("Audio autoplay blocked:",g)),this.audioElement.onended=()=>{this.sendEvent("playedStream")})},this.pc.onconnectionstatechange=()=>{var i,s,h,g,b;console.log("đ [WebRTC] State:",(i=this.pc)==null?void 0:i.connectionState),((s=this.pc)==null?void 0:s.connectionState)==="connected"?(this.connected=!0,this.onConnected()):(((h=this.pc)==null?void 0:h.connectionState)==="failed"||((g=this.pc)==null?void 0:g.connectionState)==="disconnected"||((b=this.pc)==null?void 0:b.connectionState)==="closed")&&(this.connected=!1,this.onDisconnected())};const t=await this.pc.createOffer();await this.pc.setLocalDescription(t),console.log("đ [WebRTC] Created offer, waiting for ICE gathering..."),await this.waitForIceGathering(),console.log("đ§ [WebRTC] ICE gathering complete"),console.log("đ¤ [WebRTC] Sending offer via HTTP...");const e=await fetch(`${this.serverUrl}/webrtc?agent=${this.agentId}_${this.callId}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({offer:this.pc.localDescription,agentId:this.agentId,callId:this.callId})});if(!e.ok){const i=await e.json();throw new Error(i.error||`HTTP ${e.status}`)}const{answer:o}=await e.json();console.log("đĨ [WebRTC] Received answer from server"),await this.pc.setRemoteDescription(o),console.log("â
[WebRTC] Connection established!")}catch(n){throw console.error("â [WebRTC] Connection failed:",n),this.onError(n.message||n),n}}waitForIceGathering(){return new Promise(n=>{if(!this.pc)return n();if(this.pc.iceGatheringState==="complete")n();else{const t=()=>{var e;((e=this.pc)==null?void 0:e.iceGatheringState)==="complete"&&(this.pc.removeEventListener("icegatheringstatechange",t),n())};this.pc.addEventListener("icegatheringstatechange",t),setTimeout(()=>{var e;(e=this.pc)==null||e.removeEventListener("icegatheringstatechange",t),console.warn("â ī¸ [WebRTC] ICE gathering timeout, proceeding anyway"),n()},5e3)}})}sendEvent(n,t={}){var e;((e=this.dataChannel)==null?void 0:e.readyState)==="open"&&this.dataChannel.send(JSON.stringify({event:n,...t}))}handleControlEvent(n){switch(n.event){case"clearAudio":console.log("đ [WebRTC] Interrupt: stopping audio"),this.audioElement&&(this.audioElement.pause(),this.audioElement.currentTime=0);break;case"transcription":console.log("đ [WebRTC] Transcription:",n.text),n.text&&this.onTranscription(n.text,!!n.isFinal);break;case"mark":console.log("đˇī¸ [WebRTC] Mark:",n.name);break;default:console.log("âšī¸ [WebRTC] Unknown event:",n.event)}}disconnect(){console.log("đ´ [WebRTC] Disconnecting..."),this.audioElement&&(this.audioElement.pause(),this.audioElement.srcObject=null),this.dataChannel&&this.dataChannel.close(),this.pc&&this.pc.close(),this.connected=!1,this.onDisconnected()}generateCallId(){return"web_"+Date.now()+"_"+Math.random().toString(36).substr(2,8)}}const a="https://coredb.travelr.club/v1/graphql";async function p(c){var t;const n=`
|
|
2
2
|
query GetWidgetConfig($id: uuid!) {
|
|
3
3
|
app_widget_by_pk(id: $id) {
|
|
4
4
|
agent_id
|
|
@@ -13,7 +13,7 @@ var x=Object.defineProperty;var y=(l,a,h)=>a in l?x(l,a,{enumerable:!0,configura
|
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
|
-
`;try{const i=(t=(await(await fetch(a,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({query:n,variables:{id:c}})})).json()).data)==null?void 0:t.app_widget_by_pk;if(!i)throw new Error(`Widget configuration not found for ID: ${c}`);return i}catch(e){throw console.error("[AvinAI] Failed to fetch widget config:",e),e}}const
|
|
16
|
+
`;try{const i=(t=(await(await fetch(a,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({query:n,variables:{id:c}})})).json()).data)==null?void 0:t.app_widget_by_pk;if(!i)throw new Error(`Widget configuration not found for ID: ${c}`);return i}catch(e){throw console.error("[AvinAI] Failed to fetch widget config:",e),e}}const u={phone:`
|
|
17
17
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
18
18
|
<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"/>
|
|
19
19
|
</svg>
|
|
@@ -298,20 +298,20 @@ var x=Object.defineProperty;var y=(l,a,h)=>a in l?x(l,a,{enumerable:!0,configura
|
|
|
298
298
|
border-radius: 0;
|
|
299
299
|
}
|
|
300
300
|
}
|
|
301
|
-
`;class f extends HTMLElement{constructor(){super();r(this,"isPanelOpen",!1);r(this,"callActive",!1);r(this,"transcript","");r(this,"client",null);r(this,"shadow");r(this,"widgetId","");r(this,"serverUrl","https://api.travelr.club");r(this,"agentId","");this.shadow=this.attachShadow({mode:"open"})}static get observedAttributes(){return["widget-id","agent-id","position","primary-color","server-url"]}connectedCallback(){console.log("[AvinAI Widget] Initializing..."),this.widgetId=this.getAttribute("widget-id")||"",this.agentId=this.getAttribute("agent-id")||"",this.serverUrl=this.getAttribute("server-url")||"https://api.travelr.club";const t=this.getAttribute("position")||"bottom-right",e=this.getAttribute("primary-color")||"#6366f1";this.render(t,e),this.attachEventListeners(),this.widgetId&&!this.agentId&&this.initializeConfig()}async initializeConfig(){var t,e,o,i;try{console.log(`[AvinAI Widget] Fetching config for widget: ${this.widgetId}`);const s=await
|
|
301
|
+
`;class f extends HTMLElement{constructor(){super();r(this,"isPanelOpen",!1);r(this,"callActive",!1);r(this,"transcript","");r(this,"client",null);r(this,"shadow");r(this,"widgetId","");r(this,"serverUrl","https://api.travelr.club");r(this,"agentId","");this.shadow=this.attachShadow({mode:"open"})}static get observedAttributes(){return["widget-id","agent-id","position","primary-color","server-url"]}connectedCallback(){console.log("[AvinAI Widget] Initializing..."),this.widgetId=this.getAttribute("widget-id")||"",this.agentId=this.getAttribute("agent-id")||"",this.serverUrl=this.getAttribute("server-url")||"https://api.travelr.club";const t=this.getAttribute("position")||"bottom-right",e=this.getAttribute("primary-color")||"#6366f1";this.render(t,e),this.attachEventListeners(),this.widgetId&&!this.agentId&&this.initializeConfig()}async initializeConfig(){var t,e,o,i;try{console.log(`[AvinAI Widget] Fetching config for widget: ${this.widgetId}`);const s=await p(this.widgetId);this.agentId=s.agent_id,((i=(o=(e=(t=s.agent)==null?void 0:t.tts_voice)==null?void 0:e.provider)==null?void 0:o.root_name)==null?void 0:i.toLowerCase())==="premium"?this.serverUrl="https://godspeed.travelr.club":this.serverUrl="https://in-godspeed.travelr.club",console.log(`[AvinAI Widget] Configured for Agent ID: ${this.agentId}`),console.log(`[AvinAI Widget] Using Server URL: ${this.serverUrl}`)}catch(s){console.error("[AvinAI Widget] Configuration failed:",s),this.updateStatus("Configuration Failed","error")}}render(t,e){const o={"bottom-right":{bottom:"24px",right:"24px"},"bottom-left":{bottom:"24px",left:"24px"},"top-right":{top:"24px",right:"24px"},"top-left":{top:"24px",left:"24px"}},i=o[t]||o["bottom-right"],s=Object.entries(i).map(([v,m])=>`${v}: ${m}`).join("; "),h=t.includes("bottom")?"bottom: 100px;":"top: 100px;",g=t.includes("right")?"right: 24px;":"left: 24px;",b=w.replace("--primary: #6366f1",`--primary: ${e}`);this.shadow.innerHTML=`
|
|
302
302
|
<style>${b}</style>
|
|
303
303
|
|
|
304
304
|
<!-- Floating Action Button -->
|
|
305
305
|
<button class="widget-fab" style="${s}">
|
|
306
|
-
${
|
|
306
|
+
${u.phone}
|
|
307
307
|
</button>
|
|
308
308
|
|
|
309
309
|
<!-- Voice Panel -->
|
|
310
|
-
<div class="widget-panel hidden" style="width: 380px; height: 480px; ${
|
|
310
|
+
<div class="widget-panel hidden" style="width: 380px; height: 480px; ${h} ${g}">
|
|
311
311
|
<div class="widget-header">
|
|
312
312
|
<h3 class="widget-title">Voice Assistant</h3>
|
|
313
313
|
<button class="close-btn" id="close-panel">
|
|
314
|
-
${
|
|
314
|
+
${u.close}
|
|
315
315
|
</button>
|
|
316
316
|
</div>
|
|
317
317
|
|
|
@@ -327,11 +327,11 @@ var x=Object.defineProperty;var y=(l,a,h)=>a in l?x(l,a,{enumerable:!0,configura
|
|
|
327
327
|
|
|
328
328
|
<div class="controls" id="controls">
|
|
329
329
|
<button class="control-btn primary" id="start-btn">
|
|
330
|
-
${
|
|
330
|
+
${u.mic}
|
|
331
331
|
<span>Start Call</span>
|
|
332
332
|
</button>
|
|
333
333
|
</div>
|
|
334
334
|
</div>
|
|
335
335
|
</div>
|
|
336
|
-
`}attachEventListeners(){const t=this.shadow.querySelector(".widget-fab"),e=this.shadow.querySelector(".widget-panel"),o=this.shadow.querySelector("#close-panel"),i=this.shadow.querySelector("#start-btn");t==null||t.addEventListener("click",()=>{this.isPanelOpen=!this.isPanelOpen,e==null||e.classList.toggle("hidden",!this.isPanelOpen)}),o==null||o.addEventListener("click",()=>{this.isPanelOpen=!1,e==null||e.classList.add("hidden")}),i==null||i.addEventListener("click",()=>{this.callActive?this.stopCall():this.startCall()})}updateStatus(t,e){const o=this.shadow.querySelector("#status-text"),i=this.shadow.querySelector("#status-dot");o&&(o.textContent=t),i&&(e==="idle"&&(i.style.background="#ef4444"),e==="connecting"&&(i.style.background="#f59e0b"),e==="connected"&&(i.style.background="#10b981"),e==="error"&&(i.style.background="#ef4444"))}async startCall(){if(!this.agentId){this.updateStatus("Error: Agent ID not configured","error");return}const t=this.shadow.querySelector("#start-btn"),e=this.shadow.querySelector("#transcript");try{this.updateStatus("Connecting...","connecting"),t&&(t.disabled=!0),this.client=new
|
|
337
|
-
`:"")+o,e&&(e.innerHTML=this.transcript,e.scrollTop=e.scrollHeight))}}),await this.client.connect()}catch(o){console.error("[AvinAI Widget] Start call failed:",o),this.updateStatus("Connection failed","error"),t&&(t.disabled=!1)}}stopCall(){this.client&&(this.client.disconnect(),this.client=null),this.callActive=!1,this.updateStatus("Click Start to begin conversation","idle");const t=this.shadow.querySelector("#start-btn");t&&(t.innerHTML=`${
|
|
336
|
+
`}attachEventListeners(){const t=this.shadow.querySelector(".widget-fab"),e=this.shadow.querySelector(".widget-panel"),o=this.shadow.querySelector("#close-panel"),i=this.shadow.querySelector("#start-btn");t==null||t.addEventListener("click",()=>{this.isPanelOpen=!this.isPanelOpen,e==null||e.classList.toggle("hidden",!this.isPanelOpen)}),o==null||o.addEventListener("click",()=>{this.isPanelOpen=!1,e==null||e.classList.add("hidden")}),i==null||i.addEventListener("click",()=>{this.callActive?this.stopCall():this.startCall()})}updateStatus(t,e){const o=this.shadow.querySelector("#status-text"),i=this.shadow.querySelector("#status-dot");o&&(o.textContent=t),i&&(e==="idle"&&(i.style.background="#ef4444"),e==="connecting"&&(i.style.background="#f59e0b"),e==="connected"&&(i.style.background="#10b981"),e==="error"&&(i.style.background="#ef4444"))}async startCall(){if(!this.agentId){this.updateStatus("Error: Agent ID not configured","error");return}const t=this.shadow.querySelector("#start-btn"),e=this.shadow.querySelector("#transcript");try{this.updateStatus("Connecting...","connecting"),t&&(t.disabled=!0),this.client=new d({serverUrl:this.serverUrl,agentId:this.agentId,onConnected:()=>{this.callActive=!0,this.updateStatus("Connected - Listening...","connected"),t&&(t.innerHTML=`${u.close}<span>End Call</span>`,t.className="control-btn danger",t.disabled=!1)},onDisconnected:()=>{this.stopCall()},onError:o=>{this.updateStatus(`Error: ${o.message||"Connection failed"}`,"error"),t&&(t.disabled=!1)},onTranscription:(o,i)=>{i&&(this.transcript+=(this.transcript?`
|
|
337
|
+
`:"")+o,e&&(e.innerHTML=this.transcript,e.scrollTop=e.scrollHeight))}}),await this.client.connect()}catch(o){console.error("[AvinAI Widget] Start call failed:",o),this.updateStatus("Connection failed","error"),t&&(t.disabled=!1)}}stopCall(){this.client&&(this.client.disconnect(),this.client=null),this.callActive=!1,this.updateStatus("Click Start to begin conversation","idle");const t=this.shadow.querySelector("#start-btn");t&&(t.innerHTML=`${u.mic}<span>Start Call</span>`,t.className="control-btn primary",t.disabled=!1)}disconnectedCallback(){this.client&&this.client.disconnect()}}customElements.get("avin-convai")||customElements.define("avin-convai",f),typeof window<"u"&&(window.AvinConvAI=f);const l=document.currentScript;if(l){const c=l.getAttribute("data-widget-id")||l.getAttribute("widget-id"),n=l.getAttribute("data-agent-id")||l.getAttribute("agent-id");if(c||n){const t=l.getAttribute("data-position")||"bottom-right",e=l.getAttribute("data-primary-color")||"#6366f1",o=document.createElement("avin-convai");c&&o.setAttribute("widget-id",c),n&&o.setAttribute("agent-id",n),o.setAttribute("position",t),o.setAttribute("primary-color",e),document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>document.body.appendChild(o)):document.body.appendChild(o)}}})();
|
package/package.json
CHANGED