@unboundcx/sdk 4.0.10 → 4.0.12
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/package.json +1 -1
- package/proto/transcription.proto +52 -10
- package/services/ai/SttStream.js +18 -0
- package/services/ai.js +57 -0
- package/services/googleCalendar.js +24 -5
- package/services/video.js +266 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@unboundcx/sdk",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.12",
|
|
4
4
|
"description": "Official JavaScript SDK for the Unbound API - A comprehensive toolkit for integrating with Unbound's communication, AI, and data management services",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -28,7 +28,7 @@ message AudioRequest {
|
|
|
28
28
|
string language = 4;
|
|
29
29
|
|
|
30
30
|
// Transcription engine to use
|
|
31
|
-
// Options: "whisper", "google"
|
|
31
|
+
// Options: "whisper", "google", "groq"
|
|
32
32
|
string engine = 5;
|
|
33
33
|
|
|
34
34
|
// Audio configuration
|
|
@@ -66,28 +66,48 @@ message AudioRequest {
|
|
|
66
66
|
// VAD event timestamp
|
|
67
67
|
int64 vad_timestamp = 15;
|
|
68
68
|
|
|
69
|
-
//
|
|
69
|
+
// Optional playbook ID for real-time agent scoring
|
|
70
70
|
string playbook_id = 16;
|
|
71
71
|
|
|
72
|
-
// Bridge
|
|
73
|
-
//
|
|
74
|
-
// bridge_id lets the transcription service correlate them
|
|
72
|
+
// Bridge ID linking related transcription streams (e.g., both legs of a bridged call)
|
|
73
|
+
// Empty string = not part of any bridge. Dynamic: can appear, change, or disappear mid-stream.
|
|
75
74
|
string bridge_id = 17;
|
|
76
75
|
|
|
77
|
-
//
|
|
76
|
+
// Optional task ID for playbook session tracking
|
|
78
77
|
string task_id = 18;
|
|
79
78
|
|
|
80
|
-
//
|
|
79
|
+
// Optional worker ID for playbook session tracking
|
|
81
80
|
string worker_id = 19;
|
|
82
81
|
|
|
83
|
-
//
|
|
82
|
+
// Enable real-time subject generation from customer transcripts
|
|
83
|
+
// Requires task_id to be set for SDK task update
|
|
84
84
|
bool generate_subject = 20;
|
|
85
85
|
|
|
86
|
-
//
|
|
86
|
+
// Enable end-of-call transcript summary generation
|
|
87
|
+
// Requires task_id to be set for SDK task update
|
|
87
88
|
bool generate_transcript_summary = 21;
|
|
88
89
|
|
|
89
|
-
//
|
|
90
|
+
// Enable real-time sentiment analysis with multi-signal fusion
|
|
91
|
+
// Requires task_id to be set for SDK task update
|
|
90
92
|
bool generate_sentiment = 22;
|
|
93
|
+
|
|
94
|
+
// ── Meet (video-room) session metadata — additive, optional ──────────────
|
|
95
|
+
// Video room ID this stream belongs to (Meet sessions only). Also used as
|
|
96
|
+
// the conversation identifier for Meet sessions.
|
|
97
|
+
string video_room_id = 23;
|
|
98
|
+
|
|
99
|
+
// Video room participant ID (Meet sessions only)
|
|
100
|
+
string participant_id = 24;
|
|
101
|
+
|
|
102
|
+
// Display name of the participant (Meet sessions only)
|
|
103
|
+
string display_name = 25;
|
|
104
|
+
|
|
105
|
+
// Opt-in server-side VAD: when true, this repo runs its own energy-based
|
|
106
|
+
// silence detector over incoming PCM chunks and injects synthetic
|
|
107
|
+
// speaking_started/speaking_stopped vad_events (media-manager-parity
|
|
108
|
+
// SilenceDetector), instead of relying on client-sent vad_event fields.
|
|
109
|
+
// Defaults to false/unset: existing (non-Meet) callers are unaffected.
|
|
110
|
+
bool server_vad = 26;
|
|
91
111
|
}
|
|
92
112
|
|
|
93
113
|
// Audio configuration
|
|
@@ -156,6 +176,28 @@ message TranscriptResponse {
|
|
|
156
176
|
|
|
157
177
|
// Speaker role (echoed back from AudioRequest)
|
|
158
178
|
string role = 11;
|
|
179
|
+
|
|
180
|
+
// Sentiment score (-100 to +100, 0 if sentiment not enabled)
|
|
181
|
+
float sentiment_score = 12;
|
|
182
|
+
|
|
183
|
+
// Sentiment trend ('improving', 'stable', 'declining', empty if not enabled)
|
|
184
|
+
string sentiment_trend = 13;
|
|
185
|
+
|
|
186
|
+
// Unique message ID for correlating transcript with its sentiment update
|
|
187
|
+
string message_id = 14;
|
|
188
|
+
|
|
189
|
+
// Whether this message is a sentiment enrichment update (not a new transcript)
|
|
190
|
+
bool is_sentiment_update = 15;
|
|
191
|
+
|
|
192
|
+
// ── Meet (video-room) session metadata — additive, optional, echoed back ─
|
|
193
|
+
// Video room ID (echoed back from AudioRequest, Meet sessions only)
|
|
194
|
+
string video_room_id = 16;
|
|
195
|
+
|
|
196
|
+
// Video room participant ID (echoed back from AudioRequest, Meet sessions only)
|
|
197
|
+
string participant_id = 17;
|
|
198
|
+
|
|
199
|
+
// Display name of the participant (echoed back from AudioRequest, Meet sessions only)
|
|
200
|
+
string display_name = 18;
|
|
159
201
|
}
|
|
160
202
|
|
|
161
203
|
// Word-level information
|
package/services/ai/SttStream.js
CHANGED
|
@@ -118,6 +118,10 @@ export class SttStream extends EventEmitter {
|
|
|
118
118
|
// sipCallId: string, // NEW
|
|
119
119
|
// side: string, // NEW
|
|
120
120
|
// role: string // NEW
|
|
121
|
+
// videoRoomId: string, // NEW (meet sessions only, else '')
|
|
122
|
+
// participantId: string, // NEW (meet sessions only, else '')
|
|
123
|
+
// displayName: string, // NEW (meet sessions only, else '')
|
|
124
|
+
// messageId: string // NEW (proto field 14)
|
|
121
125
|
// }
|
|
122
126
|
|
|
123
127
|
if (response.transcript) {
|
|
@@ -134,6 +138,11 @@ export class SttStream extends EventEmitter {
|
|
|
134
138
|
sipCallId: response.sipCallId || response.sip_call_id || '',
|
|
135
139
|
side: response.side || '',
|
|
136
140
|
role: response.role || '',
|
|
141
|
+
// Meet (video-room) session metadata (NEW, additive, '' when not a meet session)
|
|
142
|
+
videoRoomId: response.videoRoomId || response.video_room_id || '',
|
|
143
|
+
participantId: response.participantId || response.participant_id || '',
|
|
144
|
+
displayName: response.displayName || response.display_name || '',
|
|
145
|
+
messageId: response.messageId || response.message_id || '',
|
|
137
146
|
};
|
|
138
147
|
|
|
139
148
|
this.emit('transcript', transcriptData);
|
|
@@ -154,6 +163,10 @@ export class SttStream extends EventEmitter {
|
|
|
154
163
|
* @param {string} streamMetadata.role - Optional speaker role (e.g., 'customer', 'agent', 'system')
|
|
155
164
|
* @param {boolean} streamMetadata.isLastChunk - If true, marks this specific stream as complete
|
|
156
165
|
* @returns {boolean} - True if write successful
|
|
166
|
+
*
|
|
167
|
+
* Meet (video-room) session metadata is not per-chunk — it is sent once in the
|
|
168
|
+
* first-chunk session config, read from stream options: options.videoRoomId,
|
|
169
|
+
* options.participantId, options.displayName, options.serverVad. See constructor.
|
|
157
170
|
*/
|
|
158
171
|
write(audioChunk, streamMetadata = {}) {
|
|
159
172
|
if (this.isClosed) {
|
|
@@ -205,6 +218,11 @@ export class SttStream extends EventEmitter {
|
|
|
205
218
|
generate_transcript_summary: this.options.generateTranscriptSummary || false,
|
|
206
219
|
generate_sentiment: this.options.generateSentiment || false,
|
|
207
220
|
bridge_id: bridgeId,
|
|
221
|
+
// Meet (video-room) session metadata (NEW, additive, optional)
|
|
222
|
+
video_room_id: this.options.videoRoomId || '',
|
|
223
|
+
participant_id: this.options.participantId || '',
|
|
224
|
+
display_name: this.options.displayName || '',
|
|
225
|
+
server_vad: this.options.serverVad || false,
|
|
208
226
|
};
|
|
209
227
|
|
|
210
228
|
this.grpcCall.write(request);
|
package/services/ai.js
CHANGED
|
@@ -224,6 +224,27 @@ export class GenerativeService {
|
|
|
224
224
|
return result;
|
|
225
225
|
}
|
|
226
226
|
|
|
227
|
+
/**
|
|
228
|
+
* Summarize chat/transcript content (running summary, chapters, title)
|
|
229
|
+
* @param {Object} payload
|
|
230
|
+
* @param {string} [payload.domain] - Summary domain (e.g. 'meeting')
|
|
231
|
+
* @param {string} [payload.mode] - Summary mode
|
|
232
|
+
* @param {Array} [payload.lines] - Transcript/chat lines to summarize
|
|
233
|
+
* @param {Array} [payload.chatMessages] - Chat messages to summarize
|
|
234
|
+
* @param {string} [payload.runningSummary] - Existing running summary to extend
|
|
235
|
+
* @param {boolean} [payload.includeChapters] - Include chapter breakdown
|
|
236
|
+
* @param {boolean} [payload.includeTitle] - Include a generated title
|
|
237
|
+
* @returns {Promise<Object>} Summary result
|
|
238
|
+
*/
|
|
239
|
+
async summarize(payload = {}) {
|
|
240
|
+
const params = {
|
|
241
|
+
body: payload,
|
|
242
|
+
};
|
|
243
|
+
|
|
244
|
+
const result = await this.sdk._fetch('/ai/summarize', 'POST', params);
|
|
245
|
+
return result;
|
|
246
|
+
}
|
|
247
|
+
|
|
227
248
|
/**
|
|
228
249
|
* List available chat tools and their metadata
|
|
229
250
|
* @returns {Promise<Object>} { tools: Array<{ name, label, description, configRequirements }>, count: number }
|
|
@@ -611,6 +632,11 @@ export class SpeechToTextService {
|
|
|
611
632
|
* @param {string} [options.playbookId] - Playbook ID
|
|
612
633
|
* @param {string} [options.name] - Session name
|
|
613
634
|
* @param {Object} [options.metadata] - Additional metadata
|
|
635
|
+
* @param {string} [options.videoRoomId] - Video (Meet) room ID this stream belongs to
|
|
636
|
+
* @param {string} [options.videoParticipantId] - Video (Meet) room participant ID
|
|
637
|
+
* @param {string} [options.displayName] - Participant display name (Meet sessions)
|
|
638
|
+
* @param {string} [options.role] - Speaker role (e.g. 'participant', 'host')
|
|
639
|
+
* @param {boolean} [options.serverVad] - Opt-in server-side VAD (Meet sessions; defaults false)
|
|
614
640
|
* @returns {Promise<SttStream>} Stream object with write() method and transcript events
|
|
615
641
|
*
|
|
616
642
|
* @example
|
|
@@ -658,6 +684,11 @@ export class SpeechToTextService {
|
|
|
658
684
|
metadata,
|
|
659
685
|
sipCallId,
|
|
660
686
|
cdrId,
|
|
687
|
+
videoRoomId,
|
|
688
|
+
videoParticipantId,
|
|
689
|
+
displayName,
|
|
690
|
+
role,
|
|
691
|
+
serverVad,
|
|
661
692
|
} = options;
|
|
662
693
|
|
|
663
694
|
// Validate parameters
|
|
@@ -689,6 +720,11 @@ export class SpeechToTextService {
|
|
|
689
720
|
metadata,
|
|
690
721
|
sipCallId,
|
|
691
722
|
cdrId,
|
|
723
|
+
videoRoomId,
|
|
724
|
+
videoParticipantId,
|
|
725
|
+
displayName,
|
|
726
|
+
role,
|
|
727
|
+
serverVad,
|
|
692
728
|
},
|
|
693
729
|
{
|
|
694
730
|
engine: { type: 'string', required: false },
|
|
@@ -717,6 +753,11 @@ export class SpeechToTextService {
|
|
|
717
753
|
metadata: { type: 'object', required: false },
|
|
718
754
|
sipCallId: { type: 'string', required: false },
|
|
719
755
|
cdrId: { type: 'string', required: false },
|
|
756
|
+
videoRoomId: { type: 'string', required: false },
|
|
757
|
+
videoParticipantId: { type: 'string', required: false },
|
|
758
|
+
displayName: { type: 'string', required: false },
|
|
759
|
+
role: { type: 'string', required: false },
|
|
760
|
+
serverVad: { type: 'boolean', required: false },
|
|
720
761
|
},
|
|
721
762
|
);
|
|
722
763
|
|
|
@@ -736,6 +777,10 @@ export class SpeechToTextService {
|
|
|
736
777
|
sipCallId,
|
|
737
778
|
cdrId,
|
|
738
779
|
name,
|
|
780
|
+
videoRoomId,
|
|
781
|
+
videoParticipantId,
|
|
782
|
+
displayName,
|
|
783
|
+
role,
|
|
739
784
|
metadata: {
|
|
740
785
|
...metadata,
|
|
741
786
|
languageCode,
|
|
@@ -773,6 +818,12 @@ export class SpeechToTextService {
|
|
|
773
818
|
vadEnabled,
|
|
774
819
|
minSilenceDuration,
|
|
775
820
|
speechPadMs,
|
|
821
|
+
// SttStream reads these as videoRoomId/participantId/displayName/serverVad
|
|
822
|
+
// for the gRPC first-chunk session config.
|
|
823
|
+
videoRoomId,
|
|
824
|
+
participantId: videoParticipantId,
|
|
825
|
+
displayName,
|
|
826
|
+
serverVad,
|
|
776
827
|
};
|
|
777
828
|
|
|
778
829
|
return new SttStream(this.sdk, session, streamOptions);
|
|
@@ -883,6 +934,8 @@ export class SpeechToTextService {
|
|
|
883
934
|
side,
|
|
884
935
|
bridgeId,
|
|
885
936
|
sentiment,
|
|
937
|
+
videoRoomId,
|
|
938
|
+
videoParticipantId,
|
|
886
939
|
},
|
|
887
940
|
) {
|
|
888
941
|
this.sdk.validateParams(
|
|
@@ -902,6 +955,8 @@ export class SpeechToTextService {
|
|
|
902
955
|
side: { type: 'string', required: false },
|
|
903
956
|
bridgeId: { type: 'string', required: false },
|
|
904
957
|
sentiment: { type: 'object', required: false },
|
|
958
|
+
videoRoomId: { type: 'string', required: false },
|
|
959
|
+
videoParticipantId: { type: 'string', required: false },
|
|
905
960
|
},
|
|
906
961
|
);
|
|
907
962
|
|
|
@@ -920,6 +975,8 @@ export class SpeechToTextService {
|
|
|
920
975
|
side,
|
|
921
976
|
bridgeId,
|
|
922
977
|
sentiment,
|
|
978
|
+
videoRoomId,
|
|
979
|
+
videoParticipantId,
|
|
923
980
|
},
|
|
924
981
|
};
|
|
925
982
|
|
|
@@ -3,19 +3,38 @@ export class GoogleCalendarService {
|
|
|
3
3
|
this.sdk = sdk;
|
|
4
4
|
}
|
|
5
5
|
|
|
6
|
-
async setupWebhook({
|
|
6
|
+
async setupWebhook({
|
|
7
|
+
calendarId,
|
|
8
|
+
eventTypes,
|
|
9
|
+
webhookUrl,
|
|
10
|
+
expirationTime,
|
|
11
|
+
recordTypeId,
|
|
12
|
+
} = {}) {
|
|
13
|
+
// Only calendarId is required. The server derives the webhook URL itself
|
|
14
|
+
// (per-environment: https://login.<API_BASE_URL>/webhooks/google/...) and
|
|
15
|
+
// watches all event types, so eventTypes/webhookUrl are optional. They
|
|
16
|
+
// were previously marked required, which broke the common
|
|
17
|
+
// setupWebhook({ calendarId }) call site (createRoom) with
|
|
18
|
+
// "Missing required parameter eventTypes".
|
|
19
|
+
// recordTypeId is optional: callers (e.g. createRoom) pass the meeting's
|
|
20
|
+
// already-resolved recordTypeId so the webhook row inherits it; if omitted
|
|
21
|
+
// the server resolves a fallback via findRecordTypeId.
|
|
7
22
|
this.sdk.validateParams(
|
|
8
|
-
{ calendarId, eventTypes, webhookUrl },
|
|
23
|
+
{ calendarId, eventTypes, webhookUrl, recordTypeId },
|
|
9
24
|
{
|
|
10
25
|
calendarId: { type: 'string', required: true },
|
|
11
|
-
eventTypes: { type: 'array', required:
|
|
12
|
-
webhookUrl: { type: 'string', required:
|
|
26
|
+
eventTypes: { type: 'array', required: false },
|
|
27
|
+
webhookUrl: { type: 'string', required: false },
|
|
13
28
|
expirationTime: { type: 'number', required: false },
|
|
29
|
+
recordTypeId: { type: 'string', required: false },
|
|
14
30
|
},
|
|
15
31
|
);
|
|
16
32
|
|
|
17
|
-
const webhookData = { calendarId
|
|
33
|
+
const webhookData = { calendarId };
|
|
34
|
+
if (eventTypes) webhookData.eventTypes = eventTypes;
|
|
35
|
+
if (webhookUrl) webhookData.webhookUrl = webhookUrl;
|
|
18
36
|
if (expirationTime) webhookData.expirationTime = expirationTime;
|
|
37
|
+
if (recordTypeId) webhookData.recordTypeId = recordTypeId;
|
|
19
38
|
|
|
20
39
|
const params = {
|
|
21
40
|
body: webhookData,
|
package/services/video.js
CHANGED
|
@@ -221,6 +221,13 @@ export class VideoService {
|
|
|
221
221
|
startMicrophoneMutedAfter,
|
|
222
222
|
enableChat,
|
|
223
223
|
engagementSessionId,
|
|
224
|
+
startRecordingOn,
|
|
225
|
+
startTranscribingOn,
|
|
226
|
+
syncToCalendar,
|
|
227
|
+
source,
|
|
228
|
+
calendarId,
|
|
229
|
+
eventId,
|
|
230
|
+
calendarProvider,
|
|
224
231
|
}) {
|
|
225
232
|
this.sdk.validateParams(
|
|
226
233
|
{
|
|
@@ -241,6 +248,13 @@ export class VideoService {
|
|
|
241
248
|
startMicrophoneMutedAfter,
|
|
242
249
|
enableChat,
|
|
243
250
|
engagementSessionId,
|
|
251
|
+
startRecordingOn,
|
|
252
|
+
startTranscribingOn,
|
|
253
|
+
syncToCalendar,
|
|
254
|
+
source,
|
|
255
|
+
calendarId,
|
|
256
|
+
eventId,
|
|
257
|
+
calendarProvider,
|
|
244
258
|
},
|
|
245
259
|
{
|
|
246
260
|
name: { type: 'string', required: false },
|
|
@@ -260,6 +274,13 @@ export class VideoService {
|
|
|
260
274
|
startMicrophoneMutedAfter: { type: 'number', required: false },
|
|
261
275
|
enableChat: { type: 'boolean', required: false },
|
|
262
276
|
engagementSessionId: { type: 'string', required: false },
|
|
277
|
+
startRecordingOn: { type: 'boolean', required: false },
|
|
278
|
+
startTranscribingOn: { type: 'boolean', required: false },
|
|
279
|
+
syncToCalendar: { type: 'boolean', required: false },
|
|
280
|
+
source: { type: 'string', required: false },
|
|
281
|
+
calendarId: { type: 'string', required: false },
|
|
282
|
+
eventId: { type: 'string', required: false },
|
|
283
|
+
calendarProvider: { type: 'string', required: false },
|
|
263
284
|
},
|
|
264
285
|
);
|
|
265
286
|
const params = {
|
|
@@ -281,6 +302,13 @@ export class VideoService {
|
|
|
281
302
|
startMicrophoneMutedAfter,
|
|
282
303
|
enableChat,
|
|
283
304
|
engagementSessionId,
|
|
305
|
+
startRecordingOn,
|
|
306
|
+
startTranscribingOn,
|
|
307
|
+
syncToCalendar,
|
|
308
|
+
source,
|
|
309
|
+
calendarId,
|
|
310
|
+
eventId,
|
|
311
|
+
calendarProvider,
|
|
284
312
|
},
|
|
285
313
|
};
|
|
286
314
|
const result = await this.sdk._fetch(`/video`, 'POST', params);
|
|
@@ -459,7 +487,7 @@ export class VideoService {
|
|
|
459
487
|
return result;
|
|
460
488
|
}
|
|
461
489
|
|
|
462
|
-
async deleteRoom(roomId) {
|
|
490
|
+
async deleteRoom(roomId, options = {}) {
|
|
463
491
|
this.sdk.validateParams(
|
|
464
492
|
{ roomId },
|
|
465
493
|
{
|
|
@@ -467,6 +495,9 @@ export class VideoService {
|
|
|
467
495
|
},
|
|
468
496
|
);
|
|
469
497
|
const params = {};
|
|
498
|
+
if (options && options.deleteCalendarEvent === true) {
|
|
499
|
+
params.body = { deleteCalendarEvent: true };
|
|
500
|
+
}
|
|
470
501
|
const result = await this.sdk._fetch(`/video/${roomId}`, 'DELETE', params);
|
|
471
502
|
return result;
|
|
472
503
|
}
|
|
@@ -618,6 +649,26 @@ export class VideoService {
|
|
|
618
649
|
return result;
|
|
619
650
|
}
|
|
620
651
|
|
|
652
|
+
// Persist a rolled-up quality summary to MySQL (one row per participant
|
|
653
|
+
// per meeting). Internal endpoint, called by app1-video-server on
|
|
654
|
+
// participant.leave. Long-term home for billing (bytes) and "was this
|
|
655
|
+
// meeting good?" support lookups, surviving ClickHouse TTL expiry.
|
|
656
|
+
async submitParticipantSummary(roomId, participantId, summary) {
|
|
657
|
+
this.sdk.validateParams(
|
|
658
|
+
{ roomId, participantId, summary },
|
|
659
|
+
{
|
|
660
|
+
roomId: { type: 'string', required: true },
|
|
661
|
+
participantId: { type: 'string', required: true },
|
|
662
|
+
summary: { type: 'object', required: true },
|
|
663
|
+
},
|
|
664
|
+
);
|
|
665
|
+
return this.sdk._fetch(
|
|
666
|
+
`/internal/video/${roomId}/participants/${participantId}/summary`,
|
|
667
|
+
'POST',
|
|
668
|
+
{ body: summary },
|
|
669
|
+
);
|
|
670
|
+
}
|
|
671
|
+
|
|
621
672
|
async submitSurvey({
|
|
622
673
|
videoRoomId,
|
|
623
674
|
participantId,
|
|
@@ -749,6 +800,42 @@ export class VideoService {
|
|
|
749
800
|
return result;
|
|
750
801
|
}
|
|
751
802
|
|
|
803
|
+
/**
|
|
804
|
+
* Get the live transcription transcript for a video room, paged.
|
|
805
|
+
* @param {string} roomId - The video room ID
|
|
806
|
+
* @param {Object} [options] - Paging options
|
|
807
|
+
* @param {number} [options.limit] - Max rows to return
|
|
808
|
+
* @param {number} [options.offset] - Row offset
|
|
809
|
+
* @returns {Promise} Paged transcript rows, ordered by timestamp/createdAt ascending
|
|
810
|
+
*/
|
|
811
|
+
async getTranscript(roomId, options = {}) {
|
|
812
|
+
this.sdk.validateParams(
|
|
813
|
+
{ roomId },
|
|
814
|
+
{
|
|
815
|
+
roomId: { type: 'string', required: true },
|
|
816
|
+
},
|
|
817
|
+
);
|
|
818
|
+
|
|
819
|
+
const validationSchema = {};
|
|
820
|
+
if ('limit' in options) validationSchema.limit = { type: 'number' };
|
|
821
|
+
if ('offset' in options) validationSchema.offset = { type: 'number' };
|
|
822
|
+
|
|
823
|
+
if (Object.keys(validationSchema).length > 0) {
|
|
824
|
+
this.sdk.validateParams(options, validationSchema);
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
const params = {
|
|
828
|
+
query: options,
|
|
829
|
+
};
|
|
830
|
+
|
|
831
|
+
const result = await this.sdk._fetch(
|
|
832
|
+
`/video/${roomId}/transcript`,
|
|
833
|
+
'GET',
|
|
834
|
+
params,
|
|
835
|
+
);
|
|
836
|
+
return result;
|
|
837
|
+
}
|
|
838
|
+
|
|
752
839
|
/**
|
|
753
840
|
* Edit a chat message in a video room
|
|
754
841
|
* Only the participant who created the message can edit it
|
|
@@ -943,4 +1030,182 @@ export class VideoService {
|
|
|
943
1030
|
const result = await this.sdk._fetch('/video/settings/user', 'GET', params);
|
|
944
1031
|
return result;
|
|
945
1032
|
}
|
|
1033
|
+
|
|
1034
|
+
/**
|
|
1035
|
+
* Get the AI-generated summary for a video room's transcript
|
|
1036
|
+
* @param {string} roomId - The video room ID
|
|
1037
|
+
* @returns {Promise} Meeting summary
|
|
1038
|
+
*/
|
|
1039
|
+
async getSummary(roomId) {
|
|
1040
|
+
this.sdk.validateParams(
|
|
1041
|
+
{ roomId },
|
|
1042
|
+
{
|
|
1043
|
+
roomId: { type: 'string', required: true },
|
|
1044
|
+
},
|
|
1045
|
+
);
|
|
1046
|
+
|
|
1047
|
+
const result = await this.sdk._fetch(`/video/${roomId}/summary`, 'GET');
|
|
1048
|
+
return result;
|
|
1049
|
+
}
|
|
1050
|
+
|
|
1051
|
+
/**
|
|
1052
|
+
* Host-only edit of a video room's post-meeting AI summary
|
|
1053
|
+
* @param {string} roomId - The video room ID
|
|
1054
|
+
* @param {Object} update
|
|
1055
|
+
* @param {Object} update.summaryJson - {title, summary, actionItems, chapters}
|
|
1056
|
+
* @returns {Promise} Update result
|
|
1057
|
+
*/
|
|
1058
|
+
async updateSummary(roomId, { summaryJson }) {
|
|
1059
|
+
this.sdk.validateParams(
|
|
1060
|
+
{ roomId, summaryJson },
|
|
1061
|
+
{
|
|
1062
|
+
roomId: { type: 'string', required: true },
|
|
1063
|
+
summaryJson: { type: 'object', required: true },
|
|
1064
|
+
},
|
|
1065
|
+
);
|
|
1066
|
+
|
|
1067
|
+
const params = {
|
|
1068
|
+
body: { summaryJson },
|
|
1069
|
+
};
|
|
1070
|
+
|
|
1071
|
+
const result = await this.sdk._fetch(
|
|
1072
|
+
`/video/${roomId}/summary`,
|
|
1073
|
+
'PATCH',
|
|
1074
|
+
params,
|
|
1075
|
+
);
|
|
1076
|
+
return result;
|
|
1077
|
+
}
|
|
1078
|
+
|
|
1079
|
+
/**
|
|
1080
|
+
* Generate a "catch me up" recap of a video room's transcript so far
|
|
1081
|
+
* @param {string} roomId - The video room ID
|
|
1082
|
+
* @returns {Promise} Catch-up summary
|
|
1083
|
+
*/
|
|
1084
|
+
async catchMeUp(roomId) {
|
|
1085
|
+
this.sdk.validateParams(
|
|
1086
|
+
{ roomId },
|
|
1087
|
+
{
|
|
1088
|
+
roomId: { type: 'string', required: true },
|
|
1089
|
+
},
|
|
1090
|
+
);
|
|
1091
|
+
|
|
1092
|
+
const result = await this.sdk._fetch(
|
|
1093
|
+
`/video/${roomId}/catch-me-up`,
|
|
1094
|
+
'POST',
|
|
1095
|
+
{},
|
|
1096
|
+
);
|
|
1097
|
+
return result;
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
/**
|
|
1101
|
+
* Ask the room-scoped AI assistant a question, grounded in the meeting
|
|
1102
|
+
* transcript so far
|
|
1103
|
+
* @param {string} roomId - The video room ID
|
|
1104
|
+
* @param {Object} params
|
|
1105
|
+
* @param {string} params.question - The question to ask
|
|
1106
|
+
* @param {Array<{role: 'user'|'assistant', content: string}>} [params.history] - Prior turns
|
|
1107
|
+
* @returns {Promise} Assistant answer
|
|
1108
|
+
*/
|
|
1109
|
+
async assistantChat(roomId, { question, history } = {}) {
|
|
1110
|
+
this.sdk.validateParams(
|
|
1111
|
+
{ roomId, question },
|
|
1112
|
+
{
|
|
1113
|
+
roomId: { type: 'string', required: true },
|
|
1114
|
+
question: { type: 'string', required: true },
|
|
1115
|
+
},
|
|
1116
|
+
);
|
|
1117
|
+
|
|
1118
|
+
const body = { question };
|
|
1119
|
+
if (history !== undefined) {
|
|
1120
|
+
body.history = history;
|
|
1121
|
+
}
|
|
1122
|
+
|
|
1123
|
+
const result = await this.sdk._fetch(`/video/${roomId}/assistant`, 'POST', {
|
|
1124
|
+
body,
|
|
1125
|
+
});
|
|
1126
|
+
return result;
|
|
1127
|
+
}
|
|
1128
|
+
|
|
1129
|
+
/**
|
|
1130
|
+
* Update the text of a transcript message
|
|
1131
|
+
* @param {string} roomId - The video room ID
|
|
1132
|
+
* @param {string} messageId - The transcript message ID
|
|
1133
|
+
* @param {Object} update
|
|
1134
|
+
* @param {string} update.text - New transcript text
|
|
1135
|
+
* @returns {Promise} Updated transcript message
|
|
1136
|
+
*/
|
|
1137
|
+
async updateTranscriptMessage(roomId, messageId, { text }) {
|
|
1138
|
+
this.sdk.validateParams(
|
|
1139
|
+
{ roomId, messageId, text },
|
|
1140
|
+
{
|
|
1141
|
+
roomId: { type: 'string', required: true },
|
|
1142
|
+
messageId: { type: 'string', required: true },
|
|
1143
|
+
text: { type: 'string', required: true },
|
|
1144
|
+
},
|
|
1145
|
+
);
|
|
1146
|
+
|
|
1147
|
+
const params = {
|
|
1148
|
+
body: { text },
|
|
1149
|
+
};
|
|
1150
|
+
|
|
1151
|
+
const result = await this.sdk._fetch(
|
|
1152
|
+
`/video/${roomId}/transcript/${messageId}`,
|
|
1153
|
+
'PATCH',
|
|
1154
|
+
params,
|
|
1155
|
+
);
|
|
1156
|
+
return result;
|
|
1157
|
+
}
|
|
1158
|
+
|
|
1159
|
+
/**
|
|
1160
|
+
* Redact a transcript message
|
|
1161
|
+
* @param {string} roomId - The video room ID
|
|
1162
|
+
* @param {string} messageId - The transcript message ID
|
|
1163
|
+
* @returns {Promise} Redaction result
|
|
1164
|
+
*/
|
|
1165
|
+
async redactTranscriptMessage(roomId, messageId) {
|
|
1166
|
+
this.sdk.validateParams(
|
|
1167
|
+
{ roomId, messageId },
|
|
1168
|
+
{
|
|
1169
|
+
roomId: { type: 'string', required: true },
|
|
1170
|
+
messageId: { type: 'string', required: true },
|
|
1171
|
+
},
|
|
1172
|
+
);
|
|
1173
|
+
|
|
1174
|
+
const result = await this.sdk._fetch(
|
|
1175
|
+
`/video/${roomId}/transcript/${messageId}/redact`,
|
|
1176
|
+
'POST',
|
|
1177
|
+
{},
|
|
1178
|
+
);
|
|
1179
|
+
return result;
|
|
1180
|
+
}
|
|
1181
|
+
|
|
1182
|
+
/**
|
|
1183
|
+
* Rename a speaker in the transcript for a video room
|
|
1184
|
+
* @param {string} roomId - The video room ID
|
|
1185
|
+
* @param {Object} update
|
|
1186
|
+
* @param {string} update.participantId - Participant ID whose transcript speaker name to update
|
|
1187
|
+
* @param {string} update.displayName - New display name
|
|
1188
|
+
* @returns {Promise} Update result
|
|
1189
|
+
*/
|
|
1190
|
+
async renameTranscriptSpeaker(roomId, { participantId, displayName }) {
|
|
1191
|
+
this.sdk.validateParams(
|
|
1192
|
+
{ roomId, participantId, displayName },
|
|
1193
|
+
{
|
|
1194
|
+
roomId: { type: 'string', required: true },
|
|
1195
|
+
participantId: { type: 'string', required: true },
|
|
1196
|
+
displayName: { type: 'string', required: true },
|
|
1197
|
+
},
|
|
1198
|
+
);
|
|
1199
|
+
|
|
1200
|
+
const params = {
|
|
1201
|
+
body: { participantId, displayName },
|
|
1202
|
+
};
|
|
1203
|
+
|
|
1204
|
+
const result = await this.sdk._fetch(
|
|
1205
|
+
`/video/${roomId}/transcript-speakers`,
|
|
1206
|
+
'PATCH',
|
|
1207
|
+
params,
|
|
1208
|
+
);
|
|
1209
|
+
return result;
|
|
1210
|
+
}
|
|
946
1211
|
}
|