@vogent/vogent-web-client 0.0.3 → 0.0.5
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/VogentCall.ts +114 -16
- package/devices/VogentDevice.ts +47 -10
- package/devices/VonageDevice.ts +2 -2
- package/package.json +1 -1
package/VogentCall.ts
CHANGED
|
@@ -1,3 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview VogentCall provides the main interface for managing voice calls with Vogent's AI system.
|
|
3
|
+
*
|
|
4
|
+
* This class handles:
|
|
5
|
+
* - Call lifecycle management (start, pause, hangup)
|
|
6
|
+
* - Audio connection setup
|
|
7
|
+
* - Real-time transcript monitoring
|
|
8
|
+
* - Status event handling
|
|
9
|
+
*
|
|
10
|
+
* Basic usage:
|
|
11
|
+
* ```typescript
|
|
12
|
+
* const call = new VogentCall({
|
|
13
|
+
* sessionId: "session_id",
|
|
14
|
+
* dialId: "dial_id",
|
|
15
|
+
* token: "auth_token"
|
|
16
|
+
* });
|
|
17
|
+
*
|
|
18
|
+
* // Start the call
|
|
19
|
+
* await call.start();
|
|
20
|
+
*
|
|
21
|
+
* // Connect audio
|
|
22
|
+
* const audioConn = await call.connectAudio();
|
|
23
|
+
*
|
|
24
|
+
* // Monitor transcripts
|
|
25
|
+
* const unsubscribe = call.monitorTranscript((transcript) => {
|
|
26
|
+
* console.log(transcript);
|
|
27
|
+
* });
|
|
28
|
+
*
|
|
29
|
+
* // Monitor status changes
|
|
30
|
+
* call.on('status', (status) => {
|
|
31
|
+
* console.log('Call status:', status);
|
|
32
|
+
* });
|
|
33
|
+
*
|
|
34
|
+
* // Later: cleanup
|
|
35
|
+
* unsubscribe();
|
|
36
|
+
* await call.hangup();
|
|
37
|
+
* ```
|
|
38
|
+
*
|
|
39
|
+
* @see {@link https://docs.vogent.ai} for complete server documentation
|
|
40
|
+
* @module VogentCall
|
|
41
|
+
*/
|
|
42
|
+
|
|
1
43
|
import { ApolloClient, createHttpLink, InMemoryCache, NormalizedCacheObject, split } from '@apollo/client';
|
|
2
44
|
import { setContext } from '@apollo/client/link/context';
|
|
3
45
|
import { GraphQLWsLink } from '@apollo/client/link/subscriptions';
|
|
@@ -17,27 +59,54 @@ import {
|
|
|
17
59
|
REFRESH_TRANSCRIPT,
|
|
18
60
|
} from './queries';
|
|
19
61
|
import { createClient } from 'graphql-ws';
|
|
20
|
-
import { VogentDevice } from './devices/VogentDevice';
|
|
62
|
+
import { VogentAudioConn, VogentDevice } from './devices/VogentDevice';
|
|
21
63
|
import { VonageDevice } from './devices/VonageDevice';
|
|
22
64
|
import { dialStatusIsComplete } from './utils';
|
|
23
65
|
|
|
24
66
|
export type Transcript = {
|
|
67
|
+
/** The text of the transcript */
|
|
25
68
|
text: string;
|
|
69
|
+
/** The speaker of the transcript currently either 'HUMAN' or 'AI', or 'IVR' if IVR detection is enabled */
|
|
26
70
|
speaker: string;
|
|
27
71
|
}[]
|
|
28
72
|
|
|
73
|
+
/**
|
|
74
|
+
* VogentCall manages the lifecycle and state of a voice call session
|
|
75
|
+
*/
|
|
29
76
|
export class VogentCall {
|
|
30
|
-
client
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
77
|
+
/** Apollo GraphQL client instance for API communication */
|
|
78
|
+
private client: ApolloClient<NormalizedCacheObject>;
|
|
79
|
+
|
|
80
|
+
/** Unique identifier for the current session */
|
|
81
|
+
private sessionId: string;
|
|
82
|
+
|
|
83
|
+
/** Unique identifier for the current dial/call */
|
|
84
|
+
private dialId: string;
|
|
85
|
+
|
|
86
|
+
/** GraphQL subscription handle */
|
|
87
|
+
private subscription?: ObservableSubscription;
|
|
88
|
+
|
|
89
|
+
/** Base URL for the API endpoints */
|
|
90
|
+
private baseUrl: string;
|
|
91
|
+
|
|
92
|
+
/** Current dial/call state */
|
|
93
|
+
private dial?: Dial;
|
|
94
|
+
|
|
95
|
+
/** Array of event handlers for status changes */
|
|
96
|
+
private _handlers: {
|
|
37
97
|
ev: 'status';
|
|
38
98
|
fn: (...args: any[]) => void;
|
|
39
99
|
}[];
|
|
40
100
|
|
|
101
|
+
/**
|
|
102
|
+
* Creates a new VogentCall instance
|
|
103
|
+
* @param dialDetails - Object containing session details and authentication, retrieved from the Vogent server API
|
|
104
|
+
* @param dialDetails.sessionId - Unique session identifier
|
|
105
|
+
* @param dialDetails.dialId - Unique dial/call identifier
|
|
106
|
+
* @param dialDetails.token - Authentication token
|
|
107
|
+
* @param config - Configuration options
|
|
108
|
+
* @param config.baseUrl - API base URL (defaults to 'https://api.getelto.com')
|
|
109
|
+
*/
|
|
41
110
|
constructor(dialDetails: {
|
|
42
111
|
sessionId: string;
|
|
43
112
|
dialId: string;
|
|
@@ -97,6 +166,12 @@ export class VogentCall {
|
|
|
97
166
|
});
|
|
98
167
|
}
|
|
99
168
|
|
|
169
|
+
/**
|
|
170
|
+
* Registers an event handler for status changes
|
|
171
|
+
* @param ev - Event type ('status')
|
|
172
|
+
* - status: called when the dial status changes, see docs.vogent.ai for more details
|
|
173
|
+
* @param fn - Callback function to handle the event
|
|
174
|
+
*/
|
|
100
175
|
on(ev: 'status', fn: (...args: any[]) => void) {
|
|
101
176
|
this._handlers.push({
|
|
102
177
|
ev,
|
|
@@ -104,6 +179,11 @@ export class VogentCall {
|
|
|
104
179
|
});
|
|
105
180
|
}
|
|
106
181
|
|
|
182
|
+
/**
|
|
183
|
+
* Subscribes to transcript updates for the current call
|
|
184
|
+
* @param fn - Callback function that receives transcript updates
|
|
185
|
+
* @returns Function to unsubscribe from transcript updates
|
|
186
|
+
*/
|
|
107
187
|
monitorTranscript(fn: (transcript: Transcript) => void): () => void {
|
|
108
188
|
const subscription = this.client
|
|
109
189
|
.subscribe({
|
|
@@ -130,7 +210,11 @@ export class VogentCall {
|
|
|
130
210
|
}
|
|
131
211
|
}
|
|
132
212
|
|
|
133
|
-
|
|
213
|
+
/**
|
|
214
|
+
* Internal method to update dial state and trigger status handlers
|
|
215
|
+
* @param dial - Updated dial information
|
|
216
|
+
*/
|
|
217
|
+
private updateDial(dial: Dial) {
|
|
134
218
|
if (!this.dial || dial.status !== this.dial.status) {
|
|
135
219
|
this._handlers.forEach((h) => {
|
|
136
220
|
h.fn(dial.status);
|
|
@@ -149,7 +233,13 @@ export class VogentCall {
|
|
|
149
233
|
};
|
|
150
234
|
}
|
|
151
235
|
|
|
152
|
-
|
|
236
|
+
/**
|
|
237
|
+
* Establishes audio connection for the call
|
|
238
|
+
* @param liveListen - Whether to enable live listening mode. This should be set to true for monitoring legs (e.g. humans that are listening
|
|
239
|
+
* to the call who the AI should not interact with.)
|
|
240
|
+
* @returns Promise resolving to audio connection handle
|
|
241
|
+
*/
|
|
242
|
+
async connectAudio(liveListen: boolean = false): Promise<VogentAudioConn> {
|
|
153
243
|
const token = await this.client.mutate({
|
|
154
244
|
mutation: AI_GET_TOKEN,
|
|
155
245
|
variables: {
|
|
@@ -163,11 +253,16 @@ export class VogentCall {
|
|
|
163
253
|
const d: VogentDevice = await VonageDevice.getDevice(token.data!.browserDialToken.token, true);
|
|
164
254
|
|
|
165
255
|
const c = await d.connect({
|
|
166
|
-
params: { EltoDialSessionID: this.sessionId, LiveListen: liveListen },
|
|
256
|
+
params: { EltoDialSessionID: this.sessionId, LiveListen: liveListen, DialID: this.dialId },
|
|
167
257
|
});
|
|
258
|
+
|
|
259
|
+
return c;
|
|
168
260
|
}
|
|
169
261
|
|
|
170
|
-
|
|
262
|
+
/**
|
|
263
|
+
* Starts the call session. Does not connect audio, you must call connectAudio() to do so.
|
|
264
|
+
*/
|
|
265
|
+
async start() {
|
|
171
266
|
this.subscription = this.client
|
|
172
267
|
.subscribe({
|
|
173
268
|
query: AI_CONNECT_SESSION,
|
|
@@ -196,12 +291,12 @@ export class VogentCall {
|
|
|
196
291
|
}
|
|
197
292
|
}
|
|
198
293
|
});
|
|
199
|
-
|
|
200
|
-
if (!disableAudio) {
|
|
201
|
-
await this.connectAudio();
|
|
202
|
-
}
|
|
203
294
|
}
|
|
204
295
|
|
|
296
|
+
/**
|
|
297
|
+
* Sets the pause state of the AI
|
|
298
|
+
* @param paused - Whether to pause the AI or not.
|
|
299
|
+
*/
|
|
205
300
|
async setPaused(paused: boolean) {
|
|
206
301
|
if (!this.dial) {
|
|
207
302
|
return;
|
|
@@ -216,6 +311,9 @@ export class VogentCall {
|
|
|
216
311
|
});
|
|
217
312
|
}
|
|
218
313
|
|
|
314
|
+
/**
|
|
315
|
+
* Ends the current call
|
|
316
|
+
*/
|
|
219
317
|
async hangup() {
|
|
220
318
|
if (!this.dial) {
|
|
221
319
|
return;
|
package/devices/VogentDevice.ts
CHANGED
|
@@ -1,12 +1,49 @@
|
|
|
1
1
|
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Interface representing an active audio connection to a Vogent call.
|
|
5
|
+
* Returned by VogentCall.connectAudio()
|
|
6
|
+
*/
|
|
7
|
+
export interface VogentAudioConn {
|
|
8
|
+
/**
|
|
9
|
+
* Register event handlers for connection events
|
|
10
|
+
* @param ev - Event type to listen for
|
|
11
|
+
* - 'mute': Fired when the connection's mute state changes
|
|
12
|
+
* - 'disconnect': Fired when the connection is terminated
|
|
13
|
+
* @param fn - Callback function to handle the event
|
|
14
|
+
*/
|
|
15
|
+
on: (ev: 'mute' | 'disconnect', fn: (...args: any[]) => void) => void;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Mute or unmute the audio connection
|
|
19
|
+
* @param status - True to mute, false to unmute
|
|
20
|
+
*/
|
|
21
|
+
mute: (status: boolean) => void;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Terminate the audio connection
|
|
25
|
+
*/
|
|
26
|
+
disconnect: () => void;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Send DTMF digits through the connection
|
|
30
|
+
* @param k - String of DTMF digits to send (0-9, *, #)
|
|
31
|
+
*/
|
|
32
|
+
sendDigits: (k: string) => void;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Interface representing a device that can establish audio connections
|
|
37
|
+
* Currently implemented by VonageDevice
|
|
38
|
+
*/
|
|
39
|
+
export interface VogentDevice {
|
|
40
|
+
/**
|
|
41
|
+
* Establish an audio connection with the specified parameters
|
|
42
|
+
* @param p - Connection parameters object containing:
|
|
43
|
+
* - params.EltoDialSessionID: The session ID for the call
|
|
44
|
+
* - params.LiveListen: Whether this is a monitoring connection
|
|
45
|
+
* - params.DialID: The ID of the dial to connect to
|
|
46
|
+
* @returns Promise resolving to an active audio connection
|
|
47
|
+
*/
|
|
48
|
+
connect: (p: any) => Promise<VogentAudioConn>;
|
|
49
|
+
}
|
package/devices/VonageDevice.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { VogentAudioConn } from './VogentDevice';
|
|
2
2
|
import { VonageClient, LoggingLevel } from '@vonage/client-sdk';
|
|
3
3
|
|
|
4
4
|
export class VonageCall {
|
|
@@ -95,7 +95,7 @@ export class VonageDevice {
|
|
|
95
95
|
return new VonageDevice(sessId, client, disableEffects);
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
-
async connect(p: any): Promise<
|
|
98
|
+
async connect(p: any): Promise<VogentAudioConn> {
|
|
99
99
|
const call = await this._client.serverCall(p.params);
|
|
100
100
|
const v = new VonageCall(call, this._client, p.params);
|
|
101
101
|
return v;
|