@layercode/js-sdk 1.0.11 → 1.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/layercode-js-sdk.esm.js +3777 -0
- package/dist/layercode-js-sdk.esm.js.map +1 -0
- package/dist/layercode-js-sdk.min.js +3785 -0
- package/dist/layercode-js-sdk.min.js.map +1 -0
- package/dist/types/index.d.ts +103 -0
- package/dist/types/interfaces.d.ts +36 -0
- package/dist/types/wavtools/lib/analysis/audio_analysis.d.ts +69 -0
- package/dist/types/wavtools/lib/analysis/constants.d.ts +8 -0
- package/dist/types/wavtools/lib/wav_packer.d.ts +57 -0
- package/package.json +5 -1
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interface for LayercodeClient constructor options
|
|
3
|
+
*/
|
|
4
|
+
interface LayercodeClientOptions {
|
|
5
|
+
/** The ID of the Layercode pipeline to connect to */
|
|
6
|
+
pipelineId: string;
|
|
7
|
+
/** The ID of the session to connect to */
|
|
8
|
+
sessionId?: string | null;
|
|
9
|
+
/** The endpoint URL for the audio agent API */
|
|
10
|
+
authorizeSessionEndpoint: string;
|
|
11
|
+
/** Metadata to send with webhooks */
|
|
12
|
+
metadata?: Record<string, any>;
|
|
13
|
+
/** Enable/disable voice activity detector (VAD) which improves turn taking */
|
|
14
|
+
vadEnabled?: boolean;
|
|
15
|
+
/** Callback when connection is established */
|
|
16
|
+
onConnect?: ({ sessionId }: {
|
|
17
|
+
sessionId: string | null;
|
|
18
|
+
}) => void;
|
|
19
|
+
/** Callback when connection is closed */
|
|
20
|
+
onDisconnect?: () => void;
|
|
21
|
+
/** Callback when an error occurs */
|
|
22
|
+
onError?: (error: Error) => void;
|
|
23
|
+
/** Callback for data messages */
|
|
24
|
+
onDataMessage?: (message: any) => void;
|
|
25
|
+
/** Callback for user audio amplitude changes */
|
|
26
|
+
onUserAmplitudeChange?: (amplitude: number) => void;
|
|
27
|
+
/** Callback for agent audio amplitude changes */
|
|
28
|
+
onAgentAmplitudeChange?: (amplitude: number) => void;
|
|
29
|
+
/** Callback when connection status changes */
|
|
30
|
+
onStatusChange?: (status: string) => void;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* @class LayercodeClient
|
|
34
|
+
* @classdesc Core client for Layercode audio pipeline that manages audio recording, WebSocket communication, and speech processing.
|
|
35
|
+
*/
|
|
36
|
+
declare class LayercodeClient {
|
|
37
|
+
private options;
|
|
38
|
+
private wavRecorder;
|
|
39
|
+
private wavPlayer;
|
|
40
|
+
private vad;
|
|
41
|
+
private ws;
|
|
42
|
+
private AMPLITUDE_MONITORING_SAMPLE_RATE;
|
|
43
|
+
private pushToTalkActive;
|
|
44
|
+
private vadPausedPlayer;
|
|
45
|
+
_websocketUrl: string;
|
|
46
|
+
status: string;
|
|
47
|
+
userAudioAmplitude: number;
|
|
48
|
+
agentAudioAmplitude: number;
|
|
49
|
+
sessionId: string | null;
|
|
50
|
+
/**
|
|
51
|
+
* Creates an instance of LayercodeClient.
|
|
52
|
+
* @param {Object} options - Configuration options
|
|
53
|
+
*/
|
|
54
|
+
constructor(options: LayercodeClientOptions);
|
|
55
|
+
/**
|
|
56
|
+
* Updates the connection status and triggers the callback
|
|
57
|
+
* @param {string} status - New status value
|
|
58
|
+
* @private
|
|
59
|
+
*/
|
|
60
|
+
private _setStatus;
|
|
61
|
+
/**
|
|
62
|
+
* Handles when agent audio finishes playing
|
|
63
|
+
* @private
|
|
64
|
+
*/
|
|
65
|
+
private _clientResponseAudioReplayFinished;
|
|
66
|
+
private _clientInterruptAssistantReplay;
|
|
67
|
+
triggerUserTurnStarted(): Promise<void>;
|
|
68
|
+
triggerUserTurnFinished(): Promise<void>;
|
|
69
|
+
/**
|
|
70
|
+
* Handles incoming WebSocket messages
|
|
71
|
+
* @param {MessageEvent} event - The WebSocket message event
|
|
72
|
+
* @private
|
|
73
|
+
*/
|
|
74
|
+
private _handleWebSocketMessage;
|
|
75
|
+
/**
|
|
76
|
+
* Handles available client browser microphone audio data and sends it over the WebSocket
|
|
77
|
+
* @param {ArrayBuffer} data - The audio data buffer
|
|
78
|
+
* @private
|
|
79
|
+
*/
|
|
80
|
+
private _handleDataAvailable;
|
|
81
|
+
private _wsSend;
|
|
82
|
+
/**
|
|
83
|
+
* Sets up amplitude monitoring for a given audio source.
|
|
84
|
+
* @param {WavRecorder | WavStreamPlayer} source - The audio source (recorder or player).
|
|
85
|
+
* @param {(amplitude: number) => void} callback - The callback function to invoke on amplitude change.
|
|
86
|
+
* @param {(amplitude: number) => void} updateInternalState - Function to update the internal amplitude state.
|
|
87
|
+
* @private
|
|
88
|
+
*/
|
|
89
|
+
private _setupAmplitudeMonitoring;
|
|
90
|
+
/**
|
|
91
|
+
* Connects to the Layercode pipeline and starts the audio session
|
|
92
|
+
* @async
|
|
93
|
+
* @returns {Promise<void>}
|
|
94
|
+
*/
|
|
95
|
+
connect(): Promise<void>;
|
|
96
|
+
disconnect(): Promise<void>;
|
|
97
|
+
/**
|
|
98
|
+
* Gets the microphone MediaStream used by this client
|
|
99
|
+
* @returns {MediaStream|null} The microphone stream or null if not initialized
|
|
100
|
+
*/
|
|
101
|
+
getStream(): MediaStream | null;
|
|
102
|
+
}
|
|
103
|
+
export default LayercodeClient;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export type LayercodeMessageType = 'client.audio' | 'trigger.turn.start' | 'trigger.turn.end' | 'trigger.response.audio.replay_finished' | 'turn.start' | 'turn.end' | 'response.audio' | 'response.data';
|
|
2
|
+
export interface BaseLayercodeMessage {
|
|
3
|
+
type: LayercodeMessageType;
|
|
4
|
+
event_id?: string;
|
|
5
|
+
}
|
|
6
|
+
export interface ClientAudioMessage extends BaseLayercodeMessage {
|
|
7
|
+
type: 'client.audio';
|
|
8
|
+
content: string;
|
|
9
|
+
}
|
|
10
|
+
export interface ClientTriggerTurnMessage extends BaseLayercodeMessage {
|
|
11
|
+
type: 'trigger.turn.start' | 'trigger.turn.end';
|
|
12
|
+
role: 'user';
|
|
13
|
+
}
|
|
14
|
+
export interface ClientTriggerResponseAudioReplayFinishedMessage extends BaseLayercodeMessage {
|
|
15
|
+
type: 'trigger.response.audio.replay_finished';
|
|
16
|
+
reason: 'completed' | 'interrupted';
|
|
17
|
+
last_delta_id_played?: string;
|
|
18
|
+
}
|
|
19
|
+
export interface ServerTurnMessage extends BaseLayercodeMessage {
|
|
20
|
+
type: 'turn.start' | 'turn.end';
|
|
21
|
+
role: 'user' | 'assistant';
|
|
22
|
+
}
|
|
23
|
+
export interface ServerResponseAudioMessage extends BaseLayercodeMessage {
|
|
24
|
+
type: 'response.audio';
|
|
25
|
+
content: string;
|
|
26
|
+
delta_id?: string;
|
|
27
|
+
turn_id: string;
|
|
28
|
+
}
|
|
29
|
+
export interface ServerResponseDataMessage extends BaseLayercodeMessage {
|
|
30
|
+
type: 'response.data';
|
|
31
|
+
content: any;
|
|
32
|
+
turn_id: string;
|
|
33
|
+
}
|
|
34
|
+
export type ServerMessage = ServerTurnMessage | ServerResponseAudioMessage | ServerResponseDataMessage;
|
|
35
|
+
export type ClientMessage = ClientAudioMessage | ClientTriggerTurnMessage | ClientTriggerResponseAudioReplayFinishedMessage;
|
|
36
|
+
export type LayercodeMessage = ClientMessage | ServerMessage;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Output of AudioAnalysis for the frequency domain of the audio
|
|
3
|
+
* @typedef {Object} AudioAnalysisOutputType
|
|
4
|
+
* @property {Float32Array} values Amplitude of this frequency between {0, 1} inclusive
|
|
5
|
+
* @property {number[]} frequencies Raw frequency bucket values
|
|
6
|
+
* @property {string[]} labels Labels for the frequency bucket values
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Analyzes audio for visual output
|
|
10
|
+
* @class
|
|
11
|
+
*/
|
|
12
|
+
export class AudioAnalysis {
|
|
13
|
+
/**
|
|
14
|
+
* Retrieves frequency domain data from an AnalyserNode adjusted to a decibel range
|
|
15
|
+
* returns human-readable formatting and labels
|
|
16
|
+
* @param {AnalyserNode} analyser
|
|
17
|
+
* @param {number} sampleRate
|
|
18
|
+
* @param {Float32Array} [fftResult]
|
|
19
|
+
* @param {"frequency"|"music"|"voice"} [analysisType]
|
|
20
|
+
* @param {number} [minDecibels] default -100
|
|
21
|
+
* @param {number} [maxDecibels] default -30
|
|
22
|
+
* @returns {AudioAnalysisOutputType}
|
|
23
|
+
*/
|
|
24
|
+
static getFrequencies(analyser: AnalyserNode, sampleRate: number, fftResult?: Float32Array, analysisType?: "frequency" | "music" | "voice", minDecibels?: number, maxDecibels?: number): AudioAnalysisOutputType;
|
|
25
|
+
/**
|
|
26
|
+
* Creates a new AudioAnalysis instance for an HTMLAudioElement
|
|
27
|
+
* @param {HTMLAudioElement} audioElement
|
|
28
|
+
* @param {AudioBuffer|null} [audioBuffer] If provided, will cache all frequency domain data from the buffer
|
|
29
|
+
* @returns {AudioAnalysis}
|
|
30
|
+
*/
|
|
31
|
+
constructor(audioElement: HTMLAudioElement, audioBuffer?: AudioBuffer | null);
|
|
32
|
+
fftResults: any[];
|
|
33
|
+
audio: HTMLAudioElement;
|
|
34
|
+
context: OfflineAudioContext | AudioContext;
|
|
35
|
+
analyser: AnalyserNode;
|
|
36
|
+
sampleRate: number;
|
|
37
|
+
audioBuffer: AudioBuffer | null;
|
|
38
|
+
/**
|
|
39
|
+
* Gets the current frequency domain data from the playing audio track
|
|
40
|
+
* @param {"frequency"|"music"|"voice"} [analysisType]
|
|
41
|
+
* @param {number} [minDecibels] default -100
|
|
42
|
+
* @param {number} [maxDecibels] default -30
|
|
43
|
+
* @returns {AudioAnalysisOutputType}
|
|
44
|
+
*/
|
|
45
|
+
getFrequencies(analysisType?: "frequency" | "music" | "voice", minDecibels?: number, maxDecibels?: number): AudioAnalysisOutputType;
|
|
46
|
+
/**
|
|
47
|
+
* Resume the internal AudioContext if it was suspended due to the lack of
|
|
48
|
+
* user interaction when the AudioAnalysis was instantiated.
|
|
49
|
+
* @returns {Promise<true>}
|
|
50
|
+
*/
|
|
51
|
+
resumeIfSuspended(): Promise<true>;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Output of AudioAnalysis for the frequency domain of the audio
|
|
55
|
+
*/
|
|
56
|
+
export type AudioAnalysisOutputType = {
|
|
57
|
+
/**
|
|
58
|
+
* Amplitude of this frequency between {0, 1} inclusive
|
|
59
|
+
*/
|
|
60
|
+
values: Float32Array;
|
|
61
|
+
/**
|
|
62
|
+
* Raw frequency bucket values
|
|
63
|
+
*/
|
|
64
|
+
frequencies: number[];
|
|
65
|
+
/**
|
|
66
|
+
* Labels for the frequency bucket values
|
|
67
|
+
*/
|
|
68
|
+
labels: string[];
|
|
69
|
+
};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Raw wav audio file contents
|
|
3
|
+
* @typedef {Object} WavPackerAudioType
|
|
4
|
+
* @property {Blob} blob
|
|
5
|
+
* @property {string} url
|
|
6
|
+
* @property {number} channelCount
|
|
7
|
+
* @property {number} sampleRate
|
|
8
|
+
* @property {number} duration
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Utility class for assembling PCM16 "audio/wav" data
|
|
12
|
+
* @class
|
|
13
|
+
*/
|
|
14
|
+
export class WavPacker {
|
|
15
|
+
/**
|
|
16
|
+
* Converts Float32Array of amplitude data to ArrayBuffer in Int16Array format
|
|
17
|
+
* @param {Float32Array} float32Array
|
|
18
|
+
* @returns {ArrayBuffer}
|
|
19
|
+
*/
|
|
20
|
+
static floatTo16BitPCM(float32Array: Float32Array): ArrayBuffer;
|
|
21
|
+
/**
|
|
22
|
+
* Concatenates two ArrayBuffers
|
|
23
|
+
* @param {ArrayBuffer} leftBuffer
|
|
24
|
+
* @param {ArrayBuffer} rightBuffer
|
|
25
|
+
* @returns {ArrayBuffer}
|
|
26
|
+
*/
|
|
27
|
+
static mergeBuffers(leftBuffer: ArrayBuffer, rightBuffer: ArrayBuffer): ArrayBuffer;
|
|
28
|
+
/**
|
|
29
|
+
* Packs data into an Int16 format
|
|
30
|
+
* @private
|
|
31
|
+
* @param {number} size 0 = 1x Int16, 1 = 2x Int16
|
|
32
|
+
* @param {number} arg value to pack
|
|
33
|
+
* @returns
|
|
34
|
+
*/
|
|
35
|
+
private _packData;
|
|
36
|
+
/**
|
|
37
|
+
* Packs audio into "audio/wav" Blob
|
|
38
|
+
* @param {number} sampleRate
|
|
39
|
+
* @param {{bitsPerSample: number, channels: Array<Float32Array>, data: Int16Array}} audio
|
|
40
|
+
* @returns {WavPackerAudioType}
|
|
41
|
+
*/
|
|
42
|
+
pack(sampleRate: number, audio: {
|
|
43
|
+
bitsPerSample: number;
|
|
44
|
+
channels: Array<Float32Array>;
|
|
45
|
+
data: Int16Array;
|
|
46
|
+
}): WavPackerAudioType;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Raw wav audio file contents
|
|
50
|
+
*/
|
|
51
|
+
export type WavPackerAudioType = {
|
|
52
|
+
blob: Blob;
|
|
53
|
+
url: string;
|
|
54
|
+
channelCount: number;
|
|
55
|
+
sampleRate: number;
|
|
56
|
+
duration: number;
|
|
57
|
+
};
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"author": "Layercode",
|
|
3
3
|
"license": "MIT",
|
|
4
4
|
"name": "@layercode/js-sdk",
|
|
5
|
-
"version": "1.0.
|
|
5
|
+
"version": "1.0.13",
|
|
6
6
|
"description": "Layercode JavaScript SDK for browser usage",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"main": "dist/layercode-js-sdk.esm.js",
|
|
@@ -42,5 +42,9 @@
|
|
|
42
42
|
"rollup": "^4.0.0",
|
|
43
43
|
"tslib": "^2.5.0",
|
|
44
44
|
"typescript": "^5.8.2"
|
|
45
|
+
},
|
|
46
|
+
"dependencies": {
|
|
47
|
+
"@ricky0123/vad-web": "^0.0.24",
|
|
48
|
+
"onnxruntime-web": "^1.21.1"
|
|
45
49
|
}
|
|
46
50
|
}
|