@11labs/client 0.1.4 → 0.2.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 +90 -14
- package/dist/BaseConversation.d.ts +76 -0
- package/dist/TextConversation.d.ts +4 -0
- package/dist/VoiceConversation.d.ts +27 -0
- package/dist/dist/BaseConversation.d.ts +80 -0
- package/dist/dist/TextConversation.d.ts +4 -0
- package/dist/dist/VoiceConversation.d.ts +27 -0
- package/dist/dist/index.d.ts +12 -0
- package/dist/dist/lib.cjs +2 -0
- package/dist/dist/lib.cjs.map +1 -0
- package/dist/dist/lib.modern.js +2 -0
- package/dist/dist/lib.modern.js.map +1 -0
- package/dist/dist/lib.module.js +2 -0
- package/dist/dist/lib.module.js.map +1 -0
- package/dist/dist/lib.umd.js +2 -0
- package/dist/dist/lib.umd.js.map +1 -0
- package/dist/dist/utils/BaseConnection.d.ts +99 -0
- package/dist/dist/utils/ConnectionFactory.d.ts +2 -0
- package/dist/dist/utils/WebRTCConnection.d.ts +23 -0
- package/dist/dist/utils/WebSocketConnection.d.ts +13 -0
- package/dist/dist/utils/applyDelay.d.ts +2 -0
- package/dist/dist/utils/audio.d.ts +2 -0
- package/dist/dist/utils/audioConcatProcessor.d.ts +1 -0
- package/dist/dist/utils/compatibility.d.ts +2 -0
- package/dist/dist/utils/createWorkletModuleLoader.d.ts +1 -0
- package/dist/dist/utils/events.d.ts +125 -0
- package/dist/dist/utils/input.d.ts +14 -0
- package/dist/dist/utils/output.d.ts +10 -0
- package/dist/dist/utils/overrides.d.ts +4 -0
- package/dist/dist/utils/postOverallFeedback.d.ts +1 -0
- package/dist/dist/utils/rawAudioProcessor.d.ts +1 -0
- package/dist/dist/version.d.ts +1 -0
- package/dist/index.d.ts +9 -79
- package/dist/lib.cjs +1 -1
- package/dist/lib.cjs.map +1 -1
- package/dist/lib.modern.js +1 -1
- package/dist/lib.modern.js.map +1 -1
- package/dist/lib.module.js +1 -1
- package/dist/lib.module.js.map +1 -1
- package/dist/lib.umd.js +1 -1
- package/dist/lib.umd.js.map +1 -1
- package/dist/utils/BaseConnection.d.ts +94 -0
- package/dist/utils/ConnectionFactory.d.ts +2 -0
- package/dist/utils/WebRTCConnection.d.ts +19 -0
- package/dist/utils/WebSocketConnection.d.ts +12 -0
- package/dist/utils/applyDelay.d.ts +2 -0
- package/dist/utils/events.d.ts +13 -3
- package/dist/utils/input.d.ts +1 -1
- package/dist/utils/output.d.ts +1 -1
- package/dist/utils/overrides.d.ts +4 -0
- package/dist/utils/postOverallFeedback.d.ts +1 -0
- package/dist/version.d.ts +1 -0
- package/package.json +17 -12
- package/LICENSE +0 -21
- package/dist/utils/connection.d.ts +0 -65
package/dist/index.d.ts
CHANGED
@@ -1,82 +1,12 @@
|
|
1
|
-
import {
|
2
|
-
|
3
|
-
import { OnDisconnectCallback, SessionConfig } from "./utils/connection";
|
4
|
-
import { ClientToolCallEvent } from "./utils/events";
|
1
|
+
import { BaseConversation, type PartialOptions } from "./BaseConversation";
|
2
|
+
export type { Mode, Role, Options, PartialOptions, ClientToolsConfig, Callbacks, Status, } from "./BaseConversation";
|
5
3
|
export type { InputConfig } from "./utils/input";
|
6
4
|
export type { IncomingSocketEvent } from "./utils/events";
|
7
|
-
export type { SessionConfig, DisconnectionDetails, Language, } from "./utils/
|
8
|
-
export
|
9
|
-
export
|
10
|
-
export
|
11
|
-
export
|
12
|
-
export
|
13
|
-
|
14
|
-
};
|
15
|
-
export type Callbacks = {
|
16
|
-
onConnect: (props: {
|
17
|
-
conversationId: string;
|
18
|
-
}) => void;
|
19
|
-
onDebug: (props: any) => void;
|
20
|
-
onDisconnect: OnDisconnectCallback;
|
21
|
-
onError: (message: string, context?: any) => void;
|
22
|
-
onMessage: (props: {
|
23
|
-
message: string;
|
24
|
-
source: Role;
|
25
|
-
}) => void;
|
26
|
-
onAudio: (base64Audio: string) => void;
|
27
|
-
onModeChange: (prop: {
|
28
|
-
mode: Mode;
|
29
|
-
}) => void;
|
30
|
-
onStatusChange: (prop: {
|
31
|
-
status: Status;
|
32
|
-
}) => void;
|
33
|
-
onCanSendFeedbackChange: (prop: {
|
34
|
-
canSendFeedback: boolean;
|
35
|
-
}) => void;
|
36
|
-
onUnhandledClientToolCall?: (params: ClientToolCallEvent["client_tool_call"]) => void;
|
37
|
-
};
|
38
|
-
export declare class Conversation {
|
39
|
-
private readonly options;
|
40
|
-
private readonly connection;
|
41
|
-
readonly input: Input;
|
42
|
-
readonly output: Output;
|
43
|
-
wakeLock: WakeLockSentinel | null;
|
44
|
-
static startSession(options: SessionConfig & Partial<Callbacks> & Partial<ClientToolsConfig> & Partial<InputConfig>): Promise<Conversation>;
|
45
|
-
private lastInterruptTimestamp;
|
46
|
-
private mode;
|
47
|
-
private status;
|
48
|
-
private inputFrequencyData?;
|
49
|
-
private outputFrequencyData?;
|
50
|
-
private volume;
|
51
|
-
private currentEventId;
|
52
|
-
private lastFeedbackEventId;
|
53
|
-
private canSendFeedback;
|
54
|
-
private constructor();
|
55
|
-
endSession: () => Promise<void>;
|
56
|
-
private endSessionWithDetails;
|
57
|
-
private updateMode;
|
58
|
-
private updateStatus;
|
59
|
-
private updateCanSendFeedback;
|
60
|
-
private onMessage;
|
61
|
-
private onInputWorkletMessage;
|
62
|
-
private onOutputWorkletMessage;
|
63
|
-
private addAudioBase64Chunk;
|
64
|
-
private fadeOutAudio;
|
65
|
-
private onError;
|
66
|
-
private calculateVolume;
|
67
|
-
getId: () => string;
|
68
|
-
isOpen: () => boolean;
|
69
|
-
setVolume: ({ volume }: {
|
70
|
-
volume: number;
|
71
|
-
}) => void;
|
72
|
-
setMicMuted: (isMuted: boolean) => void;
|
73
|
-
getInputByteFrequencyData: () => Uint8Array;
|
74
|
-
getOutputByteFrequencyData: () => Uint8Array;
|
75
|
-
getInputVolume: () => number;
|
76
|
-
getOutputVolume: () => number;
|
77
|
-
sendFeedback: (like: boolean) => void;
|
78
|
-
sendContextualUpdate: (text: string) => void;
|
79
|
-
sendUserMessage: (text: string) => void;
|
80
|
-
sendUserActivity: () => void;
|
5
|
+
export type { SessionConfig, BaseSessionConfig, DisconnectionDetails, Language, ConnectionType, } from "./utils/BaseConnection";
|
6
|
+
export { createConnection } from "./utils/ConnectionFactory";
|
7
|
+
export { WebSocketConnection } from "./utils/WebSocketConnection";
|
8
|
+
export { WebRTCConnection } from "./utils/WebRTCConnection";
|
9
|
+
export { postOverallFeedback } from "./utils/postOverallFeedback";
|
10
|
+
export declare class Conversation extends BaseConversation {
|
11
|
+
static startSession(options: PartialOptions): Promise<Conversation>;
|
81
12
|
}
|
82
|
-
export declare function postOverallFeedback(conversationId: string, like: boolean, origin?: string): Promise<Response>;
|
package/dist/lib.cjs
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
function e(){return e=Object.assign?Object.assign.bind():function(e){for(var n=1;n<arguments.length;n++){var t=arguments[n];for(var o in t)({}).hasOwnProperty.call(t,o)&&(e[o]=t[o])}return e},e.apply(null,arguments)}function n(e){for(var n=window.atob(e),t=n.length,o=new Uint8Array(t),r=0;r<t;r++)o[r]=n.charCodeAt(r);return o.buffer}function t(e,n){try{var t=e()}catch(e){return n(e)}return t&&t.then?t.then(void 0,n):t}var o=new Map;function r(e,n){return function(r){try{var i,s=function(s){return i?s:t(function(){var t="data:application/javascript;base64,"+btoa(n);return Promise.resolve(r.addModule(t)).then(function(){o.set(e,t)})},function(){throw new Error("Failed to load the "+e+" worklet module. Make sure the browser supports AudioWorklets.")})},a=o.get(e);if(a)return Promise.resolve(r.addModule(a));var u=new Blob([n],{type:"application/javascript"}),c=URL.createObjectURL(u),l=t(function(){return Promise.resolve(r.addModule(c)).then(function(){o.set(e,c),i=1})},function(){URL.revokeObjectURL(c)});return Promise.resolve(l&&l.then?l.then(s):s(l))}catch(e){return Promise.reject(e)}}}var i=r("raw-audio-processor",'\nconst BIAS = 0x84;\nconst CLIP = 32635;\nconst encodeTable = [\n 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,\n 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,\n 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,\n 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,\n 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,\n 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,\n 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,\n 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,\n 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7\n];\n\nfunction encodeSample(sample) {\n let sign;\n let exponent;\n let mantissa;\n let muLawSample;\n sign = (sample >> 8) & 0x80;\n if (sign !== 0) sample = -sample;\n sample = sample + BIAS;\n if (sample > CLIP) sample = CLIP;\n exponent = encodeTable[(sample>>7) & 0xFF];\n mantissa = (sample >> (exponent+3)) & 0x0F;\n muLawSample = ~(sign | (exponent << 4) | mantissa);\n \n return muLawSample;\n}\n\nclass RawAudioProcessor extends AudioWorkletProcessor {\n constructor() {\n super();\n \n this.port.onmessage = ({ data }) => {\n switch (data.type) {\n case "setFormat":\n this.isMuted = false;\n this.buffer = []; // Initialize an empty buffer\n this.bufferSize = data.sampleRate / 4;\n this.format = data.format;\n\n if (globalThis.LibSampleRate && sampleRate !== data.sampleRate) {\n globalThis.LibSampleRate.create(1, sampleRate, data.sampleRate).then(resampler => {\n this.resampler = resampler;\n });\n }\n break;\n case "setMuted":\n this.isMuted = data.isMuted;\n break;\n }\n };\n }\n process(inputs) {\n if (!this.buffer) {\n return true;\n }\n \n const input = inputs[0]; // Get the first input node\n if (input.length > 0) {\n let channelData = input[0]; // Get the first channel\'s data\n\n // Resample the audio if necessary\n if (this.resampler) {\n channelData = this.resampler.full(channelData);\n }\n\n // Add channel data to the buffer\n this.buffer.push(...channelData);\n // Get max volume \n let sum = 0.0;\n for (let i = 0; i < channelData.length; i++) {\n sum += channelData[i] * channelData[i];\n }\n const maxVolume = Math.sqrt(sum / channelData.length);\n // Check if buffer size has reached or exceeded the threshold\n if (this.buffer.length >= this.bufferSize) {\n const float32Array = this.isMuted \n ? new Float32Array(this.buffer.length)\n : new Float32Array(this.buffer);\n\n let encodedArray = this.format === "ulaw"\n ? new Uint8Array(float32Array.length)\n : new Int16Array(float32Array.length);\n\n // Iterate through the Float32Array and convert each sample to PCM16\n for (let i = 0; i < float32Array.length; i++) {\n // Clamp the value to the range [-1, 1]\n let sample = Math.max(-1, Math.min(1, float32Array[i]));\n\n // Scale the sample to the range [-32768, 32767]\n let value = sample < 0 ? sample * 32768 : sample * 32767;\n if (this.format === "ulaw") {\n value = encodeSample(Math.round(value));\n }\n\n encodedArray[i] = value;\n }\n\n // Send the buffered data to the main script\n this.port.postMessage([encodedArray, maxVolume]);\n\n // Clear the buffer after sending\n this.buffer = [];\n }\n }\n return true; // Continue processing\n }\n}\nregisterProcessor("raw-audio-processor", RawAudioProcessor);\n');function s(){return["iPad Simulator","iPhone Simulator","iPod Simulator","iPad","iPhone","iPod"].includes(navigator.platform)||navigator.userAgent.includes("Mac")&&"ontouchend"in document}var a=/*#__PURE__*/function(){function e(e,n,t,o){this.context=void 0,this.analyser=void 0,this.worklet=void 0,this.inputStream=void 0,this.context=e,this.analyser=n,this.worklet=t,this.inputStream=o}e.create=function(n){var t=n.sampleRate,o=n.format,r=n.preferHeadphonesForIosDevices;try{var a=null,u=null;return Promise.resolve(function(n,c){try{var l=function(){function n(){function n(){return Promise.resolve(i(a.audioWorklet)).then(function(){return Promise.resolve(navigator.mediaDevices.getUserMedia({audio:c})).then(function(n){var r=a.createMediaStreamSource(u=n),i=new AudioWorkletNode(a,"raw-audio-processor");return i.port.postMessage({type:"setFormat",format:o,sampleRate:t}),r.connect(s),s.connect(i),Promise.resolve(a.resume()).then(function(){return new e(a,s,i,u)})})})}var r=navigator.mediaDevices.getSupportedConstraints().sampleRate,s=(a=new window.AudioContext(r?{sampleRate:t}:{})).createAnalyser(),l=function(){if(!r)return Promise.resolve(a.audioWorklet.addModule("https://cdn.jsdelivr.net/npm/@alexanderolsen/libsamplerate-js@2.1.2/dist/libsamplerate.worklet.js")).then(function(){})}();return l&&l.then?l.then(n):n()}var c={sampleRate:{ideal:t},echoCancellation:{ideal:!0},noiseSuppression:{ideal:!0}},l=function(){if(s()&&r)return Promise.resolve(window.navigator.mediaDevices.enumerateDevices()).then(function(e){var n=e.find(function(e){return"audioinput"===e.kind&&["airpod","headphone","earphone"].find(function(n){return e.label.toLowerCase().includes(n)})});n&&(c.deviceId={ideal:n.deviceId})})}();return l&&l.then?l.then(n):n()}()}catch(e){return c(e)}return l&&l.then?l.then(void 0,c):l}(0,function(e){var n,t;throw null==(n=u)||n.getTracks().forEach(function(e){return e.stop()}),null==(t=a)||t.close(),e}))}catch(e){return Promise.reject(e)}};var n=e.prototype;return n.close=function(){try{return this.inputStream.getTracks().forEach(function(e){return e.stop()}),Promise.resolve(this.context.close()).then(function(){})}catch(e){return Promise.reject(e)}},n.setMuted=function(e){this.worklet.port.postMessage({type:"setMuted",isMuted:e})},e}(),u=r("audio-concat-processor",'\nconst decodeTable = [0,132,396,924,1980,4092,8316,16764];\n\nexport function decodeSample(muLawSample) {\n let sign;\n let exponent;\n let mantissa;\n let sample;\n muLawSample = ~muLawSample;\n sign = (muLawSample & 0x80);\n exponent = (muLawSample >> 4) & 0x07;\n mantissa = muLawSample & 0x0F;\n sample = decodeTable[exponent] + (mantissa << (exponent+3));\n if (sign !== 0) sample = -sample;\n\n return sample;\n}\n\nclass AudioConcatProcessor extends AudioWorkletProcessor {\n constructor() {\n super();\n this.buffers = []; // Initialize an empty buffer\n this.cursor = 0;\n this.currentBuffer = null;\n this.wasInterrupted = false;\n this.finished = false;\n \n this.port.onmessage = ({ data }) => {\n switch (data.type) {\n case "setFormat":\n this.format = data.format;\n break;\n case "buffer":\n this.wasInterrupted = false;\n this.buffers.push(\n this.format === "ulaw"\n ? new Uint8Array(data.buffer)\n : new Int16Array(data.buffer)\n );\n break;\n case "interrupt":\n this.wasInterrupted = true;\n break;\n case "clearInterrupted":\n if (this.wasInterrupted) {\n this.wasInterrupted = false;\n this.buffers = [];\n this.currentBuffer = null;\n }\n }\n };\n }\n process(_, outputs) {\n let finished = false;\n const output = outputs[0][0];\n for (let i = 0; i < output.length; i++) {\n if (!this.currentBuffer) {\n if (this.buffers.length === 0) {\n finished = true;\n break;\n }\n this.currentBuffer = this.buffers.shift();\n this.cursor = 0;\n }\n\n let value = this.currentBuffer[this.cursor];\n if (this.format === "ulaw") {\n value = decodeSample(value);\n }\n output[i] = value / 32768;\n this.cursor++;\n\n if (this.cursor >= this.currentBuffer.length) {\n this.currentBuffer = null;\n }\n }\n\n if (this.finished !== finished) {\n this.finished = finished;\n this.port.postMessage({ type: "process", finished });\n }\n\n return true; // Continue processing\n }\n}\n\nregisterProcessor("audio-concat-processor", AudioConcatProcessor);\n'),c=/*#__PURE__*/function(){function e(e,n,t,o){this.context=void 0,this.analyser=void 0,this.gain=void 0,this.worklet=void 0,this.context=e,this.analyser=n,this.gain=t,this.worklet=o}return e.create=function(n){var t=n.sampleRate,o=n.format;try{var r=null;return Promise.resolve(function(n,i){try{var s=(a=(r=new AudioContext({sampleRate:t})).createAnalyser(),(c=r.createGain()).connect(a),a.connect(r.destination),Promise.resolve(u(r.audioWorklet)).then(function(){var n=new AudioWorkletNode(r,"audio-concat-processor");return n.port.postMessage({type:"setFormat",format:o}),n.connect(c),Promise.resolve(r.resume()).then(function(){return new e(r,a,c,n)})}))}catch(e){return i(e)}var a,c;return s&&s.then?s.then(void 0,i):s}(0,function(e){var n;throw null==(n=r)||n.close(),e}))}catch(e){return Promise.reject(e)}},e.prototype.close=function(){try{return Promise.resolve(this.context.close()).then(function(){})}catch(e){return Promise.reject(e)}},e}();function l(e){return!!e.type}var d=/*#__PURE__*/function(){function e(e,n,t,o){var r=this;this.socket=void 0,this.conversationId=void 0,this.inputFormat=void 0,this.outputFormat=void 0,this.queue=[],this.disconnectionDetails=null,this.onDisconnectCallback=null,this.onMessageCallback=null,this.socket=e,this.conversationId=n,this.inputFormat=t,this.outputFormat=o,this.socket.addEventListener("error",function(e){setTimeout(function(){return r.disconnect({reason:"error",message:"The connection was closed due to a socket error.",context:e})},0)}),this.socket.addEventListener("close",function(e){r.disconnect(1e3===e.code?{reason:"agent",context:e}:{reason:"error",message:e.reason||"The connection was closed by the server.",context:e})}),this.socket.addEventListener("message",function(e){try{var n=JSON.parse(e.data);if(!l(n))return;r.onMessageCallback?r.onMessageCallback(n):r.queue.push(n)}catch(e){}})}e.create=function(n){try{var t=null;return Promise.resolve(function(o,r){try{var i=(a=null!=(s=n.origin)?s:"wss://api.elevenlabs.io",u=n.signedUrl?n.signedUrl:a+"/v1/convai/conversation?agent_id="+n.agentId,c=["convai"],n.authorization&&c.push("bearer."+n.authorization),t=new WebSocket(u,c),Promise.resolve(new Promise(function(e,o){t.addEventListener("open",function(){var e,o,r,i,s,a={type:"conversation_initiation_client_data"};n.overrides&&(a.conversation_config_override={agent:{prompt:null==(o=n.overrides.agent)?void 0:o.prompt,first_message:null==(r=n.overrides.agent)?void 0:r.firstMessage,language:null==(i=n.overrides.agent)?void 0:i.language},tts:{voice_id:null==(s=n.overrides.tts)?void 0:s.voiceId}}),n.customLlmExtraBody&&(a.custom_llm_extra_body=n.customLlmExtraBody),n.dynamicVariables&&(a.dynamic_variables=n.dynamicVariables),null==(e=t)||e.send(JSON.stringify(a))},{once:!0}),t.addEventListener("error",function(e){setTimeout(function(){return o(e)},0)}),t.addEventListener("close",o),t.addEventListener("message",function(n){var t=JSON.parse(n.data);l(t)&&("conversation_initiation_metadata"===t.type?e(t.conversation_initiation_metadata_event):console.warn("First received message is not conversation metadata."))},{once:!0})})).then(function(n){var o=n.conversation_id,r=n.agent_output_audio_format,i=n.user_input_audio_format,s=h(null!=i?i:"pcm_16000"),a=h(r);return new e(t,o,s,a)}))}catch(e){return r(e)}var s,a,u,c;return i&&i.then?i.then(void 0,r):i}(0,function(e){var n;throw null==(n=t)||n.close(),e}))}catch(e){return Promise.reject(e)}};var n=e.prototype;return n.close=function(){this.socket.close()},n.sendMessage=function(e){this.socket.send(JSON.stringify(e))},n.onMessage=function(e){this.onMessageCallback=e,this.queue.forEach(e),this.queue=[]},n.onDisconnect=function(e){this.onDisconnectCallback=e,this.disconnectionDetails&&e(this.disconnectionDetails)},n.disconnect=function(e){var n;this.disconnectionDetails||(this.disconnectionDetails=e,null==(n=this.onDisconnectCallback)||n.call(this,e))},e}();function h(e){var n=e.split("_"),t=n[0],o=n[1];if(!["pcm","ulaw"].includes(t))throw new Error("Invalid format: "+e);var r=parseInt(o);if(isNaN(r))throw new Error("Invalid sample rate: "+o);return{format:t,sampleRate:r}}function p(e,n){try{var t=e()}catch(e){return n(e)}return t&&t.then?t.then(void 0,n):t}var f={clientTools:{}},m={onConnect:function(){},onDebug:function(){},onDisconnect:function(){},onError:function(){},onMessage:function(){},onAudio:function(){},onModeChange:function(){},onStatusChange:function(){},onCanSendFeedbackChange:function(){}};exports.Conversation=/*#__PURE__*/function(){function t(e,t,o,r,i){var s=this,a=this,u=this;this.options=void 0,this.connection=void 0,this.input=void 0,this.output=void 0,this.wakeLock=void 0,this.lastInterruptTimestamp=0,this.mode="listening",this.status="connecting",this.inputFrequencyData=void 0,this.outputFrequencyData=void 0,this.volume=1,this.currentEventId=1,this.lastFeedbackEventId=1,this.canSendFeedback=!1,this.endSession=function(){return u.endSessionWithDetails({reason:"user"})},this.endSessionWithDetails=function(e){try{var n=function(){return s.connection.close(),Promise.resolve(s.input.close()).then(function(){return Promise.resolve(s.output.close()).then(function(){s.updateStatus("disconnected"),s.options.onDisconnect(e)})})};if("connected"!==s.status&&"connecting"!==s.status)return Promise.resolve();s.updateStatus("disconnecting");var t=p(function(){var e;return Promise.resolve(null==(e=s.wakeLock)?void 0:e.release()).then(function(){s.wakeLock=null})},function(){});return Promise.resolve(t&&t.then?t.then(n):n())}catch(e){return Promise.reject(e)}},this.updateMode=function(e){e!==u.mode&&(u.mode=e,u.options.onModeChange({mode:e}))},this.updateStatus=function(e){e!==u.status&&(u.status=e,u.options.onStatusChange({status:e}))},this.updateCanSendFeedback=function(){var e=u.currentEventId!==u.lastFeedbackEventId;u.canSendFeedback!==e&&(u.canSendFeedback=e,u.options.onCanSendFeedbackChange({canSendFeedback:e}))},this.onMessage=function(e){try{switch(e.type){case"interruption":return e.interruption_event&&(a.lastInterruptTimestamp=e.interruption_event.event_id),a.fadeOutAudio(),Promise.resolve();case"agent_response":return a.options.onMessage({source:"ai",message:e.agent_response_event.agent_response}),Promise.resolve();case"user_transcript":return a.options.onMessage({source:"user",message:e.user_transcription_event.user_transcript}),Promise.resolve();case"internal_tentative_agent_response":return a.options.onDebug({type:"tentative_agent_response",response:e.tentative_agent_response_internal_event.tentative_agent_response}),Promise.resolve();case"client_tool_call":return Promise.resolve(function(){if(a.options.clientTools.hasOwnProperty(e.client_tool_call.tool_name)){var n=p(function(){return Promise.resolve(a.options.clientTools[e.client_tool_call.tool_name](e.client_tool_call.parameters)).then(function(n){var t="object"==typeof n?JSON.stringify(n):String(n);a.connection.sendMessage({type:"client_tool_result",tool_call_id:e.client_tool_call.tool_call_id,result:t,is_error:!1})})},function(n){a.onError("Client tool execution failed with following error: "+(null==n?void 0:n.message),{clientToolName:e.client_tool_call.tool_name}),a.connection.sendMessage({type:"client_tool_result",tool_call_id:e.client_tool_call.tool_call_id,result:"Client tool execution failed: "+(null==n?void 0:n.message),is_error:!0})});if(n&&n.then)return n.then(function(){})}else{if(a.options.onUnhandledClientToolCall)return void a.options.onUnhandledClientToolCall(e.client_tool_call);a.onError("Client tool with name "+e.client_tool_call.tool_name+" is not defined on client",{clientToolName:e.client_tool_call.tool_name}),a.connection.sendMessage({type:"client_tool_result",tool_call_id:e.client_tool_call.tool_call_id,result:"Client tool with name "+e.client_tool_call.tool_name+" is not defined on client",is_error:!0})}}());case"audio":return a.lastInterruptTimestamp<=e.audio_event.event_id&&(a.options.onAudio(e.audio_event.audio_base_64),a.addAudioBase64Chunk(e.audio_event.audio_base_64),a.currentEventId=e.audio_event.event_id,a.updateCanSendFeedback(),a.updateMode("speaking")),Promise.resolve();case"ping":return a.connection.sendMessage({type:"pong",event_id:e.ping_event.event_id}),Promise.resolve();default:return a.options.onDebug(e),Promise.resolve()}}catch(e){return Promise.reject(e)}},this.onInputWorkletMessage=function(e){var n,t;"connected"===u.status&&u.connection.sendMessage({user_audio_chunk:(n=e.data[0].buffer,t=new Uint8Array(n),window.btoa(String.fromCharCode.apply(String,t)))})},this.onOutputWorkletMessage=function(e){var n=e.data;"process"===n.type&&u.updateMode(n.finished?"listening":"speaking")},this.addAudioBase64Chunk=function(e){u.output.gain.gain.value=u.volume,u.output.worklet.port.postMessage({type:"clearInterrupted"}),u.output.worklet.port.postMessage({type:"buffer",buffer:n(e)})},this.fadeOutAudio=function(){u.updateMode("listening"),u.output.worklet.port.postMessage({type:"interrupt"}),u.output.gain.gain.exponentialRampToValueAtTime(1e-4,u.output.context.currentTime+2),setTimeout(function(){u.output.gain.gain.value=u.volume,u.output.worklet.port.postMessage({type:"clearInterrupted"})},2e3)},this.onError=function(e,n){console.error(e,n),u.options.onError(e,n)},this.calculateVolume=function(e){if(0===e.length)return 0;for(var n=0,t=0;t<e.length;t++)n+=e[t]/255;return(n/=e.length)<0?0:n>1?1:n},this.getId=function(){return u.connection.conversationId},this.isOpen=function(){return"connected"===u.status},this.setVolume=function(e){u.volume=e.volume},this.setMicMuted=function(e){u.input.setMuted(e)},this.getInputByteFrequencyData=function(){return null!=u.inputFrequencyData||(u.inputFrequencyData=new Uint8Array(u.input.analyser.frequencyBinCount)),u.input.analyser.getByteFrequencyData(u.inputFrequencyData),u.inputFrequencyData},this.getOutputByteFrequencyData=function(){return null!=u.outputFrequencyData||(u.outputFrequencyData=new Uint8Array(u.output.analyser.frequencyBinCount)),u.output.analyser.getByteFrequencyData(u.outputFrequencyData),u.outputFrequencyData},this.getInputVolume=function(){return u.calculateVolume(u.getInputByteFrequencyData())},this.getOutputVolume=function(){return u.calculateVolume(u.getOutputByteFrequencyData())},this.sendFeedback=function(e){u.canSendFeedback?(u.connection.sendMessage({type:"feedback",score:e?"like":"dislike",event_id:u.currentEventId}),u.lastFeedbackEventId=u.currentEventId,u.updateCanSendFeedback()):console.warn(0===u.lastFeedbackEventId?"Cannot send feedback: the conversation has not started yet.":"Cannot send feedback: feedback has already been sent for the current response.")},this.sendContextualUpdate=function(e){u.connection.sendMessage({type:"contextual_update",text:e})},this.sendUserMessage=function(e){u.connection.sendMessage({type:"user_message",text:e})},this.sendUserActivity=function(){u.connection.sendMessage({type:"user_activity"})},this.options=e,this.connection=t,this.input=o,this.output=r,this.wakeLock=i,this.options.onConnect({conversationId:t.conversationId}),this.connection.onDisconnect(this.endSessionWithDetails),this.connection.onMessage(this.onMessage),this.input.worklet.port.onmessage=this.onInputWorkletMessage,this.output.worklet.port.onmessage=this.onOutputWorkletMessage,this.updateStatus("connected")}return t.startSession=function(n){try{var o=function(){return p(function(){return Promise.resolve(navigator.mediaDevices.getUserMedia({audio:!0})).then(function(o){var p;function f(){return Promise.resolve(d.create(n)).then(function(o){return u=o,Promise.resolve(Promise.all([a.create(e({},u.inputFormat,{preferHeadphonesForIosDevices:n.preferHeadphonesForIosDevices})),c.create(u.outputFormat)])).then(function(e){var n;return i=e[0],l=e[1],null==(n=h)||n.getTracks().forEach(function(e){return e.stop()}),h=null,new t(r,u,i,l,v)})})}h=o;var m,g=null!=(p=n.connectionDelay)?p:{default:0,android:3e3},y=g.default;if(/android/i.test(navigator.userAgent))y=null!=(m=g.android)?m:y;else if(s()){var _;y=null!=(_=g.ios)?_:y}var b=function(){if(y>0)return Promise.resolve(new Promise(function(e){return setTimeout(e,y)})).then(function(){})}();return b&&b.then?b.then(f):f()})},function(e){var n,t,o;return r.onStatusChange({status:"disconnected"}),null==(n=h)||n.getTracks().forEach(function(e){return e.stop()}),null==(t=u)||t.close(),Promise.resolve(null==(o=i)?void 0:o.close()).then(function(){var n;return Promise.resolve(null==(n=l)?void 0:n.close()).then(function(){function n(){throw e}var t=p(function(){var e;return Promise.resolve(null==(e=v)?void 0:e.release()).then(function(){v=null})},function(){});return t&&t.then?t.then(n):n()})})})},r=e({},f,m,n);r.onStatusChange({status:"connecting"}),r.onCanSendFeedbackChange({canSendFeedback:!1});var i=null,u=null,l=null,h=null,v=null,g=function(e){if(null==(e=n.useWakeLock)||e){var t=p(function(){return Promise.resolve(navigator.wakeLock.request("screen")).then(function(e){v=e})},function(){});if(t&&t.then)return t.then(function(){})}}();return Promise.resolve(g&&g.then?g.then(o):o())}catch(e){return Promise.reject(e)}},t}(),exports.postOverallFeedback=function(e,n,t){return void 0===t&&(t="https://api.elevenlabs.io"),fetch(t+"/v1/convai/conversations/"+e+"/feedback",{method:"POST",body:JSON.stringify({feedback:n?"like":"dislike"}),headers:{"Content-Type":"application/json"}})};
|
1
|
+
var e=require("livekit-client");function n(){return n=Object.assign?Object.assign.bind():function(e){for(var n=1;n<arguments.length;n++){var t=arguments[n];for(var o in t)({}).hasOwnProperty.call(t,o)&&(e[o]=t[o])}return e},n.apply(null,arguments)}function t(e,n){e.prototype=Object.create(n.prototype),e.prototype.constructor=e,o(e,n)}function o(e,n){return o=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,n){return e.__proto__=n,e},o(e,n)}var r=new Uint8Array(0),i=/*#__PURE__*/function(){function e(e,n){var t=this,o=this,r=this;this.options=void 0,this.connection=void 0,this.lastInterruptTimestamp=0,this.mode="listening",this.status="connecting",this.volume=1,this.currentEventId=1,this.lastFeedbackEventId=1,this.canSendFeedback=!1,this.endSessionWithDetails=function(e){try{return"connected"!==o.status&&"connecting"!==o.status?Promise.resolve():(o.updateStatus("disconnecting"),Promise.resolve(o.handleEndSession()).then(function(){o.updateStatus("disconnected"),o.options.onDisconnect(e)}))}catch(e){return Promise.reject(e)}},this.onMessage=function(e){try{switch(e.type){case"interruption":return r.handleInterruption(e),Promise.resolve();case"agent_response":return r.handleAgentResponse(e),Promise.resolve();case"user_transcript":return r.handleUserTranscript(e),Promise.resolve();case"internal_tentative_agent_response":return r.handleTentativeAgentResponse(e),Promise.resolve();case"client_tool_call":return Promise.resolve(r.handleClientToolCall(e)).then(function(){});case"audio":return r.handleAudio(e),Promise.resolve();case"ping":return r.connection.sendMessage({type:"pong",event_id:e.ping_event.event_id}),Promise.resolve();default:return r.options.onDebug(e),Promise.resolve()}}catch(e){return Promise.reject(e)}},this.setVolume=function(e){t.volume=e.volume},this.options=e,this.connection=n,this.options.onConnect({conversationId:n.conversationId}),this.connection.onMessage(this.onMessage),this.connection.onDisconnect(this.endSessionWithDetails),this.updateStatus("connected")}e.getFullOptions=function(e){return n({clientTools:{},onConnect:function(){},onDebug:function(){},onDisconnect:function(){},onError:function(){},onMessage:function(){},onAudio:function(){},onModeChange:function(){},onStatusChange:function(){},onCanSendFeedbackChange:function(){}},e)};var t=e.prototype;return t.endSession=function(){return this.endSessionWithDetails({reason:"user"})},t.handleEndSession=function(){try{return this.connection.close(),Promise.resolve()}catch(e){return Promise.reject(e)}},t.updateMode=function(e){e!==this.mode&&(this.mode=e,this.options.onModeChange({mode:e}))},t.updateStatus=function(e){e!==this.status&&(this.status=e,this.options.onStatusChange({status:e}))},t.updateCanSendFeedback=function(){var e=this.currentEventId!==this.lastFeedbackEventId;this.canSendFeedback!==e&&(this.canSendFeedback=e,this.options.onCanSendFeedbackChange({canSendFeedback:e}))},t.handleInterruption=function(e){e.interruption_event&&(this.lastInterruptTimestamp=e.interruption_event.event_id)},t.handleAgentResponse=function(e){this.options.onMessage({source:"ai",message:e.agent_response_event.agent_response})},t.handleUserTranscript=function(e){this.options.onMessage({source:"user",message:e.user_transcription_event.user_transcript})},t.handleTentativeAgentResponse=function(e){this.options.onDebug({type:"tentative_agent_response",response:e.tentative_agent_response_internal_event.tentative_agent_response})},t.handleClientToolCall=function(e){try{var n=this;return Promise.resolve(function(){if(Object.prototype.hasOwnProperty.call(n.options.clientTools,e.client_tool_call.tool_name)){var t=function(t,o){try{var r=Promise.resolve(n.options.clientTools[e.client_tool_call.tool_name](e.client_tool_call.parameters)).then(function(t){var o="object"==typeof t?JSON.stringify(t):String(t);n.connection.sendMessage({type:"client_tool_result",tool_call_id:e.client_tool_call.tool_call_id,result:o,is_error:!1})})}catch(e){return o(e)}return r&&r.then?r.then(void 0,o):r}(0,function(t){n.onError("Client tool execution failed with following error: "+(null==t?void 0:t.message),{clientToolName:e.client_tool_call.tool_name}),n.connection.sendMessage({type:"client_tool_result",tool_call_id:e.client_tool_call.tool_call_id,result:"Client tool execution failed: "+(null==t?void 0:t.message),is_error:!0})});if(t&&t.then)return t.then(function(){})}else{if(n.options.onUnhandledClientToolCall)return void n.options.onUnhandledClientToolCall(e.client_tool_call);n.onError("Client tool with name "+e.client_tool_call.tool_name+" is not defined on client",{clientToolName:e.client_tool_call.tool_name}),n.connection.sendMessage({type:"client_tool_result",tool_call_id:e.client_tool_call.tool_call_id,result:"Client tool with name "+e.client_tool_call.tool_name+" is not defined on client",is_error:!0})}}())}catch(e){return Promise.reject(e)}},t.handleAudio=function(e){},t.onError=function(e,n){console.error(e,n),this.options.onError(e,n)},t.getId=function(){return this.connection.conversationId},t.isOpen=function(){return"connected"===this.status},t.setMicMuted=function(e){},t.getInputByteFrequencyData=function(){return r},t.getOutputByteFrequencyData=function(){return r},t.getInputVolume=function(){return 0},t.getOutputVolume=function(){return 0},t.sendFeedback=function(e){this.canSendFeedback?(this.connection.sendMessage({type:"feedback",score:e?"like":"dislike",event_id:this.currentEventId}),this.lastFeedbackEventId=this.currentEventId,this.updateCanSendFeedback()):console.warn(0===this.lastFeedbackEventId?"Cannot send feedback: the conversation has not started yet.":"Cannot send feedback: feedback has already been sent for the current response.")},t.sendContextualUpdate=function(e){this.connection.sendMessage({type:"contextual_update",text:e})},t.sendUserMessage=function(e){this.connection.sendMessage({type:"user_message",text:e})},t.sendUserActivity=function(){this.connection.sendMessage({type:"user_activity"})},t.sendMCPToolApprovalResult=function(e,n){this.connection.sendMessage({type:"mcp_tool_approval_result",tool_call_id:e,is_approved:n})},e}(),s=/*#__PURE__*/function(){function e(e){void 0===e&&(e={}),this.queue=[],this.disconnectionDetails=null,this.onDisconnectCallback=null,this.onMessageCallback=null,this.onDebug=void 0,this.onDebug=e.onDebug}var n=e.prototype;return n.debug=function(e){this.onDebug&&this.onDebug(e)},n.onMessage=function(e){this.onMessageCallback=e;var n=this.queue;this.queue=[],n.length>0&&queueMicrotask(function(){n.forEach(e)})},n.onDisconnect=function(e){this.onDisconnectCallback=e;var n=this.disconnectionDetails;n&&queueMicrotask(function(){e(n)})},n.disconnect=function(e){var n;this.disconnectionDetails||(this.disconnectionDetails=e,null==(n=this.onDisconnectCallback)||n.call(this,e))},n.handleMessage=function(e){this.onMessageCallback?this.onMessageCallback(e):this.queue.push(e)},e}();function a(e){var n=e.split("_"),t=n[0],o=n[1];if(!["pcm","ulaw"].includes(t))throw new Error("Invalid format: "+e);var r=Number.parseInt(o);if(Number.isNaN(r))throw new Error("Invalid sample rate: "+o);return{format:t,sampleRate:r}}var u="0.4.0";function c(e){return!!e.type}var l="conversation_initiation_client_data";function d(e){var n,t,o,r,i,s={type:l};return e.overrides&&(s.conversation_config_override={agent:{prompt:null==(n=e.overrides.agent)?void 0:n.prompt,first_message:null==(t=e.overrides.agent)?void 0:t.firstMessage,language:null==(o=e.overrides.agent)?void 0:o.language},tts:{voice_id:null==(r=e.overrides.tts)?void 0:r.voiceId},conversation:{text_only:null==(i=e.overrides.conversation)?void 0:i.textOnly}}),e.customLlmExtraBody&&(s.custom_llm_extra_body=e.customLlmExtraBody),e.dynamicVariables&&(s.dynamic_variables=e.dynamicVariables),e.userId&&(s.user_id=e.userId),s}var h=/*#__PURE__*/function(e){function n(n,t,o,r){var i;return(i=e.call(this)||this).socket=void 0,i.conversationId=void 0,i.inputFormat=void 0,i.outputFormat=void 0,i.socket=n,i.conversationId=t,i.inputFormat=o,i.outputFormat=r,i.socket.addEventListener("error",function(e){setTimeout(function(){return i.disconnect({reason:"error",message:"The connection was closed due to a socket error.",context:e})},0)}),i.socket.addEventListener("close",function(e){i.disconnect(1e3===e.code?{reason:"agent",context:e}:{reason:"error",message:e.reason||"The connection was closed by the server.",context:e})}),i.socket.addEventListener("message",function(e){try{var n=JSON.parse(e.data);if(!c(n))return;i.handleMessage(n)}catch(e){}}),i}t(n,e),n.create=function(e){try{var t=null;return Promise.resolve(function(o,r){try{var i=function(){var o,r,i,s,l=null!=(o=e.origin)?o:"wss://api.elevenlabs.io",h=(null==(r=e.overrides)||null==(r=r.client)?void 0:r.version)||u,f=(null==(i=e.overrides)||null==(i=i.client)?void 0:i.source)||"js_sdk";if(e.signedUrl){var p=e.signedUrl.includes("?")?"&":"?";s=""+e.signedUrl+p+"source="+f+"&version="+h}else s=l+"/v1/convai/conversation?agent_id="+e.agentId+"&source="+f+"&version="+h;var v=["convai"];return e.authorization&&v.push("bearer."+e.authorization),t=new WebSocket(s,v),Promise.resolve(new Promise(function(n,o){t.addEventListener("open",function(){var n,o=d(e);null==(n=t)||n.send(JSON.stringify(o))},{once:!0}),t.addEventListener("error",function(e){setTimeout(function(){return o(e)},0)}),t.addEventListener("close",o),t.addEventListener("message",function(e){var t=JSON.parse(e.data);c(t)&&("conversation_initiation_metadata"===t.type?n(t.conversation_initiation_metadata_event):console.warn("First received message is not conversation metadata."))},{once:!0})})).then(function(e){var o=e.conversation_id,r=e.agent_output_audio_format,i=e.user_input_audio_format,s=a(null!=i?i:"pcm_16000"),u=a(r);return new n(t,o,s,u)})}()}catch(e){return r(e)}return i&&i.then?i.then(void 0,r):i}(0,function(e){var n;throw null==(n=t)||n.close(),e}))}catch(e){return Promise.reject(e)}};var o=n.prototype;return o.close=function(){this.socket.close()},o.sendMessage=function(e){this.socket.send(JSON.stringify(e))},n}(s);function f(e,n){try{var t=e()}catch(e){return n(e)}return t&&t.then?t.then(void 0,n):t}var p=/*#__PURE__*/function(n){function o(e,t,o,r,i){var s;return void 0===i&&(i={}),(s=n.call(this,i)||this).conversationId=void 0,s.inputFormat=void 0,s.outputFormat=void 0,s.room=void 0,s.isConnected=!1,s.room=e,s.conversationId=t,s.inputFormat=o,s.outputFormat=r,s.setupRoomEventListeners(),s}t(o,n),o.create=function(n){try{var t,r=function(r){var i=new e.Room;return f(function(){var r="webrtc-"+Date.now(),s=a("pcm_48000"),u=a("pcm_48000"),c=new o(i,r,s,u,n);return Promise.resolve(i.connect(n.livekitUrl||"wss://livekit.rtc.elevenlabs.io",t)).then(function(){return Promise.resolve(new Promise(function(n){if(c.isConnected)n();else{var t=function(){i.off(e.RoomEvent.Connected,t),n()};i.on(e.RoomEvent.Connected,t)}})).then(function(){return i.name&&(c.conversationId=i.name),Promise.resolve(i.localParticipant.setMicrophoneEnabled(!0)).then(function(){var e=d(n);return c.debug({type:l,message:e}),Promise.resolve(c.sendMessage(e)).then(function(){return c})})})})},function(e){return Promise.resolve(i.disconnect()).then(function(){throw e})})},i=function(){if(!("conversationToken"in n)||!n.conversationToken)return function(){if("agentId"in n&&n.agentId)return f(function(){var e,o,r=(null==(e=n.overrides)||null==(e=e.client)?void 0:e.version)||u,i=(null==(o=n.overrides)||null==(o=o.client)?void 0:o.source)||"js_sdk";return Promise.resolve(fetch("https://api.elevenlabs.io/v1/convai/conversation/token?agent_id="+n.agentId+"&source="+i+"&version="+r)).then(function(e){if(!e.ok)throw new Error("ElevenLabs API returned "+e.status+" "+e.statusText);return Promise.resolve(e.json()).then(function(e){if(!(t=e.token))throw new Error("No conversation token received from API")})})},function(e){var t=e instanceof Error?e.message:String(e);throw e instanceof Error&&e.message.includes("401")&&(t="Your agent has authentication enabled, but no signed URL or conversation token was provided."),new Error("Failed to fetch conversation token for agent "+n.agentId+": "+t)});throw new Error("Either conversationToken or agentId is required for WebRTC connection")}();t=n.conversationToken}();return Promise.resolve(i&&i.then?i.then(r):r())}catch(e){return Promise.reject(e)}};var r=o.prototype;return r.setupRoomEventListeners=function(){var n=this,t=this;this.room.on(e.RoomEvent.Connected,function(){try{return t.isConnected=!0,console.info("WebRTC room connected"),Promise.resolve()}catch(e){return Promise.reject(e)}}),this.room.on(e.RoomEvent.Disconnected,function(e){n.isConnected=!1,n.disconnect({reason:"agent",context:new CloseEvent("close",{reason:null==e?void 0:e.toString()})})}),this.room.on(e.RoomEvent.ConnectionStateChanged,function(t){t===e.ConnectionState.Disconnected&&(n.isConnected=!1,n.disconnect({reason:"error",message:"LiveKit connection state changed to "+t,context:new Event("connection_state_changed")}))}),this.room.on(e.RoomEvent.DataReceived,function(e,t){try{var o=JSON.parse((new TextDecoder).decode(e));if("audio"===o.type)return;c(o)?n.handleMessage(o):console.warn("Invalid socket event received:",o)}catch(n){console.warn("Failed to parse incoming data message:",n),console.warn("Raw payload:",(new TextDecoder).decode(e))}}),this.room.on(e.RoomEvent.TrackSubscribed,function(n,t,o){try{if(n.kind===e.Track.Kind.Audio&&o.identity.includes("agent")){var r=n.attach();r.autoplay=!0,r.controls=!1,r.style.display="none",document.body.appendChild(r)}return Promise.resolve()}catch(e){return Promise.reject(e)}})},r.close=function(){this.isConnected&&this.room.disconnect()},r.sendMessage=function(e){try{var n=this;if(!n.isConnected||!n.room.localParticipant)return console.warn("Cannot send message: room not connected or no local participant"),Promise.resolve();if("user_audio_chunk"in e)return Promise.resolve();var t=f(function(){var t=(new TextEncoder).encode(JSON.stringify(e));return Promise.resolve(n.room.localParticipant.publishData(t,{reliable:!0})).then(function(){})},function(t){n.debug({type:"send_message_error",message:{message:e,error:t}}),console.error("Failed to send message via WebRTC:",t)});return Promise.resolve(t&&t.then?t.then(function(){}):void 0)}catch(e){return Promise.reject(e)}},r.getRoom=function(){return this.room},o}(s),v=function(e){try{var n=function(e){return e.connectionType?e.connectionType:"conversationToken"in e&&e.conversationToken?"webrtc":"websocket"}(e);switch(n){case"websocket":return Promise.resolve(h.create(e));case"webrtc":return Promise.resolve(p.create(e));default:throw new Error("Unknown connection type: "+n)}}catch(e){return Promise.reject(e)}};function m(){return["iPad Simulator","iPhone Simulator","iPod Simulator","iPad","iPhone","iPod"].includes(navigator.platform)||navigator.userAgent.includes("Mac")&&"ontouchend"in document}var g=function(e){void 0===e&&(e={default:0,android:3e3});try{var n,t=e.default;if(/android/i.test(navigator.userAgent))t=null!=(n=e.android)?n:t;else if(m()){var o;t=null!=(o=e.ios)?o:t}var r=function(){if(t>0)return Promise.resolve(new Promise(function(e){return setTimeout(e,t)})).then(function(){})}();return Promise.resolve(r&&r.then?r.then(function(){}):void 0)}catch(e){return Promise.reject(e)}},y=/*#__PURE__*/function(e){function n(){return e.apply(this,arguments)||this}return t(n,e),n.startSession=function(e){try{var t=i.getFullOptions(e);t.onStatusChange({status:"connecting"}),t.onCanSendFeedbackChange({canSendFeedback:!1});var o=null;return Promise.resolve(function(r,i){try{var s=Promise.resolve(g(t.connectionDelay)).then(function(){return Promise.resolve(v(e)).then(function(e){return new n(t,o=e)})})}catch(e){return i(e)}return s&&s.then?s.then(void 0,i):s}(0,function(e){var n;throw t.onStatusChange({status:"disconnected"}),null==(n=o)||n.close(),e}))}catch(e){return Promise.reject(e)}},n}(i);function _(e){for(var n=window.atob(e),t=n.length,o=new Uint8Array(t),r=0;r<t;r++)o[r]=n.charCodeAt(r);return o.buffer}function b(e,n){try{var t=e()}catch(e){return n(e)}return t&&t.then?t.then(void 0,n):t}var w=new Map;function k(e,n){return function(t){try{var o,r=function(r){return o?r:b(function(){var o="data:application/javascript;base64,"+btoa(n);return Promise.resolve(t.addModule(o)).then(function(){w.set(e,o)})},function(){throw new Error("Failed to load the "+e+" worklet module. Make sure the browser supports AudioWorklets.")})},i=w.get(e);if(i)return Promise.resolve(t.addModule(i));var s=new Blob([n],{type:"application/javascript"}),a=URL.createObjectURL(s),u=b(function(){return Promise.resolve(t.addModule(a)).then(function(){w.set(e,a),o=1})},function(){URL.revokeObjectURL(a)});return Promise.resolve(u&&u.then?u.then(r):r(u))}catch(e){return Promise.reject(e)}}}var P=k("raw-audio-processor",'\nconst BIAS = 0x84;\nconst CLIP = 32635;\nconst encodeTable = [\n 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,\n 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,\n 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,\n 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,\n 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,\n 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,\n 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,\n 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,\n 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7\n];\n\nfunction encodeSample(sample) {\n let sign;\n let exponent;\n let mantissa;\n let muLawSample;\n sign = (sample >> 8) & 0x80;\n if (sign !== 0) sample = -sample;\n sample = sample + BIAS;\n if (sample > CLIP) sample = CLIP;\n exponent = encodeTable[(sample>>7) & 0xFF];\n mantissa = (sample >> (exponent+3)) & 0x0F;\n muLawSample = ~(sign | (exponent << 4) | mantissa);\n \n return muLawSample;\n}\n\nclass RawAudioProcessor extends AudioWorkletProcessor {\n constructor() {\n super();\n \n this.port.onmessage = ({ data }) => {\n switch (data.type) {\n case "setFormat":\n this.isMuted = false;\n this.buffer = []; // Initialize an empty buffer\n this.bufferSize = data.sampleRate / 4;\n this.format = data.format;\n\n if (globalThis.LibSampleRate && sampleRate !== data.sampleRate) {\n globalThis.LibSampleRate.create(1, sampleRate, data.sampleRate).then(resampler => {\n this.resampler = resampler;\n });\n }\n break;\n case "setMuted":\n this.isMuted = data.isMuted;\n break;\n }\n };\n }\n process(inputs) {\n if (!this.buffer) {\n return true;\n }\n \n const input = inputs[0]; // Get the first input node\n if (input.length > 0) {\n let channelData = input[0]; // Get the first channel\'s data\n\n // Resample the audio if necessary\n if (this.resampler) {\n channelData = this.resampler.full(channelData);\n }\n\n // Add channel data to the buffer\n this.buffer.push(...channelData);\n // Get max volume \n let sum = 0.0;\n for (let i = 0; i < channelData.length; i++) {\n sum += channelData[i] * channelData[i];\n }\n const maxVolume = Math.sqrt(sum / channelData.length);\n // Check if buffer size has reached or exceeded the threshold\n if (this.buffer.length >= this.bufferSize) {\n const float32Array = this.isMuted \n ? new Float32Array(this.buffer.length)\n : new Float32Array(this.buffer);\n\n let encodedArray = this.format === "ulaw"\n ? new Uint8Array(float32Array.length)\n : new Int16Array(float32Array.length);\n\n // Iterate through the Float32Array and convert each sample to PCM16\n for (let i = 0; i < float32Array.length; i++) {\n // Clamp the value to the range [-1, 1]\n let sample = Math.max(-1, Math.min(1, float32Array[i]));\n\n // Scale the sample to the range [-32768, 32767]\n let value = sample < 0 ? sample * 32768 : sample * 32767;\n if (this.format === "ulaw") {\n value = encodeSample(Math.round(value));\n }\n\n encodedArray[i] = value;\n }\n\n // Send the buffered data to the main script\n this.port.postMessage([encodedArray, maxVolume]);\n\n // Clear the buffer after sending\n this.buffer = [];\n }\n }\n return true; // Continue processing\n }\n}\nregisterProcessor("raw-audio-processor", RawAudioProcessor);\n'),C=/*#__PURE__*/function(){function e(e,n,t,o){this.context=void 0,this.analyser=void 0,this.worklet=void 0,this.inputStream=void 0,this.context=e,this.analyser=n,this.worklet=t,this.inputStream=o}e.create=function(n){var t=n.sampleRate,o=n.format,r=n.preferHeadphonesForIosDevices;try{var i=null,s=null;return Promise.resolve(function(n,a){try{var u=function(){function n(){function n(){return Promise.resolve(P(i.audioWorklet)).then(function(){return Promise.resolve(navigator.mediaDevices.getUserMedia({audio:a})).then(function(n){var r=i.createMediaStreamSource(s=n),a=new AudioWorkletNode(i,"raw-audio-processor");return a.port.postMessage({type:"setFormat",format:o,sampleRate:t}),r.connect(u),u.connect(a),Promise.resolve(i.resume()).then(function(){return new e(i,u,a,s)})})})}var r=navigator.mediaDevices.getSupportedConstraints().sampleRate,u=(i=new window.AudioContext(r?{sampleRate:t}:{})).createAnalyser(),c=function(){if(!r)return Promise.resolve(i.audioWorklet.addModule("https://cdn.jsdelivr.net/npm/@alexanderolsen/libsamplerate-js@2.1.2/dist/libsamplerate.worklet.js")).then(function(){})}();return c&&c.then?c.then(n):n()}var a={sampleRate:{ideal:t},echoCancellation:{ideal:!0},noiseSuppression:{ideal:!0}},u=function(){if(m()&&r)return Promise.resolve(window.navigator.mediaDevices.enumerateDevices()).then(function(e){var n=e.find(function(e){return"audioinput"===e.kind&&["airpod","headphone","earphone"].find(function(n){return e.label.toLowerCase().includes(n)})});n&&(a.deviceId={ideal:n.deviceId})})}();return u&&u.then?u.then(n):n()}()}catch(e){return a(e)}return u&&u.then?u.then(void 0,a):u}(0,function(e){var n,t;throw null==(n=s)||n.getTracks().forEach(function(e){return e.stop()}),null==(t=i)||t.close(),e}))}catch(e){return Promise.reject(e)}};var n=e.prototype;return n.close=function(){try{return this.inputStream.getTracks().forEach(function(e){return e.stop()}),Promise.resolve(this.context.close()).then(function(){})}catch(e){return Promise.reject(e)}},n.setMuted=function(e){this.worklet.port.postMessage({type:"setMuted",isMuted:e})},e}(),S=k("audio-concat-processor",'\nconst decodeTable = [0,132,396,924,1980,4092,8316,16764];\n\nexport function decodeSample(muLawSample) {\n let sign;\n let exponent;\n let mantissa;\n let sample;\n muLawSample = ~muLawSample;\n sign = (muLawSample & 0x80);\n exponent = (muLawSample >> 4) & 0x07;\n mantissa = muLawSample & 0x0F;\n sample = decodeTable[exponent] + (mantissa << (exponent+3));\n if (sign !== 0) sample = -sample;\n\n return sample;\n}\n\nclass AudioConcatProcessor extends AudioWorkletProcessor {\n constructor() {\n super();\n this.buffers = []; // Initialize an empty buffer\n this.cursor = 0;\n this.currentBuffer = null;\n this.wasInterrupted = false;\n this.finished = false;\n \n this.port.onmessage = ({ data }) => {\n switch (data.type) {\n case "setFormat":\n this.format = data.format;\n break;\n case "buffer":\n this.wasInterrupted = false;\n this.buffers.push(\n this.format === "ulaw"\n ? new Uint8Array(data.buffer)\n : new Int16Array(data.buffer)\n );\n break;\n case "interrupt":\n this.wasInterrupted = true;\n break;\n case "clearInterrupted":\n if (this.wasInterrupted) {\n this.wasInterrupted = false;\n this.buffers = [];\n this.currentBuffer = null;\n }\n }\n };\n }\n process(_, outputs) {\n let finished = false;\n const output = outputs[0][0];\n for (let i = 0; i < output.length; i++) {\n if (!this.currentBuffer) {\n if (this.buffers.length === 0) {\n finished = true;\n break;\n }\n this.currentBuffer = this.buffers.shift();\n this.cursor = 0;\n }\n\n let value = this.currentBuffer[this.cursor];\n if (this.format === "ulaw") {\n value = decodeSample(value);\n }\n output[i] = value / 32768;\n this.cursor++;\n\n if (this.cursor >= this.currentBuffer.length) {\n this.currentBuffer = null;\n }\n }\n\n if (this.finished !== finished) {\n this.finished = finished;\n this.port.postMessage({ type: "process", finished });\n }\n\n return true; // Continue processing\n }\n}\n\nregisterProcessor("audio-concat-processor", AudioConcatProcessor);\n'),M=/*#__PURE__*/function(){function e(e,n,t,o){this.context=void 0,this.analyser=void 0,this.gain=void 0,this.worklet=void 0,this.context=e,this.analyser=n,this.gain=t,this.worklet=o}return e.create=function(n){var t=n.sampleRate,o=n.format;try{var r=null;return Promise.resolve(function(n,i){try{var s=(a=(r=new AudioContext({sampleRate:t})).createAnalyser(),(u=r.createGain()).connect(a),a.connect(r.destination),Promise.resolve(S(r.audioWorklet)).then(function(){var n=new AudioWorkletNode(r,"audio-concat-processor");return n.port.postMessage({type:"setFormat",format:o}),n.connect(u),Promise.resolve(r.resume()).then(function(){return new e(r,a,u,n)})}))}catch(e){return i(e)}var a,u;return s&&s.then?s.then(void 0,i):s}(0,function(e){var n;throw null==(n=r)||n.close(),e}))}catch(e){return Promise.reject(e)}},e.prototype.close=function(){try{return Promise.resolve(this.context.close()).then(function(){})}catch(e){return Promise.reject(e)}},e}();function F(e,n){try{var t=e()}catch(e){return n(e)}return t&&t.then?t.then(void 0,n):t}var I=/*#__PURE__*/function(e){function o(n,t,o,r,i){var s;return(s=e.call(this,n,t)||this).input=void 0,s.output=void 0,s.wakeLock=void 0,s.inputFrequencyData=void 0,s.outputFrequencyData=void 0,s.onInputWorkletMessage=function(e){var n,t;"connected"===s.status&&s.connection.sendMessage({user_audio_chunk:(n=e.data[0].buffer,t=new Uint8Array(n),window.btoa(String.fromCharCode.apply(String,t)))})},s.onOutputWorkletMessage=function(e){var n=e.data;"process"===n.type&&s.updateMode(n.finished?"listening":"speaking")},s.addAudioBase64Chunk=function(e){s.output.gain.gain.value=s.volume,s.output.worklet.port.postMessage({type:"clearInterrupted"}),s.output.worklet.port.postMessage({type:"buffer",buffer:_(e)})},s.fadeOutAudio=function(){s.updateMode("listening"),s.output.worklet.port.postMessage({type:"interrupt"}),s.output.gain.gain.exponentialRampToValueAtTime(1e-4,s.output.context.currentTime+2),setTimeout(function(){s.output.gain.gain.value=s.volume,s.output.worklet.port.postMessage({type:"clearInterrupted"})},2e3)},s.calculateVolume=function(e){if(0===e.length)return 0;for(var n=0,t=0;t<e.length;t++)n+=e[t]/255;return(n/=e.length)<0?0:n>1?1:n},s.input=o,s.output=r,s.wakeLock=i,s.input.worklet.port.onmessage=s.onInputWorkletMessage,s.output.worklet.port.onmessage=s.onOutputWorkletMessage,s}t(o,e),o.startSession=function(e){try{var t=function(){return F(function(){return Promise.resolve(navigator.mediaDevices.getUserMedia({audio:!0})).then(function(t){return c=t,Promise.resolve(g(r.connectionDelay)).then(function(){return Promise.resolve(v(e)).then(function(t){return a=t,Promise.resolve(Promise.all([C.create(n({},a.inputFormat,{preferHeadphonesForIosDevices:e.preferHeadphonesForIosDevices})),M.create(a.outputFormat)])).then(function(e){var n;return s=e[0],u=e[1],null==(n=c)||n.getTracks().forEach(function(e){return e.stop()}),c=null,new o(r,a,s,u,l)})})})})},function(e){var n,t,o;return r.onStatusChange({status:"disconnected"}),null==(n=c)||n.getTracks().forEach(function(e){return e.stop()}),null==(t=a)||t.close(),Promise.resolve(null==(o=s)?void 0:o.close()).then(function(){var n;return Promise.resolve(null==(n=u)?void 0:n.close()).then(function(){function n(){throw e}var t=F(function(){var e;return Promise.resolve(null==(e=l)?void 0:e.release()).then(function(){l=null})},function(){});return t&&t.then?t.then(n):n()})})})},r=i.getFullOptions(e);r.onStatusChange({status:"connecting"}),r.onCanSendFeedbackChange({canSendFeedback:!1});var s=null,a=null,u=null,c=null,l=null,d=function(n){if(null==(n=e.useWakeLock)||n){var t=F(function(){return Promise.resolve(navigator.wakeLock.request("screen")).then(function(e){l=e})},function(){});if(t&&t.then)return t.then(function(){})}}();return Promise.resolve(d&&d.then?d.then(t):t())}catch(e){return Promise.reject(e)}};var r=o.prototype;return r.handleEndSession=function(){try{var n=this;return Promise.resolve(e.prototype.handleEndSession.call(n)).then(function(){function e(){return Promise.resolve(n.input.close()).then(function(){return Promise.resolve(n.output.close()).then(function(){})})}var t=F(function(){var e;return Promise.resolve(null==(e=n.wakeLock)?void 0:e.release()).then(function(){n.wakeLock=null})},function(){});return t&&t.then?t.then(e):e()})}catch(e){return Promise.reject(e)}},r.handleInterruption=function(n){e.prototype.handleInterruption.call(this,n),this.fadeOutAudio()},r.handleAudio=function(e){this.lastInterruptTimestamp<=e.audio_event.event_id&&(this.options.onAudio(e.audio_event.audio_base_64),this.addAudioBase64Chunk(e.audio_event.audio_base_64),this.currentEventId=e.audio_event.event_id,this.updateCanSendFeedback(),this.updateMode("speaking"))},r.setMicMuted=function(e){this.input.setMuted(e)},r.getInputByteFrequencyData=function(){return null!=this.inputFrequencyData||(this.inputFrequencyData=new Uint8Array(this.input.analyser.frequencyBinCount)),this.input.analyser.getByteFrequencyData(this.inputFrequencyData),this.inputFrequencyData},r.getOutputByteFrequencyData=function(){return null!=this.outputFrequencyData||(this.outputFrequencyData=new Uint8Array(this.output.analyser.frequencyBinCount)),this.output.analyser.getByteFrequencyData(this.outputFrequencyData),this.outputFrequencyData},r.getInputVolume=function(){return this.calculateVolume(this.getInputByteFrequencyData())},r.getOutputVolume=function(){return this.calculateVolume(this.getOutputByteFrequencyData())},o}(i);exports.Conversation=/*#__PURE__*/function(e){function n(){return e.apply(this,arguments)||this}return t(n,e),n.startSession=function(e){return e.textOnly?y.startSession(e):I.startSession(e)},n}(i),exports.WebRTCConnection=p,exports.WebSocketConnection=h,exports.createConnection=v,exports.postOverallFeedback=function(e,n,t){return void 0===t&&(t="https://api.elevenlabs.io"),fetch(t+"/v1/convai/conversations/"+e+"/feedback",{method:"POST",body:JSON.stringify({feedback:n?"like":"dislike"}),headers:{"Content-Type":"application/json"}})};
|
2
2
|
//# sourceMappingURL=lib.cjs.map
|