@guava-ai/guava-sdk 0.37.0 → 0.39.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.
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # Guava Typescript SDK
2
2
  [![NPM Version](https://img.shields.io/npm/v/%40guava-ai%2Fguava-sdk)](https://www.npmjs.com/package/@guava-ai/guava-sdk)
3
3
 
4
- This library allows you to build Guava voice agents using TypeScript or Javascript. Currently only NodeJS is officially supported as a runtime.
4
+ This library allows you to build Guava voice agents using TypeScript or Javascript. Currently only NodeJS is officially supported as a runtime for the main SDK. The WebRTC portion of the SDK can be used from the browser.
5
5
 
6
6
  ## Documentation
7
7
 
@@ -40,4 +40,46 @@ $ yarn add @guava-ai/guava-sdk
40
40
  $ pnpm add @guava-ai/guava-sdk
41
41
  ```
42
42
 
43
- The SDK can be used with Javascript, but TypeScript is highly recommended.
43
+ The SDK can be used with Javascript, but TypeScript is highly recommended.
44
+
45
+ ## Using WebRTC from the Browser
46
+
47
+ To call your agent from the browser with a bundler, install the SDK as above and import from `@guava-ai/guava-sdk/webrtc`.
48
+
49
+ ```typescript
50
+ import * as Guava from "@guava-ai/guava-sdk/webrtc";
51
+
52
+ const call = new Guava.Call({ webrtcCode: "..." });
53
+ await call.start();
54
+ ```
55
+
56
+ You can also load a prebuilt bundle from a CDN.
57
+
58
+ ```html
59
+ <script
60
+ src="https://cdn.jsdelivr.net/npm/@guava-ai/guava-sdk@0.39.0/dist/guava-webrtc.min.js"
61
+ integrity="sha384-1Y1pGUhd4tRQdEQaEUk/2nx9w2Mvl2EEXIZiTw4YFGfUSgp5o9hMJS8UibgJXrNp"
62
+ crossorigin="anonymous"
63
+ ></script>
64
+ <script>
65
+ const call = new Guava.Call({ webrtcCode: "..." });
66
+ call.start();
67
+ </script>
68
+ ```
69
+
70
+ Or as an ES module:
71
+
72
+ ```html
73
+ <script type="importmap">
74
+ {
75
+ "integrity": {
76
+ "https://cdn.jsdelivr.net/npm/@guava-ai/guava-sdk@0.39.0/dist/guava-webrtc.esm.min.js": "sha384-jtuG1DKqz8m5JdMoUZp4jTbGTZTrqJqWqf3tVxsWHqG08UPs7lU9EC4AZkdIzzp0"
77
+ }
78
+ }
79
+ </script>
80
+ <script type="module">
81
+ import * as Guava from "https://cdn.jsdelivr.net/npm/@guava-ai/guava-sdk@0.39.0/dist/guava-webrtc.esm.min.js";
82
+ const call = new Guava.Call({ webrtcCode: "..." });
83
+ await call.start();
84
+ </script>
85
+ ```
@@ -0,0 +1,2 @@
1
+ var f=Object.defineProperty;var S=(a,e,t)=>e in a?f(a,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):a[e]=t;var i=(a,e,t)=>S(a,typeof e!="symbol"?e+"":e,t);function _(a,e){return a*(60/e)}var u=class{constructor(){i(this,"context",null);i(this,"intervalId",null);i(this,"volume",.15);i(this,"onSeconds",2);i(this,"periodSeconds",6);i(this,"startDelay",.3)}start(){if(this.context)return;let e=new AudioContext,t=e.createGain();t.gain.value=0,t.connect(e.destination);for(let o of[440,480]){let d=e.createOscillator();d.frequency.value=o,d.connect(t),d.start()}let n=e.currentTime+this.startDelay,s=()=>{t.gain.setValueAtTime(this.volume,n),t.gain.setValueAtTime(0,n+this.onSeconds),n+=this.periodSeconds};s(),this.intervalId=setInterval(s,this.periodSeconds*1e3),this.context=e}stop(){this.context&&(this.intervalId&&(clearInterval(this.intervalId),this.intervalId=null),this.context.close(),this.context=null)}},h=class{constructor(){i(this,"context",null);i(this,"masterGain",null);i(this,"intervalId",null);i(this,"running",!1);i(this,"pulseCount",0);i(this,"nextBarStart",0);i(this,"volume",.3);i(this,"bpm",120);i(this,"beatsPerBar",4);i(this,"startDelay",.3)}start(){if(this.running)return;this.running=!0,this.pulseCount=0,this.context=new AudioContext,this.masterGain=this.context.createGain(),this.masterGain.gain.value=this.volume,this.masterGain.connect(this.context.destination),this.nextBarStart=this.context.currentTime+this.startDelay,this.playPulse(),this.playPulse();let e=_(this.beatsPerBar,this.bpm);this.intervalId=setInterval(()=>{this.playPulse()},e*1e3)}noteToFrequency(e){let t=e.match(/^([A-G])(#|b)?(-?\d+)$/);if(!t)throw new Error(`Invalid note: ${e}`);let[,n,s,o]=t,d={C:0,D:2,E:4,F:5,G:7,A:9,B:11},c=s==="#"?1:s==="b"?-1:0,l=(Number(o)+1)*12+d[n]+c;return 440*Math.pow(2,(l-69)/12)}stop(){if(!this.running)return;this.running=!1,this.intervalId&&(clearInterval(this.intervalId),this.intervalId=null);let e=this.context,t=this.masterGain;if(!e||!t)return;let n=e.currentTime;t.gain.setValueAtTime(t.gain.value,n),t.gain.linearRampToValueAtTime(0,n+.15),setTimeout(()=>{e.close()},200),this.context=null,this.masterGain=null}playPulse(){if(!this.context||!this.masterGain)return;let e=this.nextBarStart,t=s=>e+_(s,this.bpm),n=_(1,this.bpm);this.pulseCount%4===0||this.pulseCount%4===2?(this.playNote("C5",t(0),n),this.playNote("E5",t(.5),n),this.playNote("G4",t(1),n)):this.pulseCount%4===3?(this.playNote("E5",t(0),n),this.playNote("G5",t(.5),n),this.playNote("C5",t(1),n)):(this.playNote("E5",t(0),n),this.playNote("G4",t(.5),n),this.playNote("C5",t(1),n)),this.pulseCount++,this.nextBarStart=t(this.beatsPerBar)}playNote(e,t,n){if(!this.context||!this.masterGain)return;let s=this.context.createOscillator(),o=this.context.createGain();s.type="sine",s.frequency.value=this.noteToFrequency(e),o.gain.setValueAtTime(0,t),o.gain.linearRampToValueAtTime(.7,t+.05),o.gain.exponentialRampToValueAtTime(.001,t+n),s.connect(o),o.connect(this.masterGain),s.start(t),s.stop(t+n+.01),s.onended=()=>{s.disconnect(),o.disconnect()}}},p=class{play(){let e=new AudioContext;e.state==="suspended"&&e.resume();let t=e.currentTime,n=this.playNote(e,{frequency:293.665,startTime:t,attack:.065,decay:.085,volume:.2}),s=this.playNote(e,{frequency:220,startTime:t+.139,attack:.018,decay:.075,volume:.2});Promise.all([n,s]).then(()=>e.close())}playNote(e,{frequency:t,startTime:n,attack:s,decay:o,volume:d}){let c=e.createOscillator(),l=e.createGain();c.type="sine",c.frequency.setValueAtTime(t,n),l.gain.setValueAtTime(0,n),l.gain.linearRampToValueAtTime(d,n+s);let m=n+s,v=m+o*5;return l.gain.setTargetAtTime(1e-5,m,o),c.connect(l),l.connect(e.destination),c.start(n),c.stop(v),new Promise(y=>{c.onended=()=>{c.disconnect(),l.disconnect(),y()}})}};var r=class extends Error{constructor(t,n,s){super(n,s);i(this,"code");this.name="CallError",this.code=t}},C=[{urls:["stun:stun.l.google.com:19302","stun:stun.sipgate.net:10000"]}],T={"http:":"ws:","https:":"wss:","ws:":"ws:","wss:":"wss:"},g=class{constructor({webrtcCode:e,baseUrl:t="https://app.goguava.ai/",connectingTone:n=new h,leavingTone:s=new p,connectionTimeoutMs:o=3e4,customPayload:d={}}){i(this,"_state","not-started");i(this,"_error");i(this,"_stateHandlers",new Set);i(this,"_remoteStreamHandlers",new Set);i(this,"_messageHandlers",new Set);i(this,"_webrtcCode");i(this,"_sockUrl");i(this,"_remoteAudio");i(this,"_connectingTone");i(this,"_leavingTone");i(this,"_connectionTimeoutMs");i(this,"_customPayload");i(this,"_connectionTimer");i(this,"_sock");i(this,"_chatSockUrl");i(this,"_chatSessionId",crypto.randomUUID());i(this,"_chatSock");i(this,"_chatReady",!1);i(this,"_pendingChatMessages",[]);i(this,"_localStream");i(this,"_peerConnection");i(this,"_remoteStream");i(this,"_iceServers");i(this,"_pendingStart");this._webrtcCode=e,this._customPayload=d,n!=="disabled"&&(this._connectingTone=n),s!=="disabled"&&(this._leavingTone=s),o!=="disabled"&&(this._connectionTimeoutMs=o),this._sockUrl=new URL("/webrtc/",t);let c=T[this._sockUrl.protocol];if(c===void 0)throw new Error(`Unsupported baseUrl protocol: ${this._sockUrl.protocol}`);this._sockUrl.protocol=c,this._chatSockUrl=new URL("/webrtc-chat/",this._sockUrl),this._remoteAudio=document.createElement("audio"),this._remoteAudio.autoplay=!0}get state(){return this._state}get error(){return this._error}get remoteStream(){return this._remoteStream}onStateChange(e){return this._stateHandlers.add(e),()=>{this._stateHandlers.delete(e)}}onRemoteStream(e){return this._remoteStreamHandlers.add(e),()=>{this._remoteStreamHandlers.delete(e)}}onMessage(e){return this._messageHandlers.add(e),()=>{this._messageHandlers.delete(e)}}_setState(e){if(e!==this._state){e==="ended"&&this._leavingTone?.play(),this._state=e,e==="connecting"?(this._connectingTone?.start(),this._connectionTimeoutMs!==void 0&&(this._connectionTimer=setTimeout(()=>{this._send({type:"hangup"}),this._end(new r("CONNECTION_TIMEOUT","Timed out connecting the call."))},this._connectionTimeoutMs))):(this._connectingTone?.stop(),clearTimeout(this._connectionTimer),this._connectionTimer=void 0);for(let t of this._stateHandlers)t(e)}}async start(){if(this._state!=="not-started")throw new Error("start() was already called.");this._setState("starting"),document.body.appendChild(this._remoteAudio);let e=setTimeout(()=>{this._setState("waiting-for-permission")},500);try{this._localStream=await navigator.mediaDevices.getUserMedia({audio:!0,video:!1})}catch(n){let s=new r("MICROPHONE_ACCESS_FAILED","Failed to access microphone.",{cause:n});throw this._end(s),s}finally{clearTimeout(e)}if(this.state==="ended"){this._teardown();return}this._setState("connecting");let t=new Promise((n,s)=>{this._pendingStart={resolve:n,reject:s}});this._sock=new WebSocket(this._sockUrl),this._sock.onopen=()=>{this._send({type:"auth",body:JSON.stringify({webrtc_code:this._webrtcCode,chat_session_id:this._chatSessionId})})},this._sock.onmessage=n=>{this._onMessage(JSON.parse(n.data))},this._sock.onclose=()=>{this._end(new r("CONNECTION_FAILED","Signaling connection closed."))},await t}sendMessage(e){if(this._state==="not-started"||this._state==="ended")throw new Error(`sendMessage() called while the call is ${this._state}.`);let t=JSON.stringify({type:"webrtc-message",payload:e});this._chatReady&&this._chatSock!==void 0?this._chatSock.send(t):this._pendingChatMessages.push(t)}_openChatSocket(){this._chatSock=new WebSocket(this._chatSockUrl),this._chatSock.onopen=()=>{this._chatSock?.send(JSON.stringify({webrtc_code:this._webrtcCode,chat_session_id:this._chatSessionId}))},this._chatSock.onmessage=e=>{let t=JSON.parse(e.data);if(t.type==="ready"&&!this._chatReady){this._chatReady=!0;for(let n of this._pendingChatMessages)this._chatSock?.send(n);this._pendingChatMessages=[]}else if(t.command_type==="send-webrtc-message")for(let n of this._messageHandlers)n(t.payload??{})}}async hangup(){if(this._state==="not-started")throw new Error("hangup() called before start().");this._state!=="ended"&&(this._send({type:"hangup"}),this._end())}_send(e){this._sock!==void 0&&this._sock.readyState===WebSocket.OPEN&&this._sock.send(JSON.stringify(e))}_onMessage(e){switch(e.type){case"auth":if(e.body!=="OK"){this._end(new r("AUTHENTICATION_FAILED",e.reason||"Authentication failed."));return}this._iceServers=e.ice_servers,this._openChatSocket(),this._send({type:"connect",body:{custom_payload:this._customPayload}}),this._connectPeer();break;case"desc":if(!this._peerConnection){this._end(new r("PROTOCOL_ERROR","Received desc before the peer connection was created."));return}this._peerConnection.setRemoteDescription(e.body).catch(t=>{this._end(new r("CONNECTION_FAILED","Failed to set remote description.",{cause:t}))});break;case"candidate":if(!this._peerConnection){this._end(new r("PROTOCOL_ERROR","Received candidate before the peer connection was created."));return}this._peerConnection.addIceCandidate(e.body).catch(t=>{console.warn("Failed to add ICE candidate:",t)});break;case"hangup":this._state==="connected"?this._end():this._end(new r("REMOTE_HANGUP","The remote hung up before the call connected."));break;case"error":this._end(new r("SERVER_ERROR",e.body||"Unknown server error."));break;case"transfer":this._end(new r("PROTOCOL_ERROR","Transfers are not supported."));break;default:console.warn("Unknown signaling message:",e)}}async _connectPeer(){if(this._localStream){this._peerConnection=new RTCPeerConnection({iceServers:this._iceServers??C}),this._peerConnection.onicecandidate=e=>{e.candidate&&this._send({type:"candidate",body:e.candidate})},this._peerConnection.ontrack=e=>{this._remoteStream=new MediaStream([e.track]),this._remoteAudio.srcObject=this._remoteStream;for(let t of this._remoteStreamHandlers)t(this._remoteStream)},this._peerConnection.onconnectionstatechange=()=>{this._peerConnection!==void 0&&(this._peerConnection.connectionState==="connected"?(this._setState("connected"),this._pendingStart!==void 0&&(this._pendingStart.resolve(),this._pendingStart=void 0)):this._peerConnection.connectionState==="failed"&&this._end(new r("CONNECTION_FAILED","Peer connection failed.")))};for(let e of this._localStream.getAudioTracks())this._peerConnection.addTrack(e);try{await this._peerConnection.setLocalDescription()}catch(e){this._end(new r("CONNECTION_FAILED","Failed to create offer.",{cause:e}));return}this.state!=="ended"&&this._send({type:"desc",body:this._peerConnection.localDescription})}}_end(e){this._state!=="ended"&&(this._error=e,this._teardown(),this._setState("ended"),this._pendingStart!==void 0&&(e?this._pendingStart.reject(e):this._pendingStart.resolve(),this._pendingStart=void 0))}_teardown(){this._sock&&(this._sock.onclose=null,this._sock.close(),this._sock=void 0),this._chatSock&&(this._chatSock.close(),this._chatSock=void 0),this._chatReady=!1,this._pendingChatMessages=[],this._peerConnection!==void 0&&(this._peerConnection.close(),this._peerConnection=void 0);for(let e of this._localStream?.getTracks()??[])e.stop();this._localStream=void 0,this._remoteStream=void 0,this._remoteAudio.srcObject=null,this._remoteAudio.remove()}};export{g as Call,r as CallError,h as JingleTone,p as LeavingTone,u as RingbackTone};
2
+ //# sourceMappingURL=guava-webrtc.esm.min.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/webrtc/tones.ts", "../src/webrtc/index.ts"],
4
+ "sourcesContent": ["// Seconds from the start of bar 0 to the given 0-indexed beat.\nfunction beatTime(beat: number, bpm: number): number {\n return beat * (60 / bpm);\n}\n\nexport interface ConnectingTone {\n start(): void;\n stop(): void;\n}\n\n// North American ringback: 440 + 480 Hz, 2s on, 4s off.\nexport class RingbackTone implements ConnectingTone {\n private context: AudioContext | null = null;\n private intervalId: ReturnType<typeof setInterval> | null = null;\n\n private readonly volume = 0.15;\n private readonly onSeconds = 2;\n private readonly periodSeconds = 6;\n // Delay before the first ring, so near-instant connections stay silent.\n private readonly startDelay = 0.3;\n\n start(): void {\n if (this.context) return;\n\n const context = new AudioContext();\n const gain = context.createGain();\n gain.gain.value = 0;\n gain.connect(context.destination);\n\n for (const frequency of [440, 480]) {\n const oscillator = context.createOscillator();\n oscillator.frequency.value = frequency;\n oscillator.connect(gain);\n oscillator.start();\n }\n\n let nextRing = context.currentTime + this.startDelay;\n const ring = () => {\n gain.gain.setValueAtTime(this.volume, nextRing);\n gain.gain.setValueAtTime(0, nextRing + this.onSeconds);\n nextRing += this.periodSeconds;\n };\n ring();\n this.intervalId = setInterval(ring, this.periodSeconds * 1000);\n this.context = context;\n }\n\n stop(): void {\n if (!this.context) return;\n\n if (this.intervalId) {\n clearInterval(this.intervalId);\n this.intervalId = null;\n }\n // Closing the context stops the oscillators.\n void this.context.close();\n this.context = null;\n }\n}\n\nexport class JingleTone implements ConnectingTone {\n private context: AudioContext | null = null;\n private masterGain: GainNode | null = null;\n private intervalId: ReturnType<typeof setInterval> | null = null;\n private running = false;\n private pulseCount = 0;\n // Audio-clock time of the next bar to schedule.\n private nextBarStart = 0;\n\n // Configuration\n private readonly volume = 0.3;\n private readonly bpm = 120;\n private readonly beatsPerBar = 4;\n // Delay before the first note, so near-instant connections stay silent.\n private readonly startDelay = 0.3;\n\n start(): void {\n if (this.running) return;\n\n this.running = true;\n this.pulseCount = 0;\n this.context = new AudioContext();\n this.masterGain = this.context.createGain();\n this.masterGain.gain.value = this.volume;\n this.masterGain.connect(this.context.destination);\n this.nextBarStart = this.context.currentTime + this.startDelay;\n\n // Stay one bar ahead so timer jitter doesn't shift the beat.\n this.playPulse();\n this.playPulse();\n\n const barLength = beatTime(this.beatsPerBar, this.bpm);\n this.intervalId = setInterval(() => {\n this.playPulse();\n }, barLength * 1000);\n }\n\n private noteToFrequency(note: string): number {\n const match = note.match(/^([A-G])(#|b)?(-?\\d+)$/);\n\n if (!match) {\n throw new Error(`Invalid note: ${note}`);\n }\n\n const [, name, accidental, octave] = match;\n\n const semitones: Record<string, number> = {\n C: 0,\n D: 2,\n E: 4,\n F: 5,\n G: 7,\n A: 9,\n B: 11,\n };\n\n const offset = accidental === \"#\" ? 1 : accidental === \"b\" ? -1 : 0;\n const midi = (Number(octave) + 1) * 12 + semitones[name] + offset;\n\n return 440 * Math.pow(2, (midi - 69) / 12);\n }\n\n stop(): void {\n if (!this.running) return;\n\n this.running = false;\n\n if (this.intervalId) {\n clearInterval(this.intervalId);\n this.intervalId = null;\n }\n\n const context = this.context;\n const gain = this.masterGain;\n\n if (!context || !gain) return;\n\n // Smooth fade-out\n const now = context.currentTime;\n gain.gain.setValueAtTime(gain.gain.value, now);\n gain.gain.linearRampToValueAtTime(0, now + 0.15);\n\n setTimeout(() => {\n void context.close();\n }, 200);\n\n this.context = null;\n this.masterGain = null;\n }\n\n private playPulse(): void {\n if (!this.context || !this.masterGain) return;\n\n const bar = this.nextBarStart;\n const beat = (n: number) => bar + beatTime(n, this.bpm);\n const beatLength = beatTime(1, this.bpm);\n\n // Notes on beats 1-3, silence on beat 4.\n if (this.pulseCount % 4 === 0 || this.pulseCount % 4 === 2) {\n this.playNote(\"C5\", beat(0), beatLength);\n this.playNote(\"E5\", beat(0.5), beatLength);\n this.playNote(\"G4\", beat(1), beatLength);\n } else if (this.pulseCount % 4 === 3) {\n this.playNote(\"E5\", beat(0), beatLength);\n this.playNote(\"G5\", beat(0.5), beatLength);\n this.playNote(\"C5\", beat(1), beatLength);\n } else {\n this.playNote(\"E5\", beat(0), beatLength);\n this.playNote(\"G4\", beat(0.5), beatLength);\n this.playNote(\"C5\", beat(1), beatLength);\n }\n this.pulseCount++;\n this.nextBarStart = beat(this.beatsPerBar);\n }\n\n private playNote(note: string, startTime: number, duration: number): void {\n if (!this.context || !this.masterGain) return;\n\n const oscillator = this.context.createOscillator();\n const envelope = this.context.createGain();\n\n oscillator.type = \"sine\";\n oscillator.frequency.value = this.noteToFrequency(note);\n\n envelope.gain.setValueAtTime(0, startTime);\n envelope.gain.linearRampToValueAtTime(0.7, startTime + 0.05);\n envelope.gain.exponentialRampToValueAtTime(0.001, startTime + duration);\n\n oscillator.connect(envelope);\n envelope.connect(this.masterGain);\n\n oscillator.start(startTime);\n oscillator.stop(startTime + duration + 0.01);\n\n oscillator.onended = () => {\n oscillator.disconnect();\n envelope.disconnect();\n };\n }\n}\n\nexport interface Tone {\n play(): void;\n}\n\nexport class LeavingTone implements Tone {\n public play(): void {\n const ctx = new AudioContext();\n\n if (ctx.state === \"suspended\") {\n void ctx.resume();\n }\n\n const now = ctx.currentTime;\n\n // First note: D4\n const first = this.playNote(ctx, {\n frequency: 293.665,\n startTime: now,\n attack: 0.065,\n decay: 0.085,\n volume: 0.2,\n });\n\n // Second note: A3, starts 139ms later\n const second = this.playNote(ctx, {\n frequency: 220.0,\n startTime: now + 0.139,\n attack: 0.018,\n decay: 0.075,\n volume: 0.2,\n });\n\n void Promise.all([first, second]).then(() => ctx.close());\n }\n\n // Resolves once the note has finished playing.\n private playNote(\n ctx: AudioContext,\n {\n frequency,\n startTime,\n attack,\n decay,\n volume,\n }: {\n frequency: number;\n startTime: number;\n attack: number;\n decay: number;\n volume: number;\n },\n ): Promise<void> {\n const oscillator = ctx.createOscillator();\n const gain = ctx.createGain();\n\n oscillator.type = \"sine\";\n oscillator.frequency.setValueAtTime(frequency, startTime);\n\n // Smooth onset\n gain.gain.setValueAtTime(0, startTime);\n gain.gain.linearRampToValueAtTime(volume, startTime + attack);\n\n // Exponential decay\n const peakTime = startTime + attack;\n const endTime = peakTime + decay * 5;\n\n gain.gain.setTargetAtTime(0.00001, peakTime, decay);\n\n oscillator.connect(gain);\n gain.connect(ctx.destination);\n\n oscillator.start(startTime);\n oscillator.stop(endTime);\n\n return new Promise((resolve) => {\n oscillator.onended = () => {\n oscillator.disconnect();\n gain.disconnect();\n resolve();\n };\n });\n }\n}\n", "import { type ConnectingTone, JingleTone, LeavingTone, type Tone } from \"./tones.ts\";\n\nexport { type ConnectingTone, JingleTone, RingbackTone, LeavingTone, type Tone } from \"./tones.ts\";\n\nexport type CallState =\n | \"not-started\" // start() hasn't been called yet.\n | \"starting\" // Starting the call. Do not play a Ringback yet.\n | \"waiting-for-permission\" // We're waiting for the Microphone permission prompt. You may show a reminder UI here.\n | \"connecting\" // The call is now connection to the remote. This is where you can play a ringback or other connecting tone.\n | \"connected\" // The call is now connected and the audio channel is established.\n | \"ended\"; // The call has ended.\n\nexport type CallErrorCode =\n | \"MICROPHONE_ACCESS_FAILED\"\n | \"CONNECTION_FAILED\"\n | \"AUTHENTICATION_FAILED\"\n | \"PROTOCOL_ERROR\" // The server sent an unexpected message.\n | \"SERVER_ERROR\" // The server sent an error message.\n | \"REMOTE_HANGUP\" // The remote hung up before the call connected.\n | \"CONNECTION_TIMEOUT\"; // The call didn't connect within connectionTimeoutMs.\n\nexport class CallError extends Error {\n readonly code: CallErrorCode;\n\n constructor(code: CallErrorCode, message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = \"CallError\";\n this.code = code;\n }\n}\n\n// Used if the server doesn't send ICE servers with the auth reply.\nconst DEFAULT_ICE_SERVERS: RTCIceServer[] = [\n { urls: [\"stun:stun.l.google.com:19302\", \"stun:stun.sipgate.net:10000\"] },\n];\n\nconst SOCKET_PROTOCOLS: Record<string, string> = {\n \"http:\": \"ws:\",\n \"https:\": \"wss:\",\n \"ws:\": \"ws:\",\n \"wss:\": \"wss:\",\n};\n\n// Messages received on the signaling socket. See junkswitch/junkswitch/webrtcsocket.py.\ntype SignalingMessage =\n | {\n type: \"auth\";\n body: \"OK\" | \"FAIL\";\n reason?: string;\n ice_servers?: RTCIceServer[];\n }\n | { type: \"desc\"; body: RTCSessionDescriptionInit }\n | { type: \"candidate\"; body: RTCIceCandidateInit }\n | { type: \"hangup\" }\n | { type: \"error\"; body?: string }\n | { type: \"transfer\" };\n\nexport class Call {\n private _state: CallState = \"not-started\";\n private _error?: CallError;\n private readonly _stateHandlers = new Set<(state: CallState) => void>();\n private readonly _remoteStreamHandlers = new Set<(stream: MediaStream) => void>();\n private readonly _messageHandlers = new Set<(payload: Record<string, unknown>) => void>();\n private readonly _webrtcCode: string;\n private readonly _sockUrl: URL;\n\n private readonly _remoteAudio: HTMLAudioElement;\n private readonly _connectingTone?: ConnectingTone;\n private readonly _leavingTone?: Tone;\n private readonly _connectionTimeoutMs?: number;\n private readonly _customPayload: Record<string, unknown>;\n private _connectionTimer?: ReturnType<typeof setTimeout>;\n private _sock?: WebSocket;\n\n private readonly _chatSockUrl: URL;\n // Links the chat socket to this call's session on the server.\n private readonly _chatSessionId = crypto.randomUUID();\n private _chatSock?: WebSocket;\n private _chatReady = false;\n // Messages sent before the chat socket is ready.\n private _pendingChatMessages: string[] = [];\n\n private _localStream?: MediaStream;\n private _peerConnection?: RTCPeerConnection;\n private _remoteStream?: MediaStream;\n private _iceServers?: RTCIceServer[];\n // Settles the promise returned by start().\n private _pendingStart?: { resolve: () => void; reject: (error: CallError) => void };\n\n constructor({\n webrtcCode,\n baseUrl = \"https://app.goguava.ai/\",\n connectingTone = new JingleTone(),\n leavingTone = new LeavingTone(),\n connectionTimeoutMs = 30_000,\n customPayload = {},\n }: {\n /** Code used to authenticate with the signaling server. */\n webrtcCode: string;\n /** Base URL of the Guava server. Defaults to `https://app.goguava.ai/`. */\n baseUrl?: string;\n /** Played while the call is in the \"connecting\" state. Defaults to {@link JingleTone}. */\n connectingTone?: ConnectingTone | \"disabled\";\n /** Played when the call ends. Defaults to {@link LeavingTone}. */\n leavingTone?: Tone | \"disabled\";\n /** Max time in the \"connecting\" state before the call fails with CONNECTION_TIMEOUT. Defaults to 30 seconds. */\n connectionTimeoutMs?: number | \"disabled\";\n /** A custom payload that is forwarded to the agent at the start of the call. */\n customPayload?: Record<string, unknown>;\n }) {\n this._webrtcCode = webrtcCode;\n this._customPayload = customPayload;\n if (connectingTone !== \"disabled\") {\n this._connectingTone = connectingTone;\n }\n if (leavingTone !== \"disabled\") {\n this._leavingTone = leavingTone;\n }\n if (connectionTimeoutMs !== \"disabled\") {\n this._connectionTimeoutMs = connectionTimeoutMs;\n }\n\n this._sockUrl = new URL(\"/webrtc/\", baseUrl);\n const sockProtocol = SOCKET_PROTOCOLS[this._sockUrl.protocol];\n if (sockProtocol === undefined) {\n throw new Error(`Unsupported baseUrl protocol: ${this._sockUrl.protocol}`);\n }\n this._sockUrl.protocol = sockProtocol;\n this._chatSockUrl = new URL(\"/webrtc-chat/\", this._sockUrl);\n\n this._remoteAudio = document.createElement(\"audio\");\n this._remoteAudio.autoplay = true;\n }\n\n get state(): CallState {\n return this._state;\n }\n\n // Set if the call ended due to a failure.\n get error(): CallError | undefined {\n return this._error;\n }\n\n // Set once the remote audio track arrives, which happens before the call reaches \"connected\".\n get remoteStream(): MediaStream | undefined {\n return this._remoteStream;\n }\n\n // Returns a function that unregisters the handler.\n onStateChange(handler: (state: CallState) => void): () => void {\n this._stateHandlers.add(handler);\n return () => {\n this._stateHandlers.delete(handler);\n };\n }\n\n // Fires whenever the remote stream is replaced, including the first time it arrives.\n // Returns a function that unregisters the handler.\n onRemoteStream(handler: (stream: MediaStream) => void): () => void {\n this._remoteStreamHandlers.add(handler);\n return () => {\n this._remoteStreamHandlers.delete(handler);\n };\n }\n\n /**\n * Registers a handler for messages the agent sends with `call.send_webrtc_message()`.\n * @param handler - Called with each message's payload.\n * @returns A function that unregisters the handler.\n */\n onMessage(handler: (payload: Record<string, unknown>) => void): () => void {\n this._messageHandlers.add(handler);\n return () => {\n this._messageHandlers.delete(handler);\n };\n }\n\n private _setState(state: CallState) {\n if (state === this._state) {\n return;\n }\n\n if (state === \"ended\") {\n this._leavingTone?.play();\n }\n\n this._state = state;\n if (state === \"connecting\") {\n this._connectingTone?.start();\n if (this._connectionTimeoutMs !== undefined) {\n this._connectionTimer = setTimeout(() => {\n this._send({ type: \"hangup\" });\n this._end(new CallError(\"CONNECTION_TIMEOUT\", \"Timed out connecting the call.\"));\n }, this._connectionTimeoutMs);\n }\n } else {\n this._connectingTone?.stop();\n clearTimeout(this._connectionTimer);\n this._connectionTimer = undefined;\n }\n for (const handler of this._stateHandlers) {\n handler(state);\n }\n }\n\n async start() {\n if (this._state !== \"not-started\") {\n throw new Error(`start() was already called.`);\n }\n this._setState(\"starting\");\n\n // Add the audio element.\n document.body.appendChild(this._remoteAudio);\n\n // We start by requesting device permissions first. The idea is that, after permission has been granted,\n // it makes sence to play a ringback, but it doesn't make sense to do so during the permission prompt.\n\n const permissionTimer = setTimeout(() => {\n this._setState(\"waiting-for-permission\");\n }, 500);\n\n try {\n this._localStream = await navigator.mediaDevices.getUserMedia({ audio: true, video: false });\n } catch (error) {\n const callError = new CallError(\"MICROPHONE_ACCESS_FAILED\", \"Failed to access microphone.\", {\n cause: error,\n });\n this._end(callError);\n throw callError;\n } finally {\n clearTimeout(permissionTimer);\n }\n\n // hangup() was called during the permission prompt.\n if (this.state === \"ended\") {\n this._teardown();\n return;\n }\n\n // Now open and authenticate the signaling socket.\n this._setState(\"connecting\"); // UI can start playing rinback tones here.\n const started = new Promise<void>((resolve, reject) => {\n this._pendingStart = { resolve, reject };\n });\n\n this._sock = new WebSocket(this._sockUrl);\n this._sock.onopen = () => {\n this._send({\n type: \"auth\",\n body: JSON.stringify({\n webrtc_code: this._webrtcCode,\n chat_session_id: this._chatSessionId,\n }),\n });\n };\n this._sock.onmessage = (event) => {\n this._onMessage(JSON.parse(event.data) as SignalingMessage);\n };\n this._sock.onclose = () => {\n this._end(new CallError(\"CONNECTION_FAILED\", \"Signaling connection closed.\"));\n };\n\n await started;\n }\n\n /**\n * Sends a message to the agent, delivered to its `on_webrtc_message` handler.\n * Messages sent before the message channel is ready are queued.\n * @param payload - A JSON-serializable object.\n */\n sendMessage(payload: Record<string, unknown>) {\n if (this._state === \"not-started\" || this._state === \"ended\") {\n throw new Error(`sendMessage() called while the call is ${this._state}.`);\n }\n const message = JSON.stringify({ type: \"webrtc-message\", payload });\n if (this._chatReady && this._chatSock !== undefined) {\n this._chatSock.send(message);\n } else {\n this._pendingChatMessages.push(message);\n }\n }\n\n private _openChatSocket() {\n this._chatSock = new WebSocket(this._chatSockUrl);\n this._chatSock.onopen = () => {\n this._chatSock?.send(\n JSON.stringify({ webrtc_code: this._webrtcCode, chat_session_id: this._chatSessionId }),\n );\n };\n this._chatSock.onmessage = (event) => {\n const message = JSON.parse(event.data) as {\n type?: string;\n command_type?: string;\n payload?: Record<string, unknown>;\n };\n // The server sends \"ready\" once the call session is found.\n if (message.type === \"ready\" && !this._chatReady) {\n this._chatReady = true;\n for (const pending of this._pendingChatMessages) {\n this._chatSock?.send(pending);\n }\n this._pendingChatMessages = [];\n } else if (message.command_type === \"send-webrtc-message\") {\n for (const handler of this._messageHandlers) {\n handler(message.payload ?? {});\n }\n }\n };\n }\n\n async hangup() {\n if (this._state === \"not-started\") {\n throw new Error(`hangup() called before start().`);\n }\n if (this._state === \"ended\") {\n return;\n }\n this._send({ type: \"hangup\" });\n this._end();\n }\n\n private _send(message: { type: string; body?: unknown }) {\n if (this._sock !== undefined && this._sock.readyState === WebSocket.OPEN) {\n this._sock.send(JSON.stringify(message));\n }\n }\n\n private _onMessage(message: SignalingMessage) {\n switch (message.type) {\n case \"auth\":\n if (message.body !== \"OK\") {\n this._end(\n new CallError(\"AUTHENTICATION_FAILED\", message.reason || \"Authentication failed.\"),\n );\n return;\n }\n this._iceServers = message.ice_servers;\n this._openChatSocket();\n this._send({ type: \"connect\", body: { custom_payload: this._customPayload } });\n void this._connectPeer();\n break;\n case \"desc\":\n if (!this._peerConnection) {\n this._end(\n new CallError(\n \"PROTOCOL_ERROR\",\n \"Received desc before the peer connection was created.\",\n ),\n );\n return;\n }\n this._peerConnection.setRemoteDescription(message.body).catch((error) => {\n this._end(\n new CallError(\"CONNECTION_FAILED\", \"Failed to set remote description.\", {\n cause: error,\n }),\n );\n });\n break;\n case \"candidate\":\n if (!this._peerConnection) {\n this._end(\n new CallError(\n \"PROTOCOL_ERROR\",\n \"Received candidate before the peer connection was created.\",\n ),\n );\n return;\n }\n this._peerConnection.addIceCandidate(message.body).catch((error) => {\n console.warn(\"Failed to add ICE candidate:\", error);\n });\n break;\n case \"hangup\":\n if (this._state === \"connected\") {\n this._end();\n } else {\n this._end(\n new CallError(\"REMOTE_HANGUP\", \"The remote hung up before the call connected.\"),\n );\n }\n break;\n case \"error\":\n this._end(new CallError(\"SERVER_ERROR\", message.body || \"Unknown server error.\"));\n break;\n case \"transfer\":\n this._end(new CallError(\"PROTOCOL_ERROR\", \"Transfers are not supported.\"));\n break;\n default:\n console.warn(\"Unknown signaling message:\", message);\n }\n }\n\n private async _connectPeer() {\n if (!this._localStream) {\n return;\n }\n this._peerConnection = new RTCPeerConnection({\n iceServers: this._iceServers ?? DEFAULT_ICE_SERVERS,\n });\n this._peerConnection.onicecandidate = (event) => {\n if (event.candidate) {\n this._send({ type: \"candidate\", body: event.candidate });\n }\n };\n this._peerConnection.ontrack = (event) => {\n this._remoteStream = new MediaStream([event.track]);\n this._remoteAudio.srcObject = this._remoteStream;\n for (const handler of this._remoteStreamHandlers) {\n handler(this._remoteStream);\n }\n };\n this._peerConnection.onconnectionstatechange = () => {\n if (this._peerConnection === undefined) {\n return;\n }\n // \"disconnected\" is often transient, so wait for \"failed\" before ending the call.\n if (this._peerConnection.connectionState === \"connected\") {\n this._setState(\"connected\");\n if (this._pendingStart !== undefined) {\n this._pendingStart.resolve();\n this._pendingStart = undefined;\n }\n } else if (this._peerConnection.connectionState === \"failed\") {\n this._end(new CallError(\"CONNECTION_FAILED\", \"Peer connection failed.\"));\n }\n };\n for (const track of this._localStream.getAudioTracks()) {\n this._peerConnection.addTrack(track);\n }\n\n try {\n await this._peerConnection.setLocalDescription();\n } catch (error) {\n this._end(new CallError(\"CONNECTION_FAILED\", \"Failed to create offer.\", { cause: error }));\n return;\n }\n\n // The call may have ended while creating the offer.\n if (this.state === \"ended\") {\n return;\n }\n this._send({ type: \"desc\", body: this._peerConnection.localDescription });\n }\n\n private _end(error?: CallError) {\n if (this._state === \"ended\") {\n return;\n }\n this._error = error;\n this._teardown();\n this._setState(\"ended\");\n\n // If start() is still pending, it rejects on failure and resolves on hangup().\n if (this._pendingStart !== undefined) {\n if (error) {\n this._pendingStart.reject(error);\n } else {\n this._pendingStart.resolve();\n }\n this._pendingStart = undefined;\n }\n }\n\n private _teardown() {\n // Close the signaling socket.\n if (this._sock) {\n // Don't fire close handlers for a socket we closed ourselves.\n this._sock.onclose = null;\n this._sock.close();\n this._sock = undefined;\n }\n\n // Close the chat socket.\n if (this._chatSock) {\n this._chatSock.close();\n this._chatSock = undefined;\n }\n this._chatReady = false;\n this._pendingChatMessages = [];\n\n // Close the peer connection.\n if (this._peerConnection !== undefined) {\n this._peerConnection.close();\n this._peerConnection = undefined;\n }\n for (const track of this._localStream?.getTracks() ?? []) {\n track.stop();\n }\n this._localStream = undefined;\n this._remoteStream = undefined;\n\n // Remove the audio element.\n this._remoteAudio.srcObject = null;\n this._remoteAudio.remove();\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["beatTime", "beat", "bpm", "RingbackTone", "__publicField", "context", "gain", "frequency", "oscillator", "nextRing", "ring", "JingleTone", "barLength", "note", "match", "name", "accidental", "octave", "semitones", "offset", "midi", "now", "bar", "n", "beatLength", "startTime", "duration", "envelope", "LeavingTone", "ctx", "first", "second", "attack", "decay", "volume", "peakTime", "endTime", "resolve", "CallError", "code", "message", "options", "__publicField", "DEFAULT_ICE_SERVERS", "SOCKET_PROTOCOLS", "Call", "webrtcCode", "baseUrl", "connectingTone", "JingleTone", "leavingTone", "LeavingTone", "connectionTimeoutMs", "customPayload", "sockProtocol", "handler", "state", "permissionTimer", "error", "callError", "started", "resolve", "reject", "event", "payload", "pending", "track"]
7
+ }
@@ -0,0 +1,2 @@
1
+ var Guava=(()=>{var _=Object.defineProperty;var S=Object.getOwnPropertyDescriptor;var C=Object.getOwnPropertyNames;var T=Object.prototype.hasOwnProperty;var w=(o,e,t)=>e in o?_(o,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):o[e]=t;var b=(o,e)=>{for(var t in e)_(o,t,{get:e[t],enumerable:!0})},R=(o,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of C(e))!T.call(o,s)&&s!==t&&_(o,s,{get:()=>e[s],enumerable:!(n=S(e,s))||n.enumerable});return o};var k=o=>R(_({},"__esModule",{value:!0}),o);var i=(o,e,t)=>w(o,typeof e!="symbol"?e+"":e,t);var I={};b(I,{Call:()=>g,CallError:()=>a,JingleTone:()=>h,LeavingTone:()=>p,RingbackTone:()=>u});function m(o,e){return o*(60/e)}var u=class{constructor(){i(this,"context",null);i(this,"intervalId",null);i(this,"volume",.15);i(this,"onSeconds",2);i(this,"periodSeconds",6);i(this,"startDelay",.3)}start(){if(this.context)return;let e=new AudioContext,t=e.createGain();t.gain.value=0,t.connect(e.destination);for(let r of[440,480]){let d=e.createOscillator();d.frequency.value=r,d.connect(t),d.start()}let n=e.currentTime+this.startDelay,s=()=>{t.gain.setValueAtTime(this.volume,n),t.gain.setValueAtTime(0,n+this.onSeconds),n+=this.periodSeconds};s(),this.intervalId=setInterval(s,this.periodSeconds*1e3),this.context=e}stop(){this.context&&(this.intervalId&&(clearInterval(this.intervalId),this.intervalId=null),this.context.close(),this.context=null)}},h=class{constructor(){i(this,"context",null);i(this,"masterGain",null);i(this,"intervalId",null);i(this,"running",!1);i(this,"pulseCount",0);i(this,"nextBarStart",0);i(this,"volume",.3);i(this,"bpm",120);i(this,"beatsPerBar",4);i(this,"startDelay",.3)}start(){if(this.running)return;this.running=!0,this.pulseCount=0,this.context=new AudioContext,this.masterGain=this.context.createGain(),this.masterGain.gain.value=this.volume,this.masterGain.connect(this.context.destination),this.nextBarStart=this.context.currentTime+this.startDelay,this.playPulse(),this.playPulse();let e=m(this.beatsPerBar,this.bpm);this.intervalId=setInterval(()=>{this.playPulse()},e*1e3)}noteToFrequency(e){let t=e.match(/^([A-G])(#|b)?(-?\d+)$/);if(!t)throw new Error(`Invalid note: ${e}`);let[,n,s,r]=t,d={C:0,D:2,E:4,F:5,G:7,A:9,B:11},c=s==="#"?1:s==="b"?-1:0,l=(Number(r)+1)*12+d[n]+c;return 440*Math.pow(2,(l-69)/12)}stop(){if(!this.running)return;this.running=!1,this.intervalId&&(clearInterval(this.intervalId),this.intervalId=null);let e=this.context,t=this.masterGain;if(!e||!t)return;let n=e.currentTime;t.gain.setValueAtTime(t.gain.value,n),t.gain.linearRampToValueAtTime(0,n+.15),setTimeout(()=>{e.close()},200),this.context=null,this.masterGain=null}playPulse(){if(!this.context||!this.masterGain)return;let e=this.nextBarStart,t=s=>e+m(s,this.bpm),n=m(1,this.bpm);this.pulseCount%4===0||this.pulseCount%4===2?(this.playNote("C5",t(0),n),this.playNote("E5",t(.5),n),this.playNote("G4",t(1),n)):this.pulseCount%4===3?(this.playNote("E5",t(0),n),this.playNote("G5",t(.5),n),this.playNote("C5",t(1),n)):(this.playNote("E5",t(0),n),this.playNote("G4",t(.5),n),this.playNote("C5",t(1),n)),this.pulseCount++,this.nextBarStart=t(this.beatsPerBar)}playNote(e,t,n){if(!this.context||!this.masterGain)return;let s=this.context.createOscillator(),r=this.context.createGain();s.type="sine",s.frequency.value=this.noteToFrequency(e),r.gain.setValueAtTime(0,t),r.gain.linearRampToValueAtTime(.7,t+.05),r.gain.exponentialRampToValueAtTime(.001,t+n),s.connect(r),r.connect(this.masterGain),s.start(t),s.stop(t+n+.01),s.onended=()=>{s.disconnect(),r.disconnect()}}},p=class{play(){let e=new AudioContext;e.state==="suspended"&&e.resume();let t=e.currentTime,n=this.playNote(e,{frequency:293.665,startTime:t,attack:.065,decay:.085,volume:.2}),s=this.playNote(e,{frequency:220,startTime:t+.139,attack:.018,decay:.075,volume:.2});Promise.all([n,s]).then(()=>e.close())}playNote(e,{frequency:t,startTime:n,attack:s,decay:r,volume:d}){let c=e.createOscillator(),l=e.createGain();c.type="sine",c.frequency.setValueAtTime(t,n),l.gain.setValueAtTime(0,n),l.gain.linearRampToValueAtTime(d,n+s);let v=n+s,y=v+r*5;return l.gain.setTargetAtTime(1e-5,v,r),c.connect(l),l.connect(e.destination),c.start(n),c.stop(y),new Promise(f=>{c.onended=()=>{c.disconnect(),l.disconnect(),f()}})}};var a=class extends Error{constructor(t,n,s){super(n,s);i(this,"code");this.name="CallError",this.code=t}},E=[{urls:["stun:stun.l.google.com:19302","stun:stun.sipgate.net:10000"]}],O={"http:":"ws:","https:":"wss:","ws:":"ws:","wss:":"wss:"},g=class{constructor({webrtcCode:e,baseUrl:t="https://app.goguava.ai/",connectingTone:n=new h,leavingTone:s=new p,connectionTimeoutMs:r=3e4,customPayload:d={}}){i(this,"_state","not-started");i(this,"_error");i(this,"_stateHandlers",new Set);i(this,"_remoteStreamHandlers",new Set);i(this,"_messageHandlers",new Set);i(this,"_webrtcCode");i(this,"_sockUrl");i(this,"_remoteAudio");i(this,"_connectingTone");i(this,"_leavingTone");i(this,"_connectionTimeoutMs");i(this,"_customPayload");i(this,"_connectionTimer");i(this,"_sock");i(this,"_chatSockUrl");i(this,"_chatSessionId",crypto.randomUUID());i(this,"_chatSock");i(this,"_chatReady",!1);i(this,"_pendingChatMessages",[]);i(this,"_localStream");i(this,"_peerConnection");i(this,"_remoteStream");i(this,"_iceServers");i(this,"_pendingStart");this._webrtcCode=e,this._customPayload=d,n!=="disabled"&&(this._connectingTone=n),s!=="disabled"&&(this._leavingTone=s),r!=="disabled"&&(this._connectionTimeoutMs=r),this._sockUrl=new URL("/webrtc/",t);let c=O[this._sockUrl.protocol];if(c===void 0)throw new Error(`Unsupported baseUrl protocol: ${this._sockUrl.protocol}`);this._sockUrl.protocol=c,this._chatSockUrl=new URL("/webrtc-chat/",this._sockUrl),this._remoteAudio=document.createElement("audio"),this._remoteAudio.autoplay=!0}get state(){return this._state}get error(){return this._error}get remoteStream(){return this._remoteStream}onStateChange(e){return this._stateHandlers.add(e),()=>{this._stateHandlers.delete(e)}}onRemoteStream(e){return this._remoteStreamHandlers.add(e),()=>{this._remoteStreamHandlers.delete(e)}}onMessage(e){return this._messageHandlers.add(e),()=>{this._messageHandlers.delete(e)}}_setState(e){if(e!==this._state){e==="ended"&&this._leavingTone?.play(),this._state=e,e==="connecting"?(this._connectingTone?.start(),this._connectionTimeoutMs!==void 0&&(this._connectionTimer=setTimeout(()=>{this._send({type:"hangup"}),this._end(new a("CONNECTION_TIMEOUT","Timed out connecting the call."))},this._connectionTimeoutMs))):(this._connectingTone?.stop(),clearTimeout(this._connectionTimer),this._connectionTimer=void 0);for(let t of this._stateHandlers)t(e)}}async start(){if(this._state!=="not-started")throw new Error("start() was already called.");this._setState("starting"),document.body.appendChild(this._remoteAudio);let e=setTimeout(()=>{this._setState("waiting-for-permission")},500);try{this._localStream=await navigator.mediaDevices.getUserMedia({audio:!0,video:!1})}catch(n){let s=new a("MICROPHONE_ACCESS_FAILED","Failed to access microphone.",{cause:n});throw this._end(s),s}finally{clearTimeout(e)}if(this.state==="ended"){this._teardown();return}this._setState("connecting");let t=new Promise((n,s)=>{this._pendingStart={resolve:n,reject:s}});this._sock=new WebSocket(this._sockUrl),this._sock.onopen=()=>{this._send({type:"auth",body:JSON.stringify({webrtc_code:this._webrtcCode,chat_session_id:this._chatSessionId})})},this._sock.onmessage=n=>{this._onMessage(JSON.parse(n.data))},this._sock.onclose=()=>{this._end(new a("CONNECTION_FAILED","Signaling connection closed."))},await t}sendMessage(e){if(this._state==="not-started"||this._state==="ended")throw new Error(`sendMessage() called while the call is ${this._state}.`);let t=JSON.stringify({type:"webrtc-message",payload:e});this._chatReady&&this._chatSock!==void 0?this._chatSock.send(t):this._pendingChatMessages.push(t)}_openChatSocket(){this._chatSock=new WebSocket(this._chatSockUrl),this._chatSock.onopen=()=>{this._chatSock?.send(JSON.stringify({webrtc_code:this._webrtcCode,chat_session_id:this._chatSessionId}))},this._chatSock.onmessage=e=>{let t=JSON.parse(e.data);if(t.type==="ready"&&!this._chatReady){this._chatReady=!0;for(let n of this._pendingChatMessages)this._chatSock?.send(n);this._pendingChatMessages=[]}else if(t.command_type==="send-webrtc-message")for(let n of this._messageHandlers)n(t.payload??{})}}async hangup(){if(this._state==="not-started")throw new Error("hangup() called before start().");this._state!=="ended"&&(this._send({type:"hangup"}),this._end())}_send(e){this._sock!==void 0&&this._sock.readyState===WebSocket.OPEN&&this._sock.send(JSON.stringify(e))}_onMessage(e){switch(e.type){case"auth":if(e.body!=="OK"){this._end(new a("AUTHENTICATION_FAILED",e.reason||"Authentication failed."));return}this._iceServers=e.ice_servers,this._openChatSocket(),this._send({type:"connect",body:{custom_payload:this._customPayload}}),this._connectPeer();break;case"desc":if(!this._peerConnection){this._end(new a("PROTOCOL_ERROR","Received desc before the peer connection was created."));return}this._peerConnection.setRemoteDescription(e.body).catch(t=>{this._end(new a("CONNECTION_FAILED","Failed to set remote description.",{cause:t}))});break;case"candidate":if(!this._peerConnection){this._end(new a("PROTOCOL_ERROR","Received candidate before the peer connection was created."));return}this._peerConnection.addIceCandidate(e.body).catch(t=>{console.warn("Failed to add ICE candidate:",t)});break;case"hangup":this._state==="connected"?this._end():this._end(new a("REMOTE_HANGUP","The remote hung up before the call connected."));break;case"error":this._end(new a("SERVER_ERROR",e.body||"Unknown server error."));break;case"transfer":this._end(new a("PROTOCOL_ERROR","Transfers are not supported."));break;default:console.warn("Unknown signaling message:",e)}}async _connectPeer(){if(this._localStream){this._peerConnection=new RTCPeerConnection({iceServers:this._iceServers??E}),this._peerConnection.onicecandidate=e=>{e.candidate&&this._send({type:"candidate",body:e.candidate})},this._peerConnection.ontrack=e=>{this._remoteStream=new MediaStream([e.track]),this._remoteAudio.srcObject=this._remoteStream;for(let t of this._remoteStreamHandlers)t(this._remoteStream)},this._peerConnection.onconnectionstatechange=()=>{this._peerConnection!==void 0&&(this._peerConnection.connectionState==="connected"?(this._setState("connected"),this._pendingStart!==void 0&&(this._pendingStart.resolve(),this._pendingStart=void 0)):this._peerConnection.connectionState==="failed"&&this._end(new a("CONNECTION_FAILED","Peer connection failed.")))};for(let e of this._localStream.getAudioTracks())this._peerConnection.addTrack(e);try{await this._peerConnection.setLocalDescription()}catch(e){this._end(new a("CONNECTION_FAILED","Failed to create offer.",{cause:e}));return}this.state!=="ended"&&this._send({type:"desc",body:this._peerConnection.localDescription})}}_end(e){this._state!=="ended"&&(this._error=e,this._teardown(),this._setState("ended"),this._pendingStart!==void 0&&(e?this._pendingStart.reject(e):this._pendingStart.resolve(),this._pendingStart=void 0))}_teardown(){this._sock&&(this._sock.onclose=null,this._sock.close(),this._sock=void 0),this._chatSock&&(this._chatSock.close(),this._chatSock=void 0),this._chatReady=!1,this._pendingChatMessages=[],this._peerConnection!==void 0&&(this._peerConnection.close(),this._peerConnection=void 0);for(let e of this._localStream?.getTracks()??[])e.stop();this._localStream=void 0,this._remoteStream=void 0,this._remoteAudio.srcObject=null,this._remoteAudio.remove()}};return k(I);})();
2
+ //# sourceMappingURL=guava-webrtc.min.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/webrtc/index.ts", "../src/webrtc/tones.ts"],
4
+ "sourcesContent": ["import { type ConnectingTone, JingleTone, LeavingTone, type Tone } from \"./tones.ts\";\n\nexport { type ConnectingTone, JingleTone, RingbackTone, LeavingTone, type Tone } from \"./tones.ts\";\n\nexport type CallState =\n | \"not-started\" // start() hasn't been called yet.\n | \"starting\" // Starting the call. Do not play a Ringback yet.\n | \"waiting-for-permission\" // We're waiting for the Microphone permission prompt. You may show a reminder UI here.\n | \"connecting\" // The call is now connection to the remote. This is where you can play a ringback or other connecting tone.\n | \"connected\" // The call is now connected and the audio channel is established.\n | \"ended\"; // The call has ended.\n\nexport type CallErrorCode =\n | \"MICROPHONE_ACCESS_FAILED\"\n | \"CONNECTION_FAILED\"\n | \"AUTHENTICATION_FAILED\"\n | \"PROTOCOL_ERROR\" // The server sent an unexpected message.\n | \"SERVER_ERROR\" // The server sent an error message.\n | \"REMOTE_HANGUP\" // The remote hung up before the call connected.\n | \"CONNECTION_TIMEOUT\"; // The call didn't connect within connectionTimeoutMs.\n\nexport class CallError extends Error {\n readonly code: CallErrorCode;\n\n constructor(code: CallErrorCode, message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = \"CallError\";\n this.code = code;\n }\n}\n\n// Used if the server doesn't send ICE servers with the auth reply.\nconst DEFAULT_ICE_SERVERS: RTCIceServer[] = [\n { urls: [\"stun:stun.l.google.com:19302\", \"stun:stun.sipgate.net:10000\"] },\n];\n\nconst SOCKET_PROTOCOLS: Record<string, string> = {\n \"http:\": \"ws:\",\n \"https:\": \"wss:\",\n \"ws:\": \"ws:\",\n \"wss:\": \"wss:\",\n};\n\n// Messages received on the signaling socket. See junkswitch/junkswitch/webrtcsocket.py.\ntype SignalingMessage =\n | {\n type: \"auth\";\n body: \"OK\" | \"FAIL\";\n reason?: string;\n ice_servers?: RTCIceServer[];\n }\n | { type: \"desc\"; body: RTCSessionDescriptionInit }\n | { type: \"candidate\"; body: RTCIceCandidateInit }\n | { type: \"hangup\" }\n | { type: \"error\"; body?: string }\n | { type: \"transfer\" };\n\nexport class Call {\n private _state: CallState = \"not-started\";\n private _error?: CallError;\n private readonly _stateHandlers = new Set<(state: CallState) => void>();\n private readonly _remoteStreamHandlers = new Set<(stream: MediaStream) => void>();\n private readonly _messageHandlers = new Set<(payload: Record<string, unknown>) => void>();\n private readonly _webrtcCode: string;\n private readonly _sockUrl: URL;\n\n private readonly _remoteAudio: HTMLAudioElement;\n private readonly _connectingTone?: ConnectingTone;\n private readonly _leavingTone?: Tone;\n private readonly _connectionTimeoutMs?: number;\n private readonly _customPayload: Record<string, unknown>;\n private _connectionTimer?: ReturnType<typeof setTimeout>;\n private _sock?: WebSocket;\n\n private readonly _chatSockUrl: URL;\n // Links the chat socket to this call's session on the server.\n private readonly _chatSessionId = crypto.randomUUID();\n private _chatSock?: WebSocket;\n private _chatReady = false;\n // Messages sent before the chat socket is ready.\n private _pendingChatMessages: string[] = [];\n\n private _localStream?: MediaStream;\n private _peerConnection?: RTCPeerConnection;\n private _remoteStream?: MediaStream;\n private _iceServers?: RTCIceServer[];\n // Settles the promise returned by start().\n private _pendingStart?: { resolve: () => void; reject: (error: CallError) => void };\n\n constructor({\n webrtcCode,\n baseUrl = \"https://app.goguava.ai/\",\n connectingTone = new JingleTone(),\n leavingTone = new LeavingTone(),\n connectionTimeoutMs = 30_000,\n customPayload = {},\n }: {\n /** Code used to authenticate with the signaling server. */\n webrtcCode: string;\n /** Base URL of the Guava server. Defaults to `https://app.goguava.ai/`. */\n baseUrl?: string;\n /** Played while the call is in the \"connecting\" state. Defaults to {@link JingleTone}. */\n connectingTone?: ConnectingTone | \"disabled\";\n /** Played when the call ends. Defaults to {@link LeavingTone}. */\n leavingTone?: Tone | \"disabled\";\n /** Max time in the \"connecting\" state before the call fails with CONNECTION_TIMEOUT. Defaults to 30 seconds. */\n connectionTimeoutMs?: number | \"disabled\";\n /** A custom payload that is forwarded to the agent at the start of the call. */\n customPayload?: Record<string, unknown>;\n }) {\n this._webrtcCode = webrtcCode;\n this._customPayload = customPayload;\n if (connectingTone !== \"disabled\") {\n this._connectingTone = connectingTone;\n }\n if (leavingTone !== \"disabled\") {\n this._leavingTone = leavingTone;\n }\n if (connectionTimeoutMs !== \"disabled\") {\n this._connectionTimeoutMs = connectionTimeoutMs;\n }\n\n this._sockUrl = new URL(\"/webrtc/\", baseUrl);\n const sockProtocol = SOCKET_PROTOCOLS[this._sockUrl.protocol];\n if (sockProtocol === undefined) {\n throw new Error(`Unsupported baseUrl protocol: ${this._sockUrl.protocol}`);\n }\n this._sockUrl.protocol = sockProtocol;\n this._chatSockUrl = new URL(\"/webrtc-chat/\", this._sockUrl);\n\n this._remoteAudio = document.createElement(\"audio\");\n this._remoteAudio.autoplay = true;\n }\n\n get state(): CallState {\n return this._state;\n }\n\n // Set if the call ended due to a failure.\n get error(): CallError | undefined {\n return this._error;\n }\n\n // Set once the remote audio track arrives, which happens before the call reaches \"connected\".\n get remoteStream(): MediaStream | undefined {\n return this._remoteStream;\n }\n\n // Returns a function that unregisters the handler.\n onStateChange(handler: (state: CallState) => void): () => void {\n this._stateHandlers.add(handler);\n return () => {\n this._stateHandlers.delete(handler);\n };\n }\n\n // Fires whenever the remote stream is replaced, including the first time it arrives.\n // Returns a function that unregisters the handler.\n onRemoteStream(handler: (stream: MediaStream) => void): () => void {\n this._remoteStreamHandlers.add(handler);\n return () => {\n this._remoteStreamHandlers.delete(handler);\n };\n }\n\n /**\n * Registers a handler for messages the agent sends with `call.send_webrtc_message()`.\n * @param handler - Called with each message's payload.\n * @returns A function that unregisters the handler.\n */\n onMessage(handler: (payload: Record<string, unknown>) => void): () => void {\n this._messageHandlers.add(handler);\n return () => {\n this._messageHandlers.delete(handler);\n };\n }\n\n private _setState(state: CallState) {\n if (state === this._state) {\n return;\n }\n\n if (state === \"ended\") {\n this._leavingTone?.play();\n }\n\n this._state = state;\n if (state === \"connecting\") {\n this._connectingTone?.start();\n if (this._connectionTimeoutMs !== undefined) {\n this._connectionTimer = setTimeout(() => {\n this._send({ type: \"hangup\" });\n this._end(new CallError(\"CONNECTION_TIMEOUT\", \"Timed out connecting the call.\"));\n }, this._connectionTimeoutMs);\n }\n } else {\n this._connectingTone?.stop();\n clearTimeout(this._connectionTimer);\n this._connectionTimer = undefined;\n }\n for (const handler of this._stateHandlers) {\n handler(state);\n }\n }\n\n async start() {\n if (this._state !== \"not-started\") {\n throw new Error(`start() was already called.`);\n }\n this._setState(\"starting\");\n\n // Add the audio element.\n document.body.appendChild(this._remoteAudio);\n\n // We start by requesting device permissions first. The idea is that, after permission has been granted,\n // it makes sence to play a ringback, but it doesn't make sense to do so during the permission prompt.\n\n const permissionTimer = setTimeout(() => {\n this._setState(\"waiting-for-permission\");\n }, 500);\n\n try {\n this._localStream = await navigator.mediaDevices.getUserMedia({ audio: true, video: false });\n } catch (error) {\n const callError = new CallError(\"MICROPHONE_ACCESS_FAILED\", \"Failed to access microphone.\", {\n cause: error,\n });\n this._end(callError);\n throw callError;\n } finally {\n clearTimeout(permissionTimer);\n }\n\n // hangup() was called during the permission prompt.\n if (this.state === \"ended\") {\n this._teardown();\n return;\n }\n\n // Now open and authenticate the signaling socket.\n this._setState(\"connecting\"); // UI can start playing rinback tones here.\n const started = new Promise<void>((resolve, reject) => {\n this._pendingStart = { resolve, reject };\n });\n\n this._sock = new WebSocket(this._sockUrl);\n this._sock.onopen = () => {\n this._send({\n type: \"auth\",\n body: JSON.stringify({\n webrtc_code: this._webrtcCode,\n chat_session_id: this._chatSessionId,\n }),\n });\n };\n this._sock.onmessage = (event) => {\n this._onMessage(JSON.parse(event.data) as SignalingMessage);\n };\n this._sock.onclose = () => {\n this._end(new CallError(\"CONNECTION_FAILED\", \"Signaling connection closed.\"));\n };\n\n await started;\n }\n\n /**\n * Sends a message to the agent, delivered to its `on_webrtc_message` handler.\n * Messages sent before the message channel is ready are queued.\n * @param payload - A JSON-serializable object.\n */\n sendMessage(payload: Record<string, unknown>) {\n if (this._state === \"not-started\" || this._state === \"ended\") {\n throw new Error(`sendMessage() called while the call is ${this._state}.`);\n }\n const message = JSON.stringify({ type: \"webrtc-message\", payload });\n if (this._chatReady && this._chatSock !== undefined) {\n this._chatSock.send(message);\n } else {\n this._pendingChatMessages.push(message);\n }\n }\n\n private _openChatSocket() {\n this._chatSock = new WebSocket(this._chatSockUrl);\n this._chatSock.onopen = () => {\n this._chatSock?.send(\n JSON.stringify({ webrtc_code: this._webrtcCode, chat_session_id: this._chatSessionId }),\n );\n };\n this._chatSock.onmessage = (event) => {\n const message = JSON.parse(event.data) as {\n type?: string;\n command_type?: string;\n payload?: Record<string, unknown>;\n };\n // The server sends \"ready\" once the call session is found.\n if (message.type === \"ready\" && !this._chatReady) {\n this._chatReady = true;\n for (const pending of this._pendingChatMessages) {\n this._chatSock?.send(pending);\n }\n this._pendingChatMessages = [];\n } else if (message.command_type === \"send-webrtc-message\") {\n for (const handler of this._messageHandlers) {\n handler(message.payload ?? {});\n }\n }\n };\n }\n\n async hangup() {\n if (this._state === \"not-started\") {\n throw new Error(`hangup() called before start().`);\n }\n if (this._state === \"ended\") {\n return;\n }\n this._send({ type: \"hangup\" });\n this._end();\n }\n\n private _send(message: { type: string; body?: unknown }) {\n if (this._sock !== undefined && this._sock.readyState === WebSocket.OPEN) {\n this._sock.send(JSON.stringify(message));\n }\n }\n\n private _onMessage(message: SignalingMessage) {\n switch (message.type) {\n case \"auth\":\n if (message.body !== \"OK\") {\n this._end(\n new CallError(\"AUTHENTICATION_FAILED\", message.reason || \"Authentication failed.\"),\n );\n return;\n }\n this._iceServers = message.ice_servers;\n this._openChatSocket();\n this._send({ type: \"connect\", body: { custom_payload: this._customPayload } });\n void this._connectPeer();\n break;\n case \"desc\":\n if (!this._peerConnection) {\n this._end(\n new CallError(\n \"PROTOCOL_ERROR\",\n \"Received desc before the peer connection was created.\",\n ),\n );\n return;\n }\n this._peerConnection.setRemoteDescription(message.body).catch((error) => {\n this._end(\n new CallError(\"CONNECTION_FAILED\", \"Failed to set remote description.\", {\n cause: error,\n }),\n );\n });\n break;\n case \"candidate\":\n if (!this._peerConnection) {\n this._end(\n new CallError(\n \"PROTOCOL_ERROR\",\n \"Received candidate before the peer connection was created.\",\n ),\n );\n return;\n }\n this._peerConnection.addIceCandidate(message.body).catch((error) => {\n console.warn(\"Failed to add ICE candidate:\", error);\n });\n break;\n case \"hangup\":\n if (this._state === \"connected\") {\n this._end();\n } else {\n this._end(\n new CallError(\"REMOTE_HANGUP\", \"The remote hung up before the call connected.\"),\n );\n }\n break;\n case \"error\":\n this._end(new CallError(\"SERVER_ERROR\", message.body || \"Unknown server error.\"));\n break;\n case \"transfer\":\n this._end(new CallError(\"PROTOCOL_ERROR\", \"Transfers are not supported.\"));\n break;\n default:\n console.warn(\"Unknown signaling message:\", message);\n }\n }\n\n private async _connectPeer() {\n if (!this._localStream) {\n return;\n }\n this._peerConnection = new RTCPeerConnection({\n iceServers: this._iceServers ?? DEFAULT_ICE_SERVERS,\n });\n this._peerConnection.onicecandidate = (event) => {\n if (event.candidate) {\n this._send({ type: \"candidate\", body: event.candidate });\n }\n };\n this._peerConnection.ontrack = (event) => {\n this._remoteStream = new MediaStream([event.track]);\n this._remoteAudio.srcObject = this._remoteStream;\n for (const handler of this._remoteStreamHandlers) {\n handler(this._remoteStream);\n }\n };\n this._peerConnection.onconnectionstatechange = () => {\n if (this._peerConnection === undefined) {\n return;\n }\n // \"disconnected\" is often transient, so wait for \"failed\" before ending the call.\n if (this._peerConnection.connectionState === \"connected\") {\n this._setState(\"connected\");\n if (this._pendingStart !== undefined) {\n this._pendingStart.resolve();\n this._pendingStart = undefined;\n }\n } else if (this._peerConnection.connectionState === \"failed\") {\n this._end(new CallError(\"CONNECTION_FAILED\", \"Peer connection failed.\"));\n }\n };\n for (const track of this._localStream.getAudioTracks()) {\n this._peerConnection.addTrack(track);\n }\n\n try {\n await this._peerConnection.setLocalDescription();\n } catch (error) {\n this._end(new CallError(\"CONNECTION_FAILED\", \"Failed to create offer.\", { cause: error }));\n return;\n }\n\n // The call may have ended while creating the offer.\n if (this.state === \"ended\") {\n return;\n }\n this._send({ type: \"desc\", body: this._peerConnection.localDescription });\n }\n\n private _end(error?: CallError) {\n if (this._state === \"ended\") {\n return;\n }\n this._error = error;\n this._teardown();\n this._setState(\"ended\");\n\n // If start() is still pending, it rejects on failure and resolves on hangup().\n if (this._pendingStart !== undefined) {\n if (error) {\n this._pendingStart.reject(error);\n } else {\n this._pendingStart.resolve();\n }\n this._pendingStart = undefined;\n }\n }\n\n private _teardown() {\n // Close the signaling socket.\n if (this._sock) {\n // Don't fire close handlers for a socket we closed ourselves.\n this._sock.onclose = null;\n this._sock.close();\n this._sock = undefined;\n }\n\n // Close the chat socket.\n if (this._chatSock) {\n this._chatSock.close();\n this._chatSock = undefined;\n }\n this._chatReady = false;\n this._pendingChatMessages = [];\n\n // Close the peer connection.\n if (this._peerConnection !== undefined) {\n this._peerConnection.close();\n this._peerConnection = undefined;\n }\n for (const track of this._localStream?.getTracks() ?? []) {\n track.stop();\n }\n this._localStream = undefined;\n this._remoteStream = undefined;\n\n // Remove the audio element.\n this._remoteAudio.srcObject = null;\n this._remoteAudio.remove();\n }\n}\n", "// Seconds from the start of bar 0 to the given 0-indexed beat.\nfunction beatTime(beat: number, bpm: number): number {\n return beat * (60 / bpm);\n}\n\nexport interface ConnectingTone {\n start(): void;\n stop(): void;\n}\n\n// North American ringback: 440 + 480 Hz, 2s on, 4s off.\nexport class RingbackTone implements ConnectingTone {\n private context: AudioContext | null = null;\n private intervalId: ReturnType<typeof setInterval> | null = null;\n\n private readonly volume = 0.15;\n private readonly onSeconds = 2;\n private readonly periodSeconds = 6;\n // Delay before the first ring, so near-instant connections stay silent.\n private readonly startDelay = 0.3;\n\n start(): void {\n if (this.context) return;\n\n const context = new AudioContext();\n const gain = context.createGain();\n gain.gain.value = 0;\n gain.connect(context.destination);\n\n for (const frequency of [440, 480]) {\n const oscillator = context.createOscillator();\n oscillator.frequency.value = frequency;\n oscillator.connect(gain);\n oscillator.start();\n }\n\n let nextRing = context.currentTime + this.startDelay;\n const ring = () => {\n gain.gain.setValueAtTime(this.volume, nextRing);\n gain.gain.setValueAtTime(0, nextRing + this.onSeconds);\n nextRing += this.periodSeconds;\n };\n ring();\n this.intervalId = setInterval(ring, this.periodSeconds * 1000);\n this.context = context;\n }\n\n stop(): void {\n if (!this.context) return;\n\n if (this.intervalId) {\n clearInterval(this.intervalId);\n this.intervalId = null;\n }\n // Closing the context stops the oscillators.\n void this.context.close();\n this.context = null;\n }\n}\n\nexport class JingleTone implements ConnectingTone {\n private context: AudioContext | null = null;\n private masterGain: GainNode | null = null;\n private intervalId: ReturnType<typeof setInterval> | null = null;\n private running = false;\n private pulseCount = 0;\n // Audio-clock time of the next bar to schedule.\n private nextBarStart = 0;\n\n // Configuration\n private readonly volume = 0.3;\n private readonly bpm = 120;\n private readonly beatsPerBar = 4;\n // Delay before the first note, so near-instant connections stay silent.\n private readonly startDelay = 0.3;\n\n start(): void {\n if (this.running) return;\n\n this.running = true;\n this.pulseCount = 0;\n this.context = new AudioContext();\n this.masterGain = this.context.createGain();\n this.masterGain.gain.value = this.volume;\n this.masterGain.connect(this.context.destination);\n this.nextBarStart = this.context.currentTime + this.startDelay;\n\n // Stay one bar ahead so timer jitter doesn't shift the beat.\n this.playPulse();\n this.playPulse();\n\n const barLength = beatTime(this.beatsPerBar, this.bpm);\n this.intervalId = setInterval(() => {\n this.playPulse();\n }, barLength * 1000);\n }\n\n private noteToFrequency(note: string): number {\n const match = note.match(/^([A-G])(#|b)?(-?\\d+)$/);\n\n if (!match) {\n throw new Error(`Invalid note: ${note}`);\n }\n\n const [, name, accidental, octave] = match;\n\n const semitones: Record<string, number> = {\n C: 0,\n D: 2,\n E: 4,\n F: 5,\n G: 7,\n A: 9,\n B: 11,\n };\n\n const offset = accidental === \"#\" ? 1 : accidental === \"b\" ? -1 : 0;\n const midi = (Number(octave) + 1) * 12 + semitones[name] + offset;\n\n return 440 * Math.pow(2, (midi - 69) / 12);\n }\n\n stop(): void {\n if (!this.running) return;\n\n this.running = false;\n\n if (this.intervalId) {\n clearInterval(this.intervalId);\n this.intervalId = null;\n }\n\n const context = this.context;\n const gain = this.masterGain;\n\n if (!context || !gain) return;\n\n // Smooth fade-out\n const now = context.currentTime;\n gain.gain.setValueAtTime(gain.gain.value, now);\n gain.gain.linearRampToValueAtTime(0, now + 0.15);\n\n setTimeout(() => {\n void context.close();\n }, 200);\n\n this.context = null;\n this.masterGain = null;\n }\n\n private playPulse(): void {\n if (!this.context || !this.masterGain) return;\n\n const bar = this.nextBarStart;\n const beat = (n: number) => bar + beatTime(n, this.bpm);\n const beatLength = beatTime(1, this.bpm);\n\n // Notes on beats 1-3, silence on beat 4.\n if (this.pulseCount % 4 === 0 || this.pulseCount % 4 === 2) {\n this.playNote(\"C5\", beat(0), beatLength);\n this.playNote(\"E5\", beat(0.5), beatLength);\n this.playNote(\"G4\", beat(1), beatLength);\n } else if (this.pulseCount % 4 === 3) {\n this.playNote(\"E5\", beat(0), beatLength);\n this.playNote(\"G5\", beat(0.5), beatLength);\n this.playNote(\"C5\", beat(1), beatLength);\n } else {\n this.playNote(\"E5\", beat(0), beatLength);\n this.playNote(\"G4\", beat(0.5), beatLength);\n this.playNote(\"C5\", beat(1), beatLength);\n }\n this.pulseCount++;\n this.nextBarStart = beat(this.beatsPerBar);\n }\n\n private playNote(note: string, startTime: number, duration: number): void {\n if (!this.context || !this.masterGain) return;\n\n const oscillator = this.context.createOscillator();\n const envelope = this.context.createGain();\n\n oscillator.type = \"sine\";\n oscillator.frequency.value = this.noteToFrequency(note);\n\n envelope.gain.setValueAtTime(0, startTime);\n envelope.gain.linearRampToValueAtTime(0.7, startTime + 0.05);\n envelope.gain.exponentialRampToValueAtTime(0.001, startTime + duration);\n\n oscillator.connect(envelope);\n envelope.connect(this.masterGain);\n\n oscillator.start(startTime);\n oscillator.stop(startTime + duration + 0.01);\n\n oscillator.onended = () => {\n oscillator.disconnect();\n envelope.disconnect();\n };\n }\n}\n\nexport interface Tone {\n play(): void;\n}\n\nexport class LeavingTone implements Tone {\n public play(): void {\n const ctx = new AudioContext();\n\n if (ctx.state === \"suspended\") {\n void ctx.resume();\n }\n\n const now = ctx.currentTime;\n\n // First note: D4\n const first = this.playNote(ctx, {\n frequency: 293.665,\n startTime: now,\n attack: 0.065,\n decay: 0.085,\n volume: 0.2,\n });\n\n // Second note: A3, starts 139ms later\n const second = this.playNote(ctx, {\n frequency: 220.0,\n startTime: now + 0.139,\n attack: 0.018,\n decay: 0.075,\n volume: 0.2,\n });\n\n void Promise.all([first, second]).then(() => ctx.close());\n }\n\n // Resolves once the note has finished playing.\n private playNote(\n ctx: AudioContext,\n {\n frequency,\n startTime,\n attack,\n decay,\n volume,\n }: {\n frequency: number;\n startTime: number;\n attack: number;\n decay: number;\n volume: number;\n },\n ): Promise<void> {\n const oscillator = ctx.createOscillator();\n const gain = ctx.createGain();\n\n oscillator.type = \"sine\";\n oscillator.frequency.setValueAtTime(frequency, startTime);\n\n // Smooth onset\n gain.gain.setValueAtTime(0, startTime);\n gain.gain.linearRampToValueAtTime(volume, startTime + attack);\n\n // Exponential decay\n const peakTime = startTime + attack;\n const endTime = peakTime + decay * 5;\n\n gain.gain.setTargetAtTime(0.00001, peakTime, decay);\n\n oscillator.connect(gain);\n gain.connect(ctx.destination);\n\n oscillator.start(startTime);\n oscillator.stop(endTime);\n\n return new Promise((resolve) => {\n oscillator.onended = () => {\n oscillator.disconnect();\n gain.disconnect();\n resolve();\n };\n });\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["index_exports", "__export", "Call", "CallError", "JingleTone", "LeavingTone", "RingbackTone", "beatTime", "beat", "bpm", "RingbackTone", "__publicField", "context", "gain", "frequency", "oscillator", "nextRing", "ring", "JingleTone", "barLength", "note", "match", "name", "accidental", "octave", "semitones", "offset", "midi", "now", "bar", "n", "beatLength", "startTime", "duration", "envelope", "LeavingTone", "ctx", "first", "second", "attack", "decay", "volume", "peakTime", "endTime", "resolve", "CallError", "code", "message", "options", "__publicField", "DEFAULT_ICE_SERVERS", "SOCKET_PROTOCOLS", "Call", "webrtcCode", "baseUrl", "connectingTone", "JingleTone", "leavingTone", "LeavingTone", "connectionTimeoutMs", "customPayload", "sockProtocol", "handler", "state", "permissionTimer", "error", "callError", "started", "resolve", "reject", "event", "payload", "pending", "track"]
7
+ }
@@ -4,6 +4,7 @@ import { type DTMFDigit } from "./events.ts";
4
4
  import type * as z from "zod";
5
5
  import type { FieldItem, SayItem } from "./action-item.ts";
6
6
  import type { CallInfo } from "./socket/call-info.ts";
7
+ import type { SipUri } from "./sip.ts";
7
8
  export type TaskObjective = {
8
9
  objective: string;
9
10
  } | {
@@ -74,21 +75,21 @@ export declare class Call {
74
75
  * This method does not interfere with turn-taking — use this when
75
76
  * you want the agent to naturally transfer the call.
76
77
  *
77
- * @param destination - The phone number or SIP address to transfer the call to.
78
+ * @param destination - The phone number, SIP address, or SipUri to transfer the call to.
78
79
  * @param instructions - Optional guidance for how the agent should handle the transfer.
79
80
  */
80
- transfer(destination: string, instructions?: string): Promise<void>;
81
+ transfer(destination: string | SipUri, instructions?: string): Promise<void>;
81
82
  /**
82
83
  * Transfer the call immediately.
83
84
  *
84
85
  * Unlike transfer(), this does not respect turn-taking. The agent immediately
85
86
  * initiates the transfer, saying the script (if provided).
86
87
  *
87
- * @param destination - The phone number or SIP address to transfer the call to.
88
+ * @param destination - The phone number, SIP address, or SipUri to transfer the call to.
88
89
  * @param finalScript - Optional message for the agent to deliver immediately
89
90
  * before transferring. Defaults to no message.
90
91
  */
91
- immediateTransfer(destination: string, finalScript?: string): Promise<void>;
92
+ immediateTransfer(destination: string | SipUri, finalScript?: string): Promise<void>;
92
93
  addInfo(label: string, info: unknown): Promise<void>;
93
94
  retryTask(reason: string): Promise<void>;
94
95
  readScript(script: string): Promise<void>;
package/dist/src/call.js CHANGED
@@ -213,13 +213,13 @@ let Call = (() => {
213
213
  * This method does not interfere with turn-taking — use this when
214
214
  * you want the agent to naturally transfer the call.
215
215
  *
216
- * @param destination - The phone number or SIP address to transfer the call to.
216
+ * @param destination - The phone number, SIP address, or SipUri to transfer the call to.
217
217
  * @param instructions - Optional guidance for how the agent should handle the transfer.
218
218
  */
219
219
  async transfer(destination, instructions) {
220
220
  await this.sendCommand(commands_ts_1.TransferCommand, {
221
221
  command_type: "transfer-call",
222
- to_number: destination,
222
+ to_number: destination.toString(),
223
223
  transfer_message: instructions ?? "Notify the caller that you will be transferring them, and then transfer.",
224
224
  soft_transfer: true,
225
225
  });
@@ -230,14 +230,14 @@ let Call = (() => {
230
230
  * Unlike transfer(), this does not respect turn-taking. The agent immediately
231
231
  * initiates the transfer, saying the script (if provided).
232
232
  *
233
- * @param destination - The phone number or SIP address to transfer the call to.
233
+ * @param destination - The phone number, SIP address, or SipUri to transfer the call to.
234
234
  * @param finalScript - Optional message for the agent to deliver immediately
235
235
  * before transferring. Defaults to no message.
236
236
  */
237
237
  async immediateTransfer(destination, finalScript) {
238
238
  await this.sendCommand(commands_ts_1.TransferCommand, {
239
239
  command_type: "transfer-call",
240
- to_number: destination,
240
+ to_number: destination.toString(),
241
241
  transfer_message: finalScript ?? "",
242
242
  soft_transfer: false,
243
243
  });
@@ -1 +1 @@
1
- {"version":3,"file":"call.js","sourceRoot":"","sources":["../../src/call.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"call.js","sourceRoot":"","sources":["../../src/call.ts"],"names":[],"mappings":"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"}
@@ -7,6 +7,7 @@ export { Say, Field } from "./action-item.ts";
7
7
  export { Logger, getConsoleLogger, getDefaultLogger } from "./logging.ts";
8
8
  export { Agent, CallInfo } from "./agent.ts";
9
9
  export { SIPCallInfo } from "./socket/call-info.ts";
10
+ export { SipUri } from "./sip.ts";
10
11
  export { Call, DEFAULT_REACH_PERSON_OUTCOMES } from "./call.ts";
11
12
  export type { ReachPersonOutcome } from "./call.ts";
12
13
  export type { SpeedPreset, Language } from "./commands.ts";
package/dist/src/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.MockCall = exports.TestSession = exports.DEFAULT_REACH_PERSON_OUTCOMES = exports.Call = exports.SIPCallInfo = exports.Agent = exports.getDefaultLogger = exports.getConsoleLogger = exports.Field = exports.Say = exports.Campaign = exports.Runner = exports.Client = void 0;
3
+ exports.MockCall = exports.TestSession = exports.DEFAULT_REACH_PERSON_OUTCOMES = exports.Call = exports.SipUri = exports.SIPCallInfo = exports.Agent = exports.getDefaultLogger = exports.getConsoleLogger = exports.Field = exports.Say = exports.Campaign = exports.Runner = exports.Client = void 0;
4
4
  var client_ts_1 = require("./client.js");
5
5
  Object.defineProperty(exports, "Client", { enumerable: true, get: function () { return client_ts_1.Client; } });
6
6
  var runner_ts_1 = require("./runner.js");
@@ -17,6 +17,8 @@ var agent_ts_1 = require("./agent.js");
17
17
  Object.defineProperty(exports, "Agent", { enumerable: true, get: function () { return agent_ts_1.Agent; } });
18
18
  var call_info_ts_1 = require("./socket/call-info.js");
19
19
  Object.defineProperty(exports, "SIPCallInfo", { enumerable: true, get: function () { return call_info_ts_1.SIPCallInfo; } });
20
+ var sip_ts_1 = require("./sip.js");
21
+ Object.defineProperty(exports, "SipUri", { enumerable: true, get: function () { return sip_ts_1.SipUri; } });
20
22
  var call_ts_1 = require("./call.js");
21
23
  Object.defineProperty(exports, "Call", { enumerable: true, get: function () { return call_ts_1.Call; } });
22
24
  Object.defineProperty(exports, "DEFAULT_REACH_PERSON_OUTCOMES", { enumerable: true, get: function () { return call_ts_1.DEFAULT_REACH_PERSON_OUTCOMES; } });
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;AAAA,yCAA6D;AAApD,mGAAA,MAAM,OAAA;AACf,yCAAqC;AAA5B,mGAAA,MAAM,OAAA;AAEf,+CAA0C;AAAjC,wGAAA,QAAQ,OAAA;AAQjB,mDAA8C;AAArC,qGAAA,GAAG,OAAA;AAAE,uGAAA,KAAK,OAAA;AACnB,2CAA0E;AAAzD,8GAAA,gBAAgB,OAAA;AAAE,8GAAA,gBAAgB,OAAA;AACnD,uCAA6C;AAApC,iGAAA,KAAK,OAAA;AACd,sDAAoD;AAA3C,2GAAA,WAAW,OAAA;AACpB,qCAAgE;AAAvD,+FAAA,IAAI,OAAA;AAAE,wHAAA,6BAA6B,OAAA;AAW5C,mDAAmD;AAA1C,yGAAA,WAAW,OAAA;AACpB,+CAA8C;AAArC,oGAAA,QAAQ,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;AAAA,yCAA6D;AAApD,mGAAA,MAAM,OAAA;AACf,yCAAqC;AAA5B,mGAAA,MAAM,OAAA;AAEf,+CAA0C;AAAjC,wGAAA,QAAQ,OAAA;AAQjB,mDAA8C;AAArC,qGAAA,GAAG,OAAA;AAAE,uGAAA,KAAK,OAAA;AACnB,2CAA0E;AAAzD,8GAAA,gBAAgB,OAAA;AAAE,8GAAA,gBAAgB,OAAA;AACnD,uCAA6C;AAApC,iGAAA,KAAK,OAAA;AACd,sDAAoD;AAA3C,2GAAA,WAAW,OAAA;AACpB,mCAAkC;AAAzB,gGAAA,MAAM,OAAA;AACf,qCAAgE;AAAvD,+FAAA,IAAI,OAAA;AAAE,wHAAA,6BAA6B,OAAA;AAW5C,mDAAmD;AAA1C,yGAAA,WAAW,OAAA;AACpB,+CAA8C;AAArC,oGAAA,QAAQ,OAAA"}
@@ -0,0 +1,15 @@
1
+ export declare class SipUri {
2
+ host: string;
3
+ user?: string;
4
+ /** A `null` value renders as a valueless param, e.g. `;lr`. */
5
+ uriParams: Record<string, string | null>;
6
+ /** A `null` value renders as a valueless header, e.g. `?X-Foo=`. */
7
+ headers: Record<string, string | null>;
8
+ constructor(args: {
9
+ host: string;
10
+ user?: string;
11
+ uriParams?: Record<string, string | null>;
12
+ headers?: Record<string, string | null>;
13
+ });
14
+ toString(): string;
15
+ }
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SipUri = void 0;
4
+ // Characters allowed unescaped in each component beyond RFC 3261's `unreserved`,
5
+ // which encodeURIComponent already leaves alone. See RFC 3261 section 25.1.
6
+ const USER_SAFE = "&=+$,;?/";
7
+ const PARAM_SAFE = "[]/:&+$";
8
+ const HEADER_SAFE = "[]/?:+$";
9
+ function sipEscape(value, safe) {
10
+ return encodeURIComponent(value).replace(/%[0-9A-F]{2}/g, (escaped) => {
11
+ // Not decodeURIComponent, which throws on single bytes of multibyte UTF-8 sequences.
12
+ const char = String.fromCharCode(Number.parseInt(escaped.slice(1), 16));
13
+ return safe.includes(char) ? char : escaped;
14
+ });
15
+ }
16
+ class SipUri {
17
+ host;
18
+ user;
19
+ /** A `null` value renders as a valueless param, e.g. `;lr`. */
20
+ uriParams;
21
+ /** A `null` value renders as a valueless header, e.g. `?X-Foo=`. */
22
+ headers;
23
+ constructor(args) {
24
+ this.host = args.host;
25
+ this.user = args.user;
26
+ this.uriParams = args.uriParams ?? {};
27
+ this.headers = args.headers ?? {};
28
+ }
29
+ toString() {
30
+ let url = "sip:";
31
+ if (this.user !== undefined) {
32
+ url += `${sipEscape(this.user, USER_SAFE)}@`;
33
+ }
34
+ url += this.host;
35
+ for (const [name, value] of Object.entries(this.uriParams)) {
36
+ url += `;${sipEscape(name, PARAM_SAFE)}`;
37
+ if (value !== null) {
38
+ url += `=${sipEscape(value, PARAM_SAFE)}`;
39
+ }
40
+ }
41
+ // Headers always need an "=", so a null value renders as "name=".
42
+ const headers = Object.entries(this.headers);
43
+ if (headers.length > 0) {
44
+ url += `?${headers
45
+ .map(([name, value]) => `${sipEscape(name, HEADER_SAFE)}=${sipEscape(value === null ? "" : String(value), HEADER_SAFE)}`)
46
+ .join("&")}`;
47
+ }
48
+ return url;
49
+ }
50
+ }
51
+ exports.SipUri = SipUri;
52
+ //# sourceMappingURL=sip.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sip.js","sourceRoot":"","sources":["../../src/sip.ts"],"names":[],"mappings":";;;AAAA,iFAAiF;AACjF,4EAA4E;AAC5E,MAAM,SAAS,GAAG,UAAU,CAAC;AAC7B,MAAM,UAAU,GAAG,SAAS,CAAC;AAC7B,MAAM,WAAW,GAAG,SAAS,CAAC;AAE9B,SAAS,SAAS,CAAC,KAAa,EAAE,IAAY;IAC5C,OAAO,kBAAkB,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,eAAe,EAAE,CAAC,OAAO,EAAE,EAAE;QACpE,qFAAqF;QACrF,MAAM,IAAI,GAAG,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;QACxE,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC;IAC9C,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAa,MAAM;IACjB,IAAI,CAAS;IACb,IAAI,CAAU;IACd,+DAA+D;IAC/D,SAAS,CAAgC;IACzC,oEAAoE;IACpE,OAAO,CAAgC;IAEvC,YAAY,IAKX;QACC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACtB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACtB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,EAAE,CAAC;QACtC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC;IACpC,CAAC;IAED,QAAQ;QACN,IAAI,GAAG,GAAG,MAAM,CAAC;QACjB,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC5B,GAAG,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,GAAG,CAAC;QAC/C,CAAC;QACD,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC;QAEjB,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;YAC3D,GAAG,IAAI,IAAI,SAAS,CAAC,IAAI,EAAE,UAAU,CAAC,EAAE,CAAC;YACzC,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;gBACnB,GAAG,IAAI,IAAI,SAAS,CAAC,KAAK,EAAE,UAAU,CAAC,EAAE,CAAC;YAC5C,CAAC;QACH,CAAC;QAED,kEAAkE;QAClE,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC7C,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,GAAG,IAAI,IAAI,OAAO;iBACf,GAAG,CACF,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,CAChB,GAAG,SAAS,CAAC,IAAI,EAAE,WAAW,CAAC,IAAI,SAAS,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,WAAW,CAAC,EAAE,CACnG;iBACA,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACjB,CAAC;QAED,OAAO,GAAG,CAAC;IACb,CAAC;CACF;AA/CD,wBA+CC"}
@@ -9,6 +9,7 @@ export type PSTNCallInfo = z.infer<typeof PSTNCallInfo>;
9
9
  export declare const WebRTCCallInfo: z.ZodObject<{
10
10
  call_type: z.ZodLiteral<"webrtc">;
11
11
  webrtc_code: z.ZodString;
12
+ custom_payload: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
12
13
  }, z.core.$strip>;
13
14
  export type WebRTCCallInfo = z.infer<typeof WebRTCCallInfo>;
14
15
  export declare class SIPCallInfo {
@@ -28,6 +29,7 @@ export declare const CallInfo: z.ZodDiscriminatedUnion<[z.ZodObject<{
28
29
  }, z.core.$strip>, z.ZodObject<{
29
30
  call_type: z.ZodLiteral<"webrtc">;
30
31
  webrtc_code: z.ZodString;
32
+ custom_payload: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
31
33
  }, z.core.$strip>, z.ZodPipe<z.ZodObject<{
32
34
  call_type: z.ZodLiteral<"sip">;
33
35
  from_aor: z.ZodString;
@@ -44,6 +44,7 @@ exports.PSTNCallInfo = z.object({
44
44
  exports.WebRTCCallInfo = z.object({
45
45
  call_type: z.literal("webrtc"),
46
46
  webrtc_code: z.string(),
47
+ custom_payload: z.record(z.string(), z.unknown()).default({}),
47
48
  });
48
49
  const SIPCallInfoSchema = z
49
50
  .object({
@@ -1 +1 @@
1
- {"version":3,"file":"call-info.js","sourceRoot":"","sources":["../../../src/socket/call-info.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"call-info.js","sourceRoot":"","sources":["../../../src/socket/call-info.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,uCAAyB;AAEZ,QAAA,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC;IACnC,SAAS,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;IAC5B,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAClC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CACjC,CAAC,CAAC;AAGU,QAAA,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC;IACrC,SAAS,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC;IAC9B,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;IACvB,cAAc,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;CAC9D,CAAC,CAAC;AAGH,MAAM,iBAAiB,GAAG,CAAC;KACxB,MAAM,CAAC;IACN,SAAS,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC;IAC3B,QAAQ,EAAE,CAAC;SACR,MAAM,EAAE;SACR,QAAQ,CACP,2JAA2J,CAC5J;IACH,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC/B,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;CAC1D,CAAC;KACD,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,WAAW,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;AAExF,MAAa,WAAW;IAIX;IACA;IACA;IALF,SAAS,GAAG,KAAc,CAAC;IAEpC,YACW,QAAgB,EAChB,QAAiB,EACjB,cAAsC,EAAE;QAFxC,aAAQ,GAAR,QAAQ,CAAQ;QAChB,aAAQ,GAAR,QAAQ,CAAS;QACjB,gBAAW,GAAX,WAAW,CAA6B;IAChD,CAAC;IAEJ,oBAAoB;IACpB,IAAI,OAAO;QACT,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QAEnC,4EAA4E;QAC5E,IAAI,CAAC,GAAG,CAAC,CAAC;QACV,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC1B,CAAC,GAAG,CAAC,CAAC;YACN,OAAO,CAAC,GAAG,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;gBAC5C,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACjC,CAAC;YACD,CAAC,IAAI,CAAC,CAAC;QACT,CAAC;QAED,6EAA6E;QAC7E,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACpC,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACnC,IAAI,KAAK,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,KAAK,GAAG,IAAI,CAAC,EAAE,CAAC;YAClD,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YACtC,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;gBACf,OAAO,KAAK,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;YAC5C,CAAC;QACH,CAAC;QAED,OAAO,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IACvC,CAAC;CACF;AAnCD,kCAmCC;AAEY,QAAA,QAAQ,GAAG,CAAC,CAAC,kBAAkB,CAAC,WAAW,EAAE;IACxD,oBAAY;IACZ,sBAAc;IACd,iBAAiB;CAClB,CAAC,CAAC"}
@@ -21,6 +21,7 @@ export declare const AssignCall: z.ZodObject<{
21
21
  }, z.core.$strip>, z.ZodObject<{
22
22
  call_type: z.ZodLiteral<"webrtc">;
23
23
  webrtc_code: z.ZodString;
24
+ custom_payload: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
24
25
  }, z.core.$strip>, z.ZodPipe<z.ZodObject<{
25
26
  call_type: z.ZodLiteral<"sip">;
26
27
  from_aor: z.ZodString;
@@ -51,6 +52,7 @@ export declare const ServerMessage: z.ZodDiscriminatedUnion<[z.ZodObject<{
51
52
  }, z.core.$strip>, z.ZodObject<{
52
53
  call_type: z.ZodLiteral<"webrtc">;
53
54
  webrtc_code: z.ZodString;
55
+ custom_payload: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
54
56
  }, z.core.$strip>, z.ZodPipe<z.ZodObject<{
55
57
  call_type: z.ZodLiteral<"sip">;
56
58
  from_aor: z.ZodString;
@@ -1 +1 @@
1
- export declare const SDK_VERSION = "0.37.0";
1
+ export declare const SDK_VERSION = "0.39.0";
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SDK_VERSION = void 0;
4
- exports.SDK_VERSION = "0.37.0";
4
+ exports.SDK_VERSION = "0.39.0";
5
5
  //# sourceMappingURL=version.js.map