@webex/internal-plugin-voicea 2.29.3 → 2.30.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/dist/voicea.js CHANGED
@@ -81,12 +81,7 @@ var VoiceaChannel = /*#__PURE__*/function (_WebexPlugin) {
81
81
  }, _constants.EVENT_TRIGGERS.NEW_CAPTION, {
82
82
  isFinal: false,
83
83
  transcriptId: voiceaPayload.transcript_id,
84
- translations: voiceaPayload.translations,
85
- transcript: {
86
- csis: voiceaPayload.transcripts[0] ? voiceaPayload.transcripts[0].csis : [],
87
- text: voiceaPayload.data,
88
- transcriptLanguageCode: voiceaPayload.transcripts[0].transcript_language_code
89
- }
84
+ transcripts: voiceaPayload.transcripts
90
85
  });
91
86
 
92
87
  break;
@@ -98,7 +93,6 @@ var VoiceaChannel = /*#__PURE__*/function (_WebexPlugin) {
98
93
  }, _constants.EVENT_TRIGGERS.NEW_CAPTION, {
99
94
  isFinal: true,
100
95
  transcriptId: voiceaPayload.transcript_id,
101
- translations: voiceaPayload.translations,
102
96
  transcript: {
103
97
  csis: voiceaPayload.csis,
104
98
  text: voiceaPayload.transcript.text,
@@ -1 +1 @@
1
- {"version":3,"names":["VoiceaChannel","args","VOICEA","voiceaPayload","type","TRANSCRIPTION_TYPE","TRANSCRIPT_INTERIM_RESULTS","Trigger","trigger","file","function","EVENT_TRIGGERS","NEW_CAPTION","isFinal","transcriptId","transcript_id","translations","transcript","csis","transcripts","text","data","transcriptLanguageCode","transcript_language_code","TRANSCRIPT_FINAL_RESULT","timestamp","millisToMinutesAndSeconds","end_millis","HIGHLIGHT_CREATED","highlight","highlightId","highlight_id","highlightLabel","highlight_label","highlightSource","highlight_source","EVA_THANKS","EVA_COMMAND","isListening","command_response","EVA_WAKE","EVA_CANCEL","statusCode","CAPTION_LANGUAGE_UPDATE","errorCode","errorMessage","message","voiceaLanguageOptions","captionLanguages","translation","allowed_languages","maxLanguages","max_languages","spokenLanguages","ASR","spoken_languages","VOICEA_ANNOUNCEMENT","hasVoiceaJoined","webex","internal","llm","isConnected","listenToEvents","socket","send","id","seqNum","recipients","route","getBinding","headers","clientPayload","version","eventType","relayType","VOICEA_RELAY_TYPES","CLIENT_ANNOUNCEMENT","trackingId","config","trackingIdPrefix","uuid","v4","toString","languageCode","request","method","url","getLocusUrl","body","then","SPOKEN_LANGUAGE_UPDATE","to","vmcDeviceId","translationLanguage","TRANSLATION_REQUEST","areCaptionsEnabled","undefined","transcribe","caption","CAPTIONS_TURNED_ON","sendAnnouncement","activate","isTranscribingEnabled","transcribing","TRANSCRIBING_ON","TRANSCRIBING_OFF","turnOnCaptions","on","e","sequenceNumber","ANNOUNCEMENT","from","processAnnouncementMessage","TRANSLATION_RESPONSE","processCaptionLanguageResponse","TRANSCRIPTION","processTranscription","WebexPlugin"],"sources":["voicea.ts"],"sourcesContent":["import uuid from 'uuid';\nimport {TriggerProxy as Trigger} from '@webex/plugin-meetings';\nimport {WebexPlugin, config} from '@webex/webex-core';\n\nimport {EVENT_TRIGGERS, VOICEA_RELAY_TYPES, TRANSCRIPTION_TYPE, VOICEA} from './constants';\n// eslint-disable-next-line no-unused-vars\nimport {AnnouncementPayload, CaptionLanguageResponse, TranscriptionResponse, IVoiceaChannel} from './voicea.types';\nimport {millisToMinutesAndSeconds} from './utils';\n\n/**\n * VoiceaChannel to hold single instance of LLM\n */\nexport class VoiceaChannel extends WebexPlugin implements IVoiceaChannel {\n namespace = VOICEA;\n\n private seqNum: number;\n\n private hasVoiceaJoined: boolean;\n\n private areCaptionsEnabled: boolean;\n\n private isTranscribingEnabled:boolean;\n\n private vmcDeviceId: string;\n\n /**\n * Listen to websocket messages\n */\n private listenToEvents() {\n this.webex.internal.llm.on('event:relay.event', (e) => {\n this.seqNum = e.sequenceNumber + 1;\n switch (e.data.relayType) {\n case VOICEA_RELAY_TYPES.ANNOUNCEMENT:\n this.vmcDeviceId = e.headers.from;\n this.hasVoiceaJoined = true;\n this.processAnnouncementMessage(e.data.voiceaPayload);\n break;\n case VOICEA_RELAY_TYPES.TRANSLATION_RESPONSE:\n this.processCaptionLanguageResponse(e.data.voiceaPayload);\n break;\n case VOICEA_RELAY_TYPES.TRANSCRIPTION:\n this.processTranscription(e.data.voiceaPayload);\n break;\n default:\n break;\n }\n });\n }\n\n /**\n * Initializes Voicea plugin\n * @param {any} args\n */\n constructor(...args) {\n super(...args);\n this.seqNum = 1;\n this.hasVoiceaJoined = false;\n this.areCaptionsEnabled = false;\n this.isTranscribingEnabled = false;\n this.vmcDeviceId = undefined;\n }\n\n /**\n * Process Transcript and send alert\n * @param {TranscriptionResponse} voiceaPayload\n * @returns {void}\n */\n private processTranscription = (voiceaPayload: TranscriptionResponse): void => {\n switch (voiceaPayload.type) {\n case TRANSCRIPTION_TYPE.TRANSCRIPT_INTERIM_RESULTS:\n Trigger.trigger(this, {\n file: 'voicea',\n function: 'processTranscription'\n },\n EVENT_TRIGGERS.NEW_CAPTION, {\n isFinal: false,\n transcriptId: voiceaPayload.transcript_id,\n translations: voiceaPayload.translations,\n transcript: {\n csis: voiceaPayload.transcripts[0] ? voiceaPayload.transcripts[0].csis : [],\n text: voiceaPayload.data,\n transcriptLanguageCode: voiceaPayload.transcripts[0].transcript_language_code\n },\n });\n break;\n\n case TRANSCRIPTION_TYPE.TRANSCRIPT_FINAL_RESULT:\n Trigger.trigger(this, {\n file: 'voicea',\n function: 'processTranscription'\n },\n EVENT_TRIGGERS.NEW_CAPTION, {\n isFinal: true,\n transcriptId: voiceaPayload.transcript_id,\n translations: voiceaPayload.translations,\n transcript: {\n csis: voiceaPayload.csis,\n text: voiceaPayload.transcript.text,\n transcriptLanguageCode: voiceaPayload.transcript.transcript_language_code\n },\n timestamp: millisToMinutesAndSeconds(voiceaPayload.transcript.end_millis)\n });\n break;\n\n case TRANSCRIPTION_TYPE.HIGHLIGHT_CREATED:\n Trigger.trigger(this, {\n file: 'voicea',\n function: 'processTranscription'\n },\n EVENT_TRIGGERS.HIGHLIGHT_CREATED, {\n csis: voiceaPayload.highlight.csis,\n highlightId: voiceaPayload.highlight.highlight_id,\n text: voiceaPayload.highlight.transcript,\n highlightLabel: voiceaPayload.highlight.highlight_label,\n highlightSource: voiceaPayload.highlight.highlight_source,\n timestamp: millisToMinutesAndSeconds(voiceaPayload.highlight.end_millis)\n });\n break;\n\n case TRANSCRIPTION_TYPE.EVA_THANKS:\n Trigger.trigger(this, {\n file: 'voicea',\n function: 'processTranscription'\n },\n EVENT_TRIGGERS.EVA_COMMAND, {\n isListening: false, text: voiceaPayload.command_response\n });\n break;\n\n case TRANSCRIPTION_TYPE.EVA_WAKE:\n case TRANSCRIPTION_TYPE.EVA_CANCEL:\n Trigger.trigger(this, {\n file: 'voicea',\n function: 'processTranscription'\n },\n EVENT_TRIGGERS.EVA_COMMAND, {\n isListening: voiceaPayload.type === TRANSCRIPTION_TYPE.EVA_WAKE\n });\n break;\n\n default:\n break;\n }\n };\n\n /**\n * Processes Caption Language Response\n * @param {CaptionLanguageResponse} voiceaPayload\n * @returns {void}\n */\n private processCaptionLanguageResponse = (voiceaPayload: CaptionLanguageResponse):void => {\n if (voiceaPayload.statusCode === 200) {\n Trigger.trigger(this, {\n file: 'voicea',\n function: 'processCaptionLanguageResponse'\n },\n EVENT_TRIGGERS.CAPTION_LANGUAGE_UPDATE, {statusCode: 200});\n }\n else {\n Trigger.trigger(this, {\n file: 'voicea',\n function: 'processCaptionLanguageResponse'\n },\n EVENT_TRIGGERS.CAPTION_LANGUAGE_UPDATE, {statusCode: voiceaPayload.errorCode, errorMessage: voiceaPayload.message});\n }\n };\n\n /**\n * processes voicea announcement response and triggers event\n * @param {Object} voiceaPayload\n * @returns {void}\n */\n private processAnnouncementMessage = (voiceaPayload: AnnouncementPayload):void => {\n const voiceaLanguageOptions = {\n captionLanguages: voiceaPayload?.translation?.allowed_languages ?? [],\n maxLanguages: voiceaPayload?.translation?.max_languages ?? 0,\n spokenLanguages: voiceaPayload?.ASR?.spoken_languages ?? [],\n };\n\n Trigger.trigger(\n this,\n {\n file: 'voicea',\n function: 'processAnnouncementMessage'\n },\n EVENT_TRIGGERS.VOICEA_ANNOUNCEMENT,\n voiceaLanguageOptions\n );\n };\n\n\n /**\n * Sends Announcement to add voicea to the meeting\n * @returns {void}\n */\n private sendAnnouncement = ():void => {\n if (this.hasVoiceaJoined || !this.webex.internal.llm.isConnected()) return;\n\n this.listenToEvents();\n this.webex.internal.llm.socket.send({\n id: `${this.seqNum}`,\n type: 'publishRequest',\n recipients: {\n route: this.webex.internal.llm.getBinding(),\n },\n headers: {},\n data: {\n clientPayload: {\n version: 'v2',\n },\n eventType: 'relay.event',\n relayType: VOICEA_RELAY_TYPES.CLIENT_ANNOUNCEMENT,\n },\n trackingId: `${config.trackingIdPrefix}_${uuid.v4().toString()}`\n });\n this.seqNum += 1;\n };\n\n /**\n * Set Spoken Language for the meeting\n * @param {string} languageCode\n * @returns {Promise}\n */\n public setSpokenLanguage = (languageCode: string):Promise<void> => this.request({\n method: 'PUT',\n url: `${this.webex.internal.llm.getLocusUrl()}/controls/`,\n body: {\n languageCode\n }\n }).then(() => {\n Trigger.trigger(this, {\n file: 'voicea',\n function: 'setSpokenLanguage'\n },\n EVENT_TRIGGERS.SPOKEN_LANGUAGE_UPDATE,\n {languageCode});\n });\n\n /**\n * Request Language translation\n * @param {string} languageCode\n * @returns {void}\n */\n public requestLanguage = (languageCode: string): void => {\n if (!this.webex.internal.llm.isConnected()) return;\n this.webex.internal.llm.socket.send({\n id: `${this.seqNum}`,\n type: 'publishRequest',\n recipients: {\n route: this.webex.internal.llm.getBinding(),\n },\n headers: {\n to: this.vmcDeviceId,\n },\n data: {\n clientPayload: {\n translationLanguage: languageCode,\n id: uuid.v4(),\n },\n eventType: 'relay.event',\n relayType: VOICEA_RELAY_TYPES.TRANSLATION_REQUEST,\n },\n trackingId: `${config.trackingIdPrefix}_${uuid.v4().toString()}`\n });\n this.seqNum += 1;\n };\n\n /**\n * Turn on Captions\n * @returns {Promise}\n */\n public turnOnCaptions = async (): undefined | Promise<void> => {\n if (this.hasVoiceaJoined && this.areCaptionsEnabled) return undefined;\n\n return this.request({\n method: 'PUT',\n url: `${this.webex.internal.llm.getLocusUrl()}/controls/`,\n body: {\n transcribe: {caption: true}\n }\n }).then(() => {\n Trigger.trigger(this, {\n file: 'voicea',\n function: 'turnOnCaptions'\n },\n EVENT_TRIGGERS.CAPTIONS_TURNED_ON);\n this.areCaptionsEnabled = true;\n this.sendAnnouncement();\n });\n };\n\n /**\n * Toggle transcribing for highlights\n * @param {bool} activate if true transcribing is turned on\n * @returns {Promise}\n */\n public toggleTranscribing = async (activate:boolean):undefined|Promise<void> => {\n if (this.isTranscribingEnabled === activate) return undefined;\n\n return this.request({\n method: 'PUT',\n url: `${this.webex.internal.llm.getLocusUrl()}/controls/`,\n body: {\n transcribe: {transcribing: activate}\n }\n }).then(() => {\n Trigger.trigger(this, {\n file: 'voicea',\n function: 'toggleTranscribing'\n },\n activate ? EVENT_TRIGGERS.TRANSCRIBING_ON : EVENT_TRIGGERS.TRANSCRIBING_OFF);\n this.isTranscribingEnabled = activate;\n if (activate && !this.areCaptionsEnabled && !this.hasVoiceaJoined) this.turnOnCaptions();\n });\n };\n}\n\nexport default VoiceaChannel;\n"],"mappings":"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"}
1
+ {"version":3,"names":["VoiceaChannel","args","VOICEA","voiceaPayload","type","TRANSCRIPTION_TYPE","TRANSCRIPT_INTERIM_RESULTS","Trigger","trigger","file","function","EVENT_TRIGGERS","NEW_CAPTION","isFinal","transcriptId","transcript_id","transcripts","TRANSCRIPT_FINAL_RESULT","transcript","csis","text","transcriptLanguageCode","transcript_language_code","timestamp","millisToMinutesAndSeconds","end_millis","HIGHLIGHT_CREATED","highlight","highlightId","highlight_id","highlightLabel","highlight_label","highlightSource","highlight_source","EVA_THANKS","EVA_COMMAND","isListening","command_response","EVA_WAKE","EVA_CANCEL","statusCode","CAPTION_LANGUAGE_UPDATE","errorCode","errorMessage","message","voiceaLanguageOptions","captionLanguages","translation","allowed_languages","maxLanguages","max_languages","spokenLanguages","ASR","spoken_languages","VOICEA_ANNOUNCEMENT","hasVoiceaJoined","webex","internal","llm","isConnected","listenToEvents","socket","send","id","seqNum","recipients","route","getBinding","headers","data","clientPayload","version","eventType","relayType","VOICEA_RELAY_TYPES","CLIENT_ANNOUNCEMENT","trackingId","config","trackingIdPrefix","uuid","v4","toString","languageCode","request","method","url","getLocusUrl","body","then","SPOKEN_LANGUAGE_UPDATE","to","vmcDeviceId","translationLanguage","TRANSLATION_REQUEST","areCaptionsEnabled","undefined","transcribe","caption","CAPTIONS_TURNED_ON","sendAnnouncement","activate","isTranscribingEnabled","transcribing","TRANSCRIBING_ON","TRANSCRIBING_OFF","turnOnCaptions","on","e","sequenceNumber","ANNOUNCEMENT","from","processAnnouncementMessage","TRANSLATION_RESPONSE","processCaptionLanguageResponse","TRANSCRIPTION","processTranscription","WebexPlugin"],"sources":["voicea.ts"],"sourcesContent":["import uuid from 'uuid';\nimport {TriggerProxy as Trigger} from '@webex/plugin-meetings';\nimport {WebexPlugin, config} from '@webex/webex-core';\n\nimport {EVENT_TRIGGERS, VOICEA_RELAY_TYPES, TRANSCRIPTION_TYPE, VOICEA} from './constants';\n// eslint-disable-next-line no-unused-vars\nimport {\n AnnouncementPayload,\n CaptionLanguageResponse,\n TranscriptionResponse,\n IVoiceaChannel,\n} from './voicea.types';\nimport {millisToMinutesAndSeconds} from './utils';\n\n/**\n * VoiceaChannel to hold single instance of LLM\n */\nexport class VoiceaChannel extends WebexPlugin implements IVoiceaChannel {\n namespace = VOICEA;\n\n private seqNum: number;\n\n private hasVoiceaJoined: boolean;\n\n private areCaptionsEnabled: boolean;\n\n private isTranscribingEnabled: boolean;\n\n private vmcDeviceId: string;\n\n /**\n * Listen to websocket messages\n */\n private listenToEvents() {\n this.webex.internal.llm.on('event:relay.event', (e) => {\n this.seqNum = e.sequenceNumber + 1;\n switch (e.data.relayType) {\n case VOICEA_RELAY_TYPES.ANNOUNCEMENT:\n this.vmcDeviceId = e.headers.from;\n this.hasVoiceaJoined = true;\n this.processAnnouncementMessage(e.data.voiceaPayload);\n break;\n case VOICEA_RELAY_TYPES.TRANSLATION_RESPONSE:\n this.processCaptionLanguageResponse(e.data.voiceaPayload);\n break;\n case VOICEA_RELAY_TYPES.TRANSCRIPTION:\n this.processTranscription(e.data.voiceaPayload);\n break;\n default:\n break;\n }\n });\n }\n\n /**\n * Initializes Voicea plugin\n * @param {any} args\n */\n constructor(...args) {\n super(...args);\n this.seqNum = 1;\n this.hasVoiceaJoined = false;\n this.areCaptionsEnabled = false;\n this.isTranscribingEnabled = false;\n this.vmcDeviceId = undefined;\n }\n\n /**\n * Process Transcript and send alert\n * @param {TranscriptionResponse} voiceaPayload\n * @returns {void}\n */\n private processTranscription = (voiceaPayload: TranscriptionResponse): void => {\n switch (voiceaPayload.type) {\n case TRANSCRIPTION_TYPE.TRANSCRIPT_INTERIM_RESULTS:\n Trigger.trigger(\n this,\n {\n file: 'voicea',\n function: 'processTranscription',\n },\n EVENT_TRIGGERS.NEW_CAPTION,\n {\n isFinal: false,\n transcriptId: voiceaPayload.transcript_id,\n transcripts: voiceaPayload.transcripts,\n }\n );\n break;\n\n case TRANSCRIPTION_TYPE.TRANSCRIPT_FINAL_RESULT:\n Trigger.trigger(\n this,\n {\n file: 'voicea',\n function: 'processTranscription',\n },\n EVENT_TRIGGERS.NEW_CAPTION,\n {\n isFinal: true,\n transcriptId: voiceaPayload.transcript_id,\n transcript: {\n csis: voiceaPayload.csis,\n text: voiceaPayload.transcript.text,\n transcriptLanguageCode: voiceaPayload.transcript.transcript_language_code,\n },\n timestamp: millisToMinutesAndSeconds(voiceaPayload.transcript.end_millis),\n }\n );\n break;\n\n case TRANSCRIPTION_TYPE.HIGHLIGHT_CREATED:\n Trigger.trigger(\n this,\n {\n file: 'voicea',\n function: 'processTranscription',\n },\n EVENT_TRIGGERS.HIGHLIGHT_CREATED,\n {\n csis: voiceaPayload.highlight.csis,\n highlightId: voiceaPayload.highlight.highlight_id,\n text: voiceaPayload.highlight.transcript,\n highlightLabel: voiceaPayload.highlight.highlight_label,\n highlightSource: voiceaPayload.highlight.highlight_source,\n timestamp: millisToMinutesAndSeconds(voiceaPayload.highlight.end_millis),\n }\n );\n break;\n\n case TRANSCRIPTION_TYPE.EVA_THANKS:\n Trigger.trigger(\n this,\n {\n file: 'voicea',\n function: 'processTranscription',\n },\n EVENT_TRIGGERS.EVA_COMMAND,\n {\n isListening: false,\n text: voiceaPayload.command_response,\n }\n );\n break;\n\n case TRANSCRIPTION_TYPE.EVA_WAKE:\n case TRANSCRIPTION_TYPE.EVA_CANCEL:\n Trigger.trigger(\n this,\n {\n file: 'voicea',\n function: 'processTranscription',\n },\n EVENT_TRIGGERS.EVA_COMMAND,\n {\n isListening: voiceaPayload.type === TRANSCRIPTION_TYPE.EVA_WAKE,\n }\n );\n break;\n\n default:\n break;\n }\n };\n\n /**\n * Processes Caption Language Response\n * @param {CaptionLanguageResponse} voiceaPayload\n * @returns {void}\n */\n private processCaptionLanguageResponse = (voiceaPayload: CaptionLanguageResponse): void => {\n if (voiceaPayload.statusCode === 200) {\n Trigger.trigger(\n this,\n {\n file: 'voicea',\n function: 'processCaptionLanguageResponse',\n },\n EVENT_TRIGGERS.CAPTION_LANGUAGE_UPDATE,\n {statusCode: 200}\n );\n } else {\n Trigger.trigger(\n this,\n {\n file: 'voicea',\n function: 'processCaptionLanguageResponse',\n },\n EVENT_TRIGGERS.CAPTION_LANGUAGE_UPDATE,\n {statusCode: voiceaPayload.errorCode, errorMessage: voiceaPayload.message}\n );\n }\n };\n\n /**\n * processes voicea announcement response and triggers event\n * @param {Object} voiceaPayload\n * @returns {void}\n */\n private processAnnouncementMessage = (voiceaPayload: AnnouncementPayload): void => {\n const voiceaLanguageOptions = {\n captionLanguages: voiceaPayload?.translation?.allowed_languages ?? [],\n maxLanguages: voiceaPayload?.translation?.max_languages ?? 0,\n spokenLanguages: voiceaPayload?.ASR?.spoken_languages ?? [],\n };\n\n Trigger.trigger(\n this,\n {\n file: 'voicea',\n function: 'processAnnouncementMessage',\n },\n EVENT_TRIGGERS.VOICEA_ANNOUNCEMENT,\n voiceaLanguageOptions\n );\n };\n\n /**\n * Sends Announcement to add voicea to the meeting\n * @returns {void}\n */\n private sendAnnouncement = (): void => {\n if (this.hasVoiceaJoined || !this.webex.internal.llm.isConnected()) return;\n\n this.listenToEvents();\n this.webex.internal.llm.socket.send({\n id: `${this.seqNum}`,\n type: 'publishRequest',\n recipients: {\n route: this.webex.internal.llm.getBinding(),\n },\n headers: {},\n data: {\n clientPayload: {\n version: 'v2',\n },\n eventType: 'relay.event',\n relayType: VOICEA_RELAY_TYPES.CLIENT_ANNOUNCEMENT,\n },\n trackingId: `${config.trackingIdPrefix}_${uuid.v4().toString()}`,\n });\n this.seqNum += 1;\n };\n\n /**\n * Set Spoken Language for the meeting\n * @param {string} languageCode\n * @returns {Promise}\n */\n public setSpokenLanguage = (languageCode: string): Promise<void> =>\n this.request({\n method: 'PUT',\n url: `${this.webex.internal.llm.getLocusUrl()}/controls/`,\n body: {\n languageCode,\n },\n }).then(() => {\n Trigger.trigger(\n this,\n {\n file: 'voicea',\n function: 'setSpokenLanguage',\n },\n EVENT_TRIGGERS.SPOKEN_LANGUAGE_UPDATE,\n {languageCode}\n );\n });\n\n /**\n * Request Language translation\n * @param {string} languageCode\n * @returns {void}\n */\n public requestLanguage = (languageCode: string): void => {\n if (!this.webex.internal.llm.isConnected()) return;\n this.webex.internal.llm.socket.send({\n id: `${this.seqNum}`,\n type: 'publishRequest',\n recipients: {\n route: this.webex.internal.llm.getBinding(),\n },\n headers: {\n to: this.vmcDeviceId,\n },\n data: {\n clientPayload: {\n translationLanguage: languageCode,\n id: uuid.v4(),\n },\n eventType: 'relay.event',\n relayType: VOICEA_RELAY_TYPES.TRANSLATION_REQUEST,\n },\n trackingId: `${config.trackingIdPrefix}_${uuid.v4().toString()}`,\n });\n this.seqNum += 1;\n };\n\n /**\n * Turn on Captions\n * @returns {Promise}\n */\n public turnOnCaptions = async (): undefined | Promise<void> => {\n if (this.hasVoiceaJoined && this.areCaptionsEnabled) return undefined;\n\n return this.request({\n method: 'PUT',\n url: `${this.webex.internal.llm.getLocusUrl()}/controls/`,\n body: {\n transcribe: {caption: true},\n },\n }).then(() => {\n Trigger.trigger(\n this,\n {\n file: 'voicea',\n function: 'turnOnCaptions',\n },\n EVENT_TRIGGERS.CAPTIONS_TURNED_ON\n );\n this.areCaptionsEnabled = true;\n this.sendAnnouncement();\n });\n };\n\n /**\n * Toggle transcribing for highlights\n * @param {bool} activate if true transcribing is turned on\n * @returns {Promise}\n */\n public toggleTranscribing = async (activate: boolean): undefined | Promise<void> => {\n if (this.isTranscribingEnabled === activate) return undefined;\n\n return this.request({\n method: 'PUT',\n url: `${this.webex.internal.llm.getLocusUrl()}/controls/`,\n body: {\n transcribe: {transcribing: activate},\n },\n }).then(() => {\n Trigger.trigger(\n this,\n {\n file: 'voicea',\n function: 'toggleTranscribing',\n },\n activate ? EVENT_TRIGGERS.TRANSCRIBING_ON : EVENT_TRIGGERS.TRANSCRIBING_OFF\n );\n this.isTranscribingEnabled = activate;\n if (activate && !this.areCaptionsEnabled && !this.hasVoiceaJoined) this.turnOnCaptions();\n });\n };\n}\n\nexport default VoiceaChannel;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;AACA;;AACA;;AAEA;;AAQA;;;;;;AAEA;AACA;AACA;IACaA,a;;;;;EAqCX;AACF;AACA;AACA;EACE,yBAAqB;IAAA;;IAAA;;IAAA,kCAANC,IAAM;MAANA,IAAM;IAAA;;IACnB,gDAASA,IAAT;IADmB,wFAxCTC,iBAwCS;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA,mGAcU,UAACC,aAAD,EAAgD;MAC7E,QAAQA,aAAa,CAACC,IAAtB;QACE,KAAKC,6BAAA,CAAmBC,0BAAxB;UACEC,4BAAA,CAAQC,OAAR,8CAEE;YACEC,IAAI,EAAE,QADR;YAEEC,QAAQ,EAAE;UAFZ,CAFF,EAMEC,yBAAA,CAAeC,WANjB,EAOE;YACEC,OAAO,EAAE,KADX;YAEEC,YAAY,EAAEX,aAAa,CAACY,aAF9B;YAGEC,WAAW,EAAEb,aAAa,CAACa;UAH7B,CAPF;;UAaA;;QAEF,KAAKX,6BAAA,CAAmBY,uBAAxB;UACEV,4BAAA,CAAQC,OAAR,8CAEE;YACEC,IAAI,EAAE,QADR;YAEEC,QAAQ,EAAE;UAFZ,CAFF,EAMEC,yBAAA,CAAeC,WANjB,EAOE;YACEC,OAAO,EAAE,IADX;YAEEC,YAAY,EAAEX,aAAa,CAACY,aAF9B;YAGEG,UAAU,EAAE;cACVC,IAAI,EAAEhB,aAAa,CAACgB,IADV;cAEVC,IAAI,EAAEjB,aAAa,CAACe,UAAd,CAAyBE,IAFrB;cAGVC,sBAAsB,EAAElB,aAAa,CAACe,UAAd,CAAyBI;YAHvC,CAHd;YAQEC,SAAS,EAAE,IAAAC,gCAAA,EAA0BrB,aAAa,CAACe,UAAd,CAAyBO,UAAnD;UARb,CAPF;;UAkBA;;QAEF,KAAKpB,6BAAA,CAAmBqB,iBAAxB;UACEnB,4BAAA,CAAQC,OAAR,8CAEE;YACEC,IAAI,EAAE,QADR;YAEEC,QAAQ,EAAE;UAFZ,CAFF,EAMEC,yBAAA,CAAee,iBANjB,EAOE;YACEP,IAAI,EAAEhB,aAAa,CAACwB,SAAd,CAAwBR,IADhC;YAEES,WAAW,EAAEzB,aAAa,CAACwB,SAAd,CAAwBE,YAFvC;YAGET,IAAI,EAAEjB,aAAa,CAACwB,SAAd,CAAwBT,UAHhC;YAIEY,cAAc,EAAE3B,aAAa,CAACwB,SAAd,CAAwBI,eAJ1C;YAKEC,eAAe,EAAE7B,aAAa,CAACwB,SAAd,CAAwBM,gBAL3C;YAMEV,SAAS,EAAE,IAAAC,gCAAA,EAA0BrB,aAAa,CAACwB,SAAd,CAAwBF,UAAlD;UANb,CAPF;;UAgBA;;QAEF,KAAKpB,6BAAA,CAAmB6B,UAAxB;UACE3B,4BAAA,CAAQC,OAAR,8CAEE;YACEC,IAAI,EAAE,QADR;YAEEC,QAAQ,EAAE;UAFZ,CAFF,EAMEC,yBAAA,CAAewB,WANjB,EAOE;YACEC,WAAW,EAAE,KADf;YAEEhB,IAAI,EAAEjB,aAAa,CAACkC;UAFtB,CAPF;;UAYA;;QAEF,KAAKhC,6BAAA,CAAmBiC,QAAxB;QACA,KAAKjC,6BAAA,CAAmBkC,UAAxB;UACEhC,4BAAA,CAAQC,OAAR,8CAEE;YACEC,IAAI,EAAE,QADR;YAEEC,QAAQ,EAAE;UAFZ,CAFF,EAMEC,yBAAA,CAAewB,WANjB,EAOE;YACEC,WAAW,EAAEjC,aAAa,CAACC,IAAd,KAAuBC,6BAAA,CAAmBiC;UADzD,CAPF;;UAWA;;QAEF;UACE;MAxFJ;IA0FD,CAzGoB;IAAA,6GAgHoB,UAACnC,aAAD,EAAkD;MACzF,IAAIA,aAAa,CAACqC,UAAd,KAA6B,GAAjC,EAAsC;QACpCjC,4BAAA,CAAQC,OAAR,8CAEE;UACEC,IAAI,EAAE,QADR;UAEEC,QAAQ,EAAE;QAFZ,CAFF,EAMEC,yBAAA,CAAe8B,uBANjB,EAOE;UAACD,UAAU,EAAE;QAAb,CAPF;MASD,CAVD,MAUO;QACLjC,4BAAA,CAAQC,OAAR,8CAEE;UACEC,IAAI,EAAE,QADR;UAEEC,QAAQ,EAAE;QAFZ,CAFF,EAMEC,yBAAA,CAAe8B,uBANjB,EAOE;UAACD,UAAU,EAAErC,aAAa,CAACuC,SAA3B;UAAsCC,YAAY,EAAExC,aAAa,CAACyC;QAAlE,CAPF;MASD;IACF,CAtIoB;IAAA,yGA6IgB,UAACzC,aAAD,EAA8C;MAAA;;MACjF,IAAM0C,qBAAqB,GAAG;QAC5BC,gBAAgB,2BAAE3C,aAAF,aAAEA,aAAF,iDAAEA,aAAa,CAAE4C,WAAjB,2DAAE,uBAA4BC,iBAA9B,yEAAmD,EADvC;QAE5BC,YAAY,4BAAE9C,aAAF,aAAEA,aAAF,iDAAEA,aAAa,CAAE4C,WAAjB,2DAAE,uBAA4BG,aAA9B,2EAA+C,CAF/B;QAG5BC,eAAe,2BAAEhD,aAAF,aAAEA,aAAF,6CAAEA,aAAa,CAAEiD,GAAjB,uDAAE,mBAAoBC,gBAAtB,yEAA0C;MAH7B,CAA9B;;MAMA9C,4BAAA,CAAQC,OAAR,8CAEE;QACEC,IAAI,EAAE,QADR;QAEEC,QAAQ,EAAE;MAFZ,CAFF,EAMEC,yBAAA,CAAe2C,mBANjB,EAOET,qBAPF;IASD,CA7JoB;IAAA,+FAmKM,YAAY;MACrC,IAAI,MAAKU,eAAL,IAAwB,CAAC,MAAKC,KAAL,CAAWC,QAAX,CAAoBC,GAApB,CAAwBC,WAAxB,EAA7B,EAAoE;;MAEpE,MAAKC,cAAL;;MACA,MAAKJ,KAAL,CAAWC,QAAX,CAAoBC,GAApB,CAAwBG,MAAxB,CAA+BC,IAA/B,CAAoC;QAClCC,EAAE,YAAK,MAAKC,MAAV,CADgC;QAElC5D,IAAI,EAAE,gBAF4B;QAGlC6D,UAAU,EAAE;UACVC,KAAK,EAAE,MAAKV,KAAL,CAAWC,QAAX,CAAoBC,GAApB,CAAwBS,UAAxB;QADG,CAHsB;QAMlCC,OAAO,EAAE,EANyB;QAOlCC,IAAI,EAAE;UACJC,aAAa,EAAE;YACbC,OAAO,EAAE;UADI,CADX;UAIJC,SAAS,EAAE,aAJP;UAKJC,SAAS,EAAEC,6BAAA,CAAmBC;QAL1B,CAP4B;QAclCC,UAAU,YAAKC,iBAAA,CAAOC,gBAAZ,cAAgCC,aAAA,CAAKC,EAAL,GAAUC,QAAV,EAAhC;MAdwB,CAApC;;MAgBA,MAAKjB,MAAL,IAAe,CAAf;IACD,CAxLoB;IAAA,gGA+LM,UAACkB,YAAD;MAAA,OACzB,MAAKC,OAAL,CAAa;QACXC,MAAM,EAAE,KADG;QAEXC,GAAG,YAAK,MAAK7B,KAAL,CAAWC,QAAX,CAAoBC,GAApB,CAAwB4B,WAAxB,EAAL,eAFQ;QAGXC,IAAI,EAAE;UACJL,YAAY,EAAZA;QADI;MAHK,CAAb,EAMGM,IANH,CAMQ,YAAM;QACZjF,4BAAA,CAAQC,OAAR,8CAEE;UACEC,IAAI,EAAE,QADR;UAEEC,QAAQ,EAAE;QAFZ,CAFF,EAMEC,yBAAA,CAAe8E,sBANjB,EAOE;UAACP,YAAY,EAAZA;QAAD,CAPF;MASD,CAhBD,CADyB;IAAA,CA/LN;IAAA,8FAuNI,UAACA,YAAD,EAAgC;MACvD,IAAI,CAAC,MAAK1B,KAAL,CAAWC,QAAX,CAAoBC,GAApB,CAAwBC,WAAxB,EAAL,EAA4C;;MAC5C,MAAKH,KAAL,CAAWC,QAAX,CAAoBC,GAApB,CAAwBG,MAAxB,CAA+BC,IAA/B,CAAoC;QAClCC,EAAE,YAAK,MAAKC,MAAV,CADgC;QAElC5D,IAAI,EAAE,gBAF4B;QAGlC6D,UAAU,EAAE;UACVC,KAAK,EAAE,MAAKV,KAAL,CAAWC,QAAX,CAAoBC,GAApB,CAAwBS,UAAxB;QADG,CAHsB;QAMlCC,OAAO,EAAE;UACPsB,EAAE,EAAE,MAAKC;QADF,CANyB;QASlCtB,IAAI,EAAE;UACJC,aAAa,EAAE;YACbsB,mBAAmB,EAAEV,YADR;YAEbnB,EAAE,EAAEgB,aAAA,CAAKC,EAAL;UAFS,CADX;UAKJR,SAAS,EAAE,aALP;UAMJC,SAAS,EAAEC,6BAAA,CAAmBmB;QAN1B,CAT4B;QAiBlCjB,UAAU,YAAKC,iBAAA,CAAOC,gBAAZ,cAAgCC,aAAA,CAAKC,EAAL,GAAUC,QAAV,EAAhC;MAjBwB,CAApC;;MAmBA,MAAKjB,MAAL,IAAe,CAAf;IACD,CA7OoB;IAAA,kLAmPG;MAAA;QAAA;UAAA;YAAA;cAAA,MAClB,MAAKT,eAAL,IAAwB,MAAKuC,kBADX;gBAAA;gBAAA;cAAA;;cAAA,iCACsCC,SADtC;;YAAA;cAAA,iCAGf,MAAKZ,OAAL,CAAa;gBAClBC,MAAM,EAAE,KADU;gBAElBC,GAAG,YAAK,MAAK7B,KAAL,CAAWC,QAAX,CAAoBC,GAApB,CAAwB4B,WAAxB,EAAL,eAFe;gBAGlBC,IAAI,EAAE;kBACJS,UAAU,EAAE;oBAACC,OAAO,EAAE;kBAAV;gBADR;cAHY,CAAb,EAMJT,IANI,CAMC,YAAM;gBACZjF,4BAAA,CAAQC,OAAR,8CAEE;kBACEC,IAAI,EAAE,QADR;kBAEEC,QAAQ,EAAE;gBAFZ,CAFF,EAMEC,yBAAA,CAAeuF,kBANjB;;gBAQA,MAAKJ,kBAAL,GAA0B,IAA1B;;gBACA,MAAKK,gBAAL;cACD,CAjBM,CAHe;;YAAA;YAAA;cAAA;UAAA;QAAA;MAAA;IAAA,CAnPH;IAAA;MAAA,oFA+QO,kBAAOC,QAAP;QAAA;UAAA;YAAA;cAAA;gBAAA,MACtB,MAAKC,qBAAL,KAA+BD,QADT;kBAAA;kBAAA;gBAAA;;gBAAA,kCAC0BL,SAD1B;;cAAA;gBAAA,kCAGnB,MAAKZ,OAAL,CAAa;kBAClBC,MAAM,EAAE,KADU;kBAElBC,GAAG,YAAK,MAAK7B,KAAL,CAAWC,QAAX,CAAoBC,GAApB,CAAwB4B,WAAxB,EAAL,eAFe;kBAGlBC,IAAI,EAAE;oBACJS,UAAU,EAAE;sBAACM,YAAY,EAAEF;oBAAf;kBADR;gBAHY,CAAb,EAMJZ,IANI,CAMC,YAAM;kBACZjF,4BAAA,CAAQC,OAAR,8CAEE;oBACEC,IAAI,EAAE,QADR;oBAEEC,QAAQ,EAAE;kBAFZ,CAFF,EAME0F,QAAQ,GAAGzF,yBAAA,CAAe4F,eAAlB,GAAoC5F,yBAAA,CAAe6F,gBAN7D;;kBAQA,MAAKH,qBAAL,GAA6BD,QAA7B;kBACA,IAAIA,QAAQ,IAAI,CAAC,MAAKN,kBAAlB,IAAwC,CAAC,MAAKvC,eAAlD,EAAmE,MAAKkD,cAAL;gBACpE,CAjBM,CAHmB;;cAAA;cAAA;gBAAA;YAAA;UAAA;QAAA;MAAA,CA/QP;;MAAA;QAAA;MAAA;IAAA;IAEnB,MAAKzC,MAAL,GAAc,CAAd;IACA,MAAKT,eAAL,GAAuB,KAAvB;IACA,MAAKuC,kBAAL,GAA0B,KAA1B;IACA,MAAKO,qBAAL,GAA6B,KAA7B;IACA,MAAKV,WAAL,GAAmBI,SAAnB;IANmB;EAOpB;EAED;AACF;AACA;AACA;AACA;;;;;;IAzCE;AACF;AACA;IACE,0BAAyB;MAAA;;MACvB,KAAKvC,KAAL,CAAWC,QAAX,CAAoBC,GAApB,CAAwBgD,EAAxB,CAA2B,mBAA3B,EAAgD,UAACC,CAAD,EAAO;QACrD,MAAI,CAAC3C,MAAL,GAAc2C,CAAC,CAACC,cAAF,GAAmB,CAAjC;;QACA,QAAQD,CAAC,CAACtC,IAAF,CAAOI,SAAf;UACE,KAAKC,6BAAA,CAAmBmC,YAAxB;YACE,MAAI,CAAClB,WAAL,GAAmBgB,CAAC,CAACvC,OAAF,CAAU0C,IAA7B;YACA,MAAI,CAACvD,eAAL,GAAuB,IAAvB;;YACA,MAAI,CAACwD,0BAAL,CAAgCJ,CAAC,CAACtC,IAAF,CAAOlE,aAAvC;;YACA;;UACF,KAAKuE,6BAAA,CAAmBsC,oBAAxB;YACE,MAAI,CAACC,8BAAL,CAAoCN,CAAC,CAACtC,IAAF,CAAOlE,aAA3C;;YACA;;UACF,KAAKuE,6BAAA,CAAmBwC,aAAxB;YACE,MAAI,CAACC,oBAAL,CAA0BR,CAAC,CAACtC,IAAF,CAAOlE,aAAjC;;YACA;;UACF;YACE;QAbJ;MAeD,CAjBD;IAkBD;;;EAnCgCiH,sB;;;eAgVpBpH,a"}
package/package.json CHANGED
@@ -1,24 +1,32 @@
1
1
  {
2
- "name": "@webex/internal-plugin-voicea",
3
- "version": "2.29.3",
4
- "description": "",
5
- "license": "MIT",
6
- "main": "dist/index.js",
7
- "devMain": "src/index.js",
8
- "repository": "https://github.com/webex/webex-js-sdk/tree/master/packages/node_modules/@webex/internal-plugin-voicea",
9
- "engines": {
10
- "node": ">=8"
11
- },
12
- "dependencies": {
13
- "@babel/runtime-corejs2": "^7.14.8",
14
- "@webex/webex-core": "2.29.3",
15
- "uuid": "^3.3.2",
16
- "@webex/plugin-meetings": "2.29.3",
17
- "envify": "^4.1.0"
18
- },
19
- "browserify": {
20
- "transform": [
21
- "envify"
22
- ]
23
- }
2
+ "name": "@webex/internal-plugin-voicea",
3
+ "version": "2.30.0",
4
+ "description": "",
5
+ "license": "MIT",
6
+ "main": "dist/index.js",
7
+ "devMain": "src/index.js",
8
+ "repository": "https://github.com/webex/webex-js-sdk/tree/master/packages/@webex/internal-plugin-voicea",
9
+ "engines": {
10
+ "node": ">=14"
11
+ },
12
+ "dependencies": {
13
+ "@webex/internal-plugin-llm": "workspace:^",
14
+ "@webex/internal-plugin-mercury": "workspace:^",
15
+ "@webex/internal-plugin-voicea": "workspace:^",
16
+ "@webex/plugin-meetings": "workspace:^",
17
+ "@webex/webex-core": "workspace:^",
18
+ "uuid": "^3.3.2"
19
+ },
20
+ "browserify": {
21
+ "transform": [
22
+ "babelify",
23
+ "envify"
24
+ ]
25
+ },
26
+ "devDependencies": {
27
+ "@webex/test-helper-chai": "workspace:^",
28
+ "@webex/test-helper-mock-web-socket": "workspace:^",
29
+ "@webex/test-helper-mock-webex": "workspace:^",
30
+ "sinon": "^9.2.4"
31
+ }
24
32
  }
package/src/voicea.ts CHANGED
@@ -4,7 +4,12 @@ import {WebexPlugin, config} from '@webex/webex-core';
4
4
 
5
5
  import {EVENT_TRIGGERS, VOICEA_RELAY_TYPES, TRANSCRIPTION_TYPE, VOICEA} from './constants';
6
6
  // eslint-disable-next-line no-unused-vars
7
- import {AnnouncementPayload, CaptionLanguageResponse, TranscriptionResponse, IVoiceaChannel} from './voicea.types';
7
+ import {
8
+ AnnouncementPayload,
9
+ CaptionLanguageResponse,
10
+ TranscriptionResponse,
11
+ IVoiceaChannel,
12
+ } from './voicea.types';
8
13
  import {millisToMinutesAndSeconds} from './utils';
9
14
 
10
15
  /**
@@ -19,7 +24,7 @@ export class VoiceaChannel extends WebexPlugin implements IVoiceaChannel {
19
24
 
20
25
  private areCaptionsEnabled: boolean;
21
26
 
22
- private isTranscribingEnabled:boolean;
27
+ private isTranscribingEnabled: boolean;
23
28
 
24
29
  private vmcDeviceId: string;
25
30
 
@@ -68,74 +73,89 @@ export class VoiceaChannel extends WebexPlugin implements IVoiceaChannel {
68
73
  private processTranscription = (voiceaPayload: TranscriptionResponse): void => {
69
74
  switch (voiceaPayload.type) {
70
75
  case TRANSCRIPTION_TYPE.TRANSCRIPT_INTERIM_RESULTS:
71
- Trigger.trigger(this, {
72
- file: 'voicea',
73
- function: 'processTranscription'
74
- },
75
- EVENT_TRIGGERS.NEW_CAPTION, {
76
- isFinal: false,
77
- transcriptId: voiceaPayload.transcript_id,
78
- translations: voiceaPayload.translations,
79
- transcript: {
80
- csis: voiceaPayload.transcripts[0] ? voiceaPayload.transcripts[0].csis : [],
81
- text: voiceaPayload.data,
82
- transcriptLanguageCode: voiceaPayload.transcripts[0].transcript_language_code
76
+ Trigger.trigger(
77
+ this,
78
+ {
79
+ file: 'voicea',
80
+ function: 'processTranscription',
83
81
  },
84
- });
82
+ EVENT_TRIGGERS.NEW_CAPTION,
83
+ {
84
+ isFinal: false,
85
+ transcriptId: voiceaPayload.transcript_id,
86
+ transcripts: voiceaPayload.transcripts,
87
+ }
88
+ );
85
89
  break;
86
90
 
87
91
  case TRANSCRIPTION_TYPE.TRANSCRIPT_FINAL_RESULT:
88
- Trigger.trigger(this, {
89
- file: 'voicea',
90
- function: 'processTranscription'
91
- },
92
- EVENT_TRIGGERS.NEW_CAPTION, {
93
- isFinal: true,
94
- transcriptId: voiceaPayload.transcript_id,
95
- translations: voiceaPayload.translations,
96
- transcript: {
97
- csis: voiceaPayload.csis,
98
- text: voiceaPayload.transcript.text,
99
- transcriptLanguageCode: voiceaPayload.transcript.transcript_language_code
92
+ Trigger.trigger(
93
+ this,
94
+ {
95
+ file: 'voicea',
96
+ function: 'processTranscription',
100
97
  },
101
- timestamp: millisToMinutesAndSeconds(voiceaPayload.transcript.end_millis)
102
- });
98
+ EVENT_TRIGGERS.NEW_CAPTION,
99
+ {
100
+ isFinal: true,
101
+ transcriptId: voiceaPayload.transcript_id,
102
+ transcript: {
103
+ csis: voiceaPayload.csis,
104
+ text: voiceaPayload.transcript.text,
105
+ transcriptLanguageCode: voiceaPayload.transcript.transcript_language_code,
106
+ },
107
+ timestamp: millisToMinutesAndSeconds(voiceaPayload.transcript.end_millis),
108
+ }
109
+ );
103
110
  break;
104
111
 
105
112
  case TRANSCRIPTION_TYPE.HIGHLIGHT_CREATED:
106
- Trigger.trigger(this, {
107
- file: 'voicea',
108
- function: 'processTranscription'
109
- },
110
- EVENT_TRIGGERS.HIGHLIGHT_CREATED, {
111
- csis: voiceaPayload.highlight.csis,
112
- highlightId: voiceaPayload.highlight.highlight_id,
113
- text: voiceaPayload.highlight.transcript,
114
- highlightLabel: voiceaPayload.highlight.highlight_label,
115
- highlightSource: voiceaPayload.highlight.highlight_source,
116
- timestamp: millisToMinutesAndSeconds(voiceaPayload.highlight.end_millis)
117
- });
113
+ Trigger.trigger(
114
+ this,
115
+ {
116
+ file: 'voicea',
117
+ function: 'processTranscription',
118
+ },
119
+ EVENT_TRIGGERS.HIGHLIGHT_CREATED,
120
+ {
121
+ csis: voiceaPayload.highlight.csis,
122
+ highlightId: voiceaPayload.highlight.highlight_id,
123
+ text: voiceaPayload.highlight.transcript,
124
+ highlightLabel: voiceaPayload.highlight.highlight_label,
125
+ highlightSource: voiceaPayload.highlight.highlight_source,
126
+ timestamp: millisToMinutesAndSeconds(voiceaPayload.highlight.end_millis),
127
+ }
128
+ );
118
129
  break;
119
130
 
120
131
  case TRANSCRIPTION_TYPE.EVA_THANKS:
121
- Trigger.trigger(this, {
122
- file: 'voicea',
123
- function: 'processTranscription'
124
- },
125
- EVENT_TRIGGERS.EVA_COMMAND, {
126
- isListening: false, text: voiceaPayload.command_response
127
- });
132
+ Trigger.trigger(
133
+ this,
134
+ {
135
+ file: 'voicea',
136
+ function: 'processTranscription',
137
+ },
138
+ EVENT_TRIGGERS.EVA_COMMAND,
139
+ {
140
+ isListening: false,
141
+ text: voiceaPayload.command_response,
142
+ }
143
+ );
128
144
  break;
129
145
 
130
146
  case TRANSCRIPTION_TYPE.EVA_WAKE:
131
147
  case TRANSCRIPTION_TYPE.EVA_CANCEL:
132
- Trigger.trigger(this, {
133
- file: 'voicea',
134
- function: 'processTranscription'
135
- },
136
- EVENT_TRIGGERS.EVA_COMMAND, {
137
- isListening: voiceaPayload.type === TRANSCRIPTION_TYPE.EVA_WAKE
138
- });
148
+ Trigger.trigger(
149
+ this,
150
+ {
151
+ file: 'voicea',
152
+ function: 'processTranscription',
153
+ },
154
+ EVENT_TRIGGERS.EVA_COMMAND,
155
+ {
156
+ isListening: voiceaPayload.type === TRANSCRIPTION_TYPE.EVA_WAKE,
157
+ }
158
+ );
139
159
  break;
140
160
 
141
161
  default:
@@ -148,29 +168,36 @@ export class VoiceaChannel extends WebexPlugin implements IVoiceaChannel {
148
168
  * @param {CaptionLanguageResponse} voiceaPayload
149
169
  * @returns {void}
150
170
  */
151
- private processCaptionLanguageResponse = (voiceaPayload: CaptionLanguageResponse):void => {
171
+ private processCaptionLanguageResponse = (voiceaPayload: CaptionLanguageResponse): void => {
152
172
  if (voiceaPayload.statusCode === 200) {
153
- Trigger.trigger(this, {
154
- file: 'voicea',
155
- function: 'processCaptionLanguageResponse'
156
- },
157
- EVENT_TRIGGERS.CAPTION_LANGUAGE_UPDATE, {statusCode: 200});
158
- }
159
- else {
160
- Trigger.trigger(this, {
161
- file: 'voicea',
162
- function: 'processCaptionLanguageResponse'
163
- },
164
- EVENT_TRIGGERS.CAPTION_LANGUAGE_UPDATE, {statusCode: voiceaPayload.errorCode, errorMessage: voiceaPayload.message});
173
+ Trigger.trigger(
174
+ this,
175
+ {
176
+ file: 'voicea',
177
+ function: 'processCaptionLanguageResponse',
178
+ },
179
+ EVENT_TRIGGERS.CAPTION_LANGUAGE_UPDATE,
180
+ {statusCode: 200}
181
+ );
182
+ } else {
183
+ Trigger.trigger(
184
+ this,
185
+ {
186
+ file: 'voicea',
187
+ function: 'processCaptionLanguageResponse',
188
+ },
189
+ EVENT_TRIGGERS.CAPTION_LANGUAGE_UPDATE,
190
+ {statusCode: voiceaPayload.errorCode, errorMessage: voiceaPayload.message}
191
+ );
165
192
  }
166
193
  };
167
194
 
168
195
  /**
169
- * processes voicea announcement response and triggers event
170
- * @param {Object} voiceaPayload
171
- * @returns {void}
172
- */
173
- private processAnnouncementMessage = (voiceaPayload: AnnouncementPayload):void => {
196
+ * processes voicea announcement response and triggers event
197
+ * @param {Object} voiceaPayload
198
+ * @returns {void}
199
+ */
200
+ private processAnnouncementMessage = (voiceaPayload: AnnouncementPayload): void => {
174
201
  const voiceaLanguageOptions = {
175
202
  captionLanguages: voiceaPayload?.translation?.allowed_languages ?? [],
176
203
  maxLanguages: voiceaPayload?.translation?.max_languages ?? 0,
@@ -181,19 +208,18 @@ export class VoiceaChannel extends WebexPlugin implements IVoiceaChannel {
181
208
  this,
182
209
  {
183
210
  file: 'voicea',
184
- function: 'processAnnouncementMessage'
211
+ function: 'processAnnouncementMessage',
185
212
  },
186
213
  EVENT_TRIGGERS.VOICEA_ANNOUNCEMENT,
187
214
  voiceaLanguageOptions
188
215
  );
189
216
  };
190
217
 
191
-
192
218
  /**
193
219
  * Sends Announcement to add voicea to the meeting
194
220
  * @returns {void}
195
221
  */
196
- private sendAnnouncement = ():void => {
222
+ private sendAnnouncement = (): void => {
197
223
  if (this.hasVoiceaJoined || !this.webex.internal.llm.isConnected()) return;
198
224
 
199
225
  this.listenToEvents();
@@ -211,7 +237,7 @@ export class VoiceaChannel extends WebexPlugin implements IVoiceaChannel {
211
237
  eventType: 'relay.event',
212
238
  relayType: VOICEA_RELAY_TYPES.CLIENT_ANNOUNCEMENT,
213
239
  },
214
- trackingId: `${config.trackingIdPrefix}_${uuid.v4().toString()}`
240
+ trackingId: `${config.trackingIdPrefix}_${uuid.v4().toString()}`,
215
241
  });
216
242
  this.seqNum += 1;
217
243
  };
@@ -221,20 +247,24 @@ export class VoiceaChannel extends WebexPlugin implements IVoiceaChannel {
221
247
  * @param {string} languageCode
222
248
  * @returns {Promise}
223
249
  */
224
- public setSpokenLanguage = (languageCode: string):Promise<void> => this.request({
225
- method: 'PUT',
226
- url: `${this.webex.internal.llm.getLocusUrl()}/controls/`,
227
- body: {
228
- languageCode
229
- }
230
- }).then(() => {
231
- Trigger.trigger(this, {
232
- file: 'voicea',
233
- function: 'setSpokenLanguage'
234
- },
235
- EVENT_TRIGGERS.SPOKEN_LANGUAGE_UPDATE,
236
- {languageCode});
237
- });
250
+ public setSpokenLanguage = (languageCode: string): Promise<void> =>
251
+ this.request({
252
+ method: 'PUT',
253
+ url: `${this.webex.internal.llm.getLocusUrl()}/controls/`,
254
+ body: {
255
+ languageCode,
256
+ },
257
+ }).then(() => {
258
+ Trigger.trigger(
259
+ this,
260
+ {
261
+ file: 'voicea',
262
+ function: 'setSpokenLanguage',
263
+ },
264
+ EVENT_TRIGGERS.SPOKEN_LANGUAGE_UPDATE,
265
+ {languageCode}
266
+ );
267
+ });
238
268
 
239
269
  /**
240
270
  * Request Language translation
@@ -260,7 +290,7 @@ export class VoiceaChannel extends WebexPlugin implements IVoiceaChannel {
260
290
  eventType: 'relay.event',
261
291
  relayType: VOICEA_RELAY_TYPES.TRANSLATION_REQUEST,
262
292
  },
263
- trackingId: `${config.trackingIdPrefix}_${uuid.v4().toString()}`
293
+ trackingId: `${config.trackingIdPrefix}_${uuid.v4().toString()}`,
264
294
  });
265
295
  this.seqNum += 1;
266
296
  };
@@ -276,14 +306,17 @@ export class VoiceaChannel extends WebexPlugin implements IVoiceaChannel {
276
306
  method: 'PUT',
277
307
  url: `${this.webex.internal.llm.getLocusUrl()}/controls/`,
278
308
  body: {
279
- transcribe: {caption: true}
280
- }
281
- }).then(() => {
282
- Trigger.trigger(this, {
283
- file: 'voicea',
284
- function: 'turnOnCaptions'
309
+ transcribe: {caption: true},
285
310
  },
286
- EVENT_TRIGGERS.CAPTIONS_TURNED_ON);
311
+ }).then(() => {
312
+ Trigger.trigger(
313
+ this,
314
+ {
315
+ file: 'voicea',
316
+ function: 'turnOnCaptions',
317
+ },
318
+ EVENT_TRIGGERS.CAPTIONS_TURNED_ON
319
+ );
287
320
  this.areCaptionsEnabled = true;
288
321
  this.sendAnnouncement();
289
322
  });
@@ -294,21 +327,24 @@ export class VoiceaChannel extends WebexPlugin implements IVoiceaChannel {
294
327
  * @param {bool} activate if true transcribing is turned on
295
328
  * @returns {Promise}
296
329
  */
297
- public toggleTranscribing = async (activate:boolean):undefined|Promise<void> => {
330
+ public toggleTranscribing = async (activate: boolean): undefined | Promise<void> => {
298
331
  if (this.isTranscribingEnabled === activate) return undefined;
299
332
 
300
333
  return this.request({
301
334
  method: 'PUT',
302
335
  url: `${this.webex.internal.llm.getLocusUrl()}/controls/`,
303
336
  body: {
304
- transcribe: {transcribing: activate}
305
- }
306
- }).then(() => {
307
- Trigger.trigger(this, {
308
- file: 'voicea',
309
- function: 'toggleTranscribing'
337
+ transcribe: {transcribing: activate},
310
338
  },
311
- activate ? EVENT_TRIGGERS.TRANSCRIBING_ON : EVENT_TRIGGERS.TRANSCRIBING_OFF);
339
+ }).then(() => {
340
+ Trigger.trigger(
341
+ this,
342
+ {
343
+ file: 'voicea',
344
+ function: 'toggleTranscribing',
345
+ },
346
+ activate ? EVENT_TRIGGERS.TRANSCRIBING_ON : EVENT_TRIGGERS.TRANSCRIBING_OFF
347
+ );
312
348
  this.isTranscribingEnabled = activate;
313
349
  if (activate && !this.areCaptionsEnabled && !this.hasVoiceaJoined) this.turnOnCaptions();
314
350
  });
@@ -14,13 +14,12 @@ describe('plugin-voicea', () => {
14
14
  describe('voicea', () => {
15
15
  let webex, voiceaService;
16
16
 
17
-
18
17
  beforeEach(() => {
19
18
  webex = new MockWebex({
20
19
  children: {
21
20
  mercury: Mercury,
22
21
  llm: LLMChannel,
23
- voicea: VoiceaService
22
+ voicea: VoiceaService,
24
23
  },
25
24
  });
26
25
 
@@ -32,13 +31,13 @@ describe('plugin-voicea', () => {
32
31
 
33
32
  voiceaService.request = sinon.stub().resolves({
34
33
  headers: {},
35
- body: ''
34
+ body: '',
36
35
  });
37
36
  voiceaService.register = sinon.stub().resolves({
38
37
  body: {
39
38
  binding: 'binding',
40
- webSocketUrl: 'url'
41
- }
39
+ webSocketUrl: 'url',
40
+ },
42
41
  });
43
42
  });
44
43
 
@@ -67,7 +66,7 @@ describe('plugin-voicea', () => {
67
66
  eventType: 'relay.event',
68
67
  relayType: 'client.annc',
69
68
  },
70
- trackingId: sinon.match.string
69
+ trackingId: sinon.match.string,
71
70
  });
72
71
  });
73
72
  });
@@ -80,10 +79,10 @@ describe('plugin-voicea', () => {
80
79
  max_languages: 5,
81
80
  },
82
81
  ASR: {
83
- spoken_languages: ['en']
82
+ spoken_languages: ['en'],
84
83
  },
85
84
 
86
- version: 'v2'
85
+ version: 'v2',
87
86
  };
88
87
 
89
88
  const spy = sinon.spy();
@@ -94,7 +93,7 @@ describe('plugin-voicea', () => {
94
93
  assert.calledOnceWithExactly(spy, {
95
94
  captionLanguages: ['af', 'am'],
96
95
  spokenLanguages: ['en'],
97
- maxLanguages: 5
96
+ maxLanguages: 5,
98
97
  });
99
98
  });
100
99
 
@@ -107,7 +106,7 @@ describe('plugin-voicea', () => {
107
106
  assert.calledOnceWithExactly(spy, {
108
107
  captionLanguages: [],
109
108
  spokenLanguages: [],
110
- maxLanguages: 0
109
+ maxLanguages: 0,
111
110
  });
112
111
  });
113
112
  });
@@ -130,12 +129,12 @@ describe('plugin-voicea', () => {
130
129
  data: {
131
130
  clientPayload: {
132
131
  translationLanguage: 'en',
133
- id: sinon.match.string
132
+ id: sinon.match.string,
134
133
  },
135
134
  eventType: 'relay.event',
136
- relayType: 'voicea.transl.req'
135
+ relayType: 'voicea.transl.req',
137
136
  },
138
- trackingId: sinon.match.string
137
+ trackingId: sinon.match.string,
139
138
  });
140
139
  });
141
140
  });
@@ -151,11 +150,14 @@ describe('plugin-voicea', () => {
151
150
 
152
151
  assert.calledOnceWithExactly(triggerSpy, {languageCode});
153
152
 
154
- sinon.assert.calledWith(voiceaService.request, sinon.match({
155
- method: 'PUT',
156
- url: `${locusUrl}/controls/`,
157
- body: {languageCode}
158
- }));
153
+ sinon.assert.calledWith(
154
+ voiceaService.request,
155
+ sinon.match({
156
+ method: 'PUT',
157
+ url: `${locusUrl}/controls/`,
158
+ body: {languageCode},
159
+ })
160
+ );
159
161
  });
160
162
  });
161
163
 
@@ -175,22 +177,28 @@ describe('plugin-voicea', () => {
175
177
  voiceaService.listenToEvents();
176
178
 
177
179
  await voiceaService.turnOnCaptions();
178
- sinon.assert.calledWith(voiceaService.request, sinon.match({
179
- method: 'PUT',
180
- url: `${locusUrl}/controls/`,
181
- body: {transcribe: {caption: true}}
182
- }));
180
+ sinon.assert.calledWith(
181
+ voiceaService.request,
182
+ sinon.match({
183
+ method: 'PUT',
184
+ url: `${locusUrl}/controls/`,
185
+ body: {transcribe: {caption: true}},
186
+ })
187
+ );
183
188
 
184
189
  assert.calledOnceWithExactly(triggerSpy, undefined);
185
190
 
186
191
  assert.calledOnce(announcementSpy);
187
192
  });
188
193
 
189
- it('doesn\'t call API on captions', async () => {
194
+ it("doesn't call API on captions", async () => {
190
195
  await voiceaService.turnOnCaptions();
191
196
 
192
197
  // eslint-disable-next-line no-underscore-dangle
193
- voiceaService.webex.internal.llm._emit('event:relay.event', {headers: {from: 'ws'}, data: {relayType: 'voicea.annc', voiceaPayload: {}}});
198
+ voiceaService.webex.internal.llm._emit('event:relay.event', {
199
+ headers: {from: 'ws'},
200
+ data: {relayType: 'voicea.annc', voiceaPayload: {}},
201
+ });
194
202
 
195
203
  const response = await voiceaService.turnOnCaptions();
196
204
 
@@ -211,7 +219,10 @@ describe('plugin-voicea', () => {
211
219
  const announcementSpy = sinon.spy(voiceaService, 'sendAnnouncement');
212
220
 
213
221
  // eslint-disable-next-line no-underscore-dangle
214
- voiceaService.webex.internal.llm._emit('event:relay.event', {headers: {from: 'ws'}, data: {relayType: 'voicea.annc', voiceaPayload: {}}});
222
+ voiceaService.webex.internal.llm._emit('event:relay.event', {
223
+ headers: {from: 'ws'},
224
+ data: {relayType: 'voicea.annc', voiceaPayload: {}},
225
+ });
215
226
 
216
227
  const triggerSpy = sinon.spy();
217
228
 
@@ -219,11 +230,14 @@ describe('plugin-voicea', () => {
219
230
  voiceaService.listenToEvents();
220
231
 
221
232
  await voiceaService.toggleTranscribing(true);
222
- sinon.assert.calledWith(voiceaService.request, sinon.match({
223
- method: 'PUT',
224
- url: `${locusUrl}/controls/`,
225
- body: {transcribe: {transcribing: true}}
226
- }));
233
+ sinon.assert.calledWith(
234
+ voiceaService.request,
235
+ sinon.match({
236
+ method: 'PUT',
237
+ url: `${locusUrl}/controls/`,
238
+ body: {transcribe: {transcribing: true}},
239
+ })
240
+ );
227
241
 
228
242
  assert.calledOnce(triggerSpy);
229
243
  assert.notCalled(announcementSpy);
@@ -238,11 +252,14 @@ describe('plugin-voicea', () => {
238
252
  voiceaService.listenToEvents();
239
253
 
240
254
  await voiceaService.toggleTranscribing(true);
241
- sinon.assert.calledWith(voiceaService.request, sinon.match({
242
- method: 'PUT',
243
- url: `${locusUrl}/controls/`,
244
- body: {transcribe: {transcribing: true}}
245
- }));
255
+ sinon.assert.calledWith(
256
+ voiceaService.request,
257
+ sinon.match({
258
+ method: 'PUT',
259
+ url: `${locusUrl}/controls/`,
260
+ body: {transcribe: {transcribing: true}},
261
+ })
262
+ );
246
263
 
247
264
  assert.calledOnce(triggerSpy);
248
265
  assert.calledOnce(announcementSpy);
@@ -259,25 +276,26 @@ describe('plugin-voicea', () => {
259
276
  voiceaService.listenToEvents();
260
277
 
261
278
  await voiceaService.toggleTranscribing(false);
262
- sinon.assert.calledWith(voiceaService.request, sinon.match({
263
- method: 'PUT',
264
- url: `${locusUrl}/controls/`,
265
- body: {transcribe: {transcribing: true}}
266
- }));
279
+ sinon.assert.calledWith(
280
+ voiceaService.request,
281
+ sinon.match({
282
+ method: 'PUT',
283
+ url: `${locusUrl}/controls/`,
284
+ body: {transcribe: {transcribing: true}},
285
+ })
286
+ );
267
287
 
268
288
  assert.calledOnce(triggerSpy);
269
289
  assert.notCalled(announcementSpy);
270
290
  });
271
291
 
272
- it('doesn\'t call API on same value', async () => {
292
+ it("doesn't call API on same value", async () => {
273
293
  await voiceaService.toggleTranscribing(true);
274
294
  const triggerSpy = sinon.spy();
275
295
  const announcementSpy = sinon.spy(voiceaService, 'sendAnnouncement');
276
296
 
277
-
278
297
  voiceaService.on(EVENT_TRIGGERS.TRANSCRIBING_OFF, triggerSpy);
279
298
 
280
-
281
299
  await voiceaService.toggleTranscribing(true);
282
300
 
283
301
  assert.notCalled(triggerSpy);
@@ -301,9 +319,9 @@ describe('plugin-voicea', () => {
301
319
  data: {
302
320
  relayType: 'voicea.transl.rsp',
303
321
  voiceaPayload: {
304
- statusCode: 200
305
- }
306
- }
322
+ statusCode: 200,
323
+ },
324
+ },
307
325
  });
308
326
 
309
327
  assert.calledOnceWithExactly(triggerSpy, {statusCode: 200});
@@ -319,13 +337,13 @@ describe('plugin-voicea', () => {
319
337
 
320
338
  const payload = {
321
339
  errorCode: 300,
322
- message: 'error text'
340
+ message: 'error text',
323
341
  };
324
342
 
325
343
  // eslint-disable-next-line no-underscore-dangle
326
344
  voiceaService.webex.internal.llm._emit('event:relay.event', {
327
345
  headers: {from: 'ws'},
328
- data: {relayType: 'voicea.transl.rsp', voiceaPayload: payload}
346
+ data: {relayType: 'voicea.transl.rsp', voiceaPayload: payload},
329
347
  });
330
348
  assert.calledOnce(functionSpy);
331
349
  assert.calledOnceWithExactly(triggerSpy, {statusCode: 300, errorMessage: 'error text'});
@@ -343,7 +361,24 @@ describe('plugin-voicea', () => {
343
361
 
344
362
  it('processes interim transcription', async () => {
345
363
  voiceaService.on(EVENT_TRIGGERS.NEW_CAPTION, triggerSpy);
346
-
364
+ const transcripts = [
365
+ {
366
+ text: 'Hello.',
367
+ csis: [3556942592],
368
+ transcript_language_code: 'en',
369
+ translations: {
370
+ fr: 'Bonjour.',
371
+ },
372
+ },
373
+ {
374
+ text: 'This is Webex',
375
+ csis: [3556942593],
376
+ transcript_language_code: 'en',
377
+ translations: {
378
+ fr: "C'est Webex",
379
+ },
380
+ },
381
+ ];
347
382
  const voiceaPayload = {
348
383
  audio_received_millis: 0,
349
384
  command_response: '',
@@ -355,40 +390,20 @@ describe('plugin-voicea', () => {
355
390
  ts: 1611653204.3147924,
356
391
  type: 'transcript_interim_results',
357
392
 
358
- transcripts: [
359
- {
360
- text: 'Hello.',
361
- csis: [
362
- 3556942592
363
- ],
364
- transcript_language_code: 'en',
365
- translations: {
366
- fr: 'Bonjour.'
367
- }
368
- },
369
- {
370
- text: 'This is Webex',
371
- csis: [
372
- 3556942593
373
- ],
374
- transcript_language_code: 'en',
375
- translations: {
376
- fr: "C'est Webex"
377
- }
378
- }
379
- ]
380
-
393
+ transcripts,
381
394
  };
382
395
 
383
396
  // eslint-disable-next-line no-underscore-dangle
384
397
  await voiceaService.webex.internal.llm._emit('event:relay.event', {
385
398
  headers: {from: 'ws'},
386
- data: {relayType: 'voicea.transcription', voiceaPayload}
399
+ data: {relayType: 'voicea.transcription', voiceaPayload},
387
400
  });
388
401
 
389
402
  assert.calledOnceWithExactly(functionSpy, voiceaPayload);
390
403
  assert.calledOnceWithExactly(triggerSpy, {
391
- isFinal: false, transcriptId: '3ec73890-bffb-f28b-e77f-99dc13caea7e', translations: undefined, transcript: {text: 'Hello.', csis: [3556942592], transcriptLanguageCode: 'en'}
404
+ isFinal: false,
405
+ transcriptId: '3ec73890-bffb-f28b-e77f-99dc13caea7e',
406
+ transcripts,
392
407
  });
393
408
  });
394
409
 
@@ -410,64 +425,56 @@ describe('plugin-voicea', () => {
410
425
  {
411
426
  end_millis: 12474,
412
427
  start_millis: 12204,
413
- word: 'Hello?'
414
- }
415
- ],
416
- csis: [
417
- 3556942592
428
+ word: 'Hello?',
429
+ },
418
430
  ],
431
+ csis: [3556942592],
419
432
  end_millis: 13044,
420
433
  last_packet_timestamp_ms: 1611653206784,
421
434
  start_millis: 12204,
422
435
  text: 'Hello?',
423
- transcript_language_code: 'en'
436
+ transcript_language_code: 'en',
424
437
  },
425
438
  transcripts: [
426
439
  {
427
440
  start_millis: 12204,
428
441
  end_millis: 13044,
429
442
  text: 'Hello.',
430
- csis: [
431
- 3556942592
432
- ],
443
+ csis: [3556942592],
433
444
  transcript_language_code: 'en',
434
445
  translations: {
435
- fr: 'Bonjour.'
436
- }
446
+ fr: 'Bonjour.',
447
+ },
437
448
  },
438
449
  {
439
450
  start_millis: 12204,
440
451
  end_millis: 13044,
441
452
  text: 'This is Webex',
442
- csis: [
443
- 3556942593
444
- ],
453
+ csis: [3556942593],
445
454
  transcript_language_code: 'en',
446
455
  translations: {
447
- fr: "C'est Webex"
448
- }
449
- }
450
- ]
451
-
456
+ fr: "C'est Webex",
457
+ },
458
+ },
459
+ ],
452
460
  };
453
461
 
454
462
  // eslint-disable-next-line no-underscore-dangle
455
463
  await voiceaService.webex.internal.llm._emit('event:relay.event', {
456
464
  headers: {from: 'ws'},
457
- data: {relayType: 'voicea.transcription', voiceaPayload}
465
+ data: {relayType: 'voicea.transcription', voiceaPayload},
458
466
  });
459
467
 
460
468
  assert.calledOnceWithExactly(functionSpy, voiceaPayload);
461
469
  assert.calledOnceWithExactly(triggerSpy, {
462
470
  isFinal: true,
463
471
  transcriptId: '3ec73890-bffb-f28b-e77f-99dc13caea7e',
464
- translations: undefined,
465
472
  transcript: {
466
473
  csis: [3556942592],
467
474
  text: 'Hello?',
468
- transcriptLanguageCode: 'en'
475
+ transcriptLanguageCode: 'en',
469
476
  },
470
- timestamp: '0:13'
477
+ timestamp: '0:13',
471
478
  });
472
479
  });
473
480
 
@@ -485,22 +492,23 @@ describe('plugin-voicea', () => {
485
492
  ews_keyphrase: 'OkayWebEx',
486
493
  model_version: 'WebEx',
487
494
  offset_seconds: 2336.5900000000001,
488
- recording_file_name: 'OkayWebEx_fd5bd0fc-06fb-4fd1-982b-554c4368f101_47900f3f-8579-25eb-3f6a-74d81a3c66a4_2335.8900000000003_2336.79.raw',
489
- type: 'live-hotword'
495
+ recording_file_name:
496
+ 'OkayWebEx_fd5bd0fc-06fb-4fd1-982b-554c4368f101_47900f3f-8579-25eb-3f6a-74d81a3c66a4_2335.8900000000003_2336.79.raw',
497
+ type: 'live-hotword',
490
498
  },
491
499
  ts: 1616137504.8107769,
492
- type: 'eva_wake'
500
+ type: 'eva_wake',
493
501
  };
494
502
 
495
503
  // eslint-disable-next-line no-underscore-dangle
496
504
  await voiceaService.webex.internal.llm._emit('event:relay.event', {
497
505
  headers: {from: 'ws'},
498
- data: {relayType: 'voicea.transcription', voiceaPayload}
506
+ data: {relayType: 'voicea.transcription', voiceaPayload},
499
507
  });
500
508
 
501
509
  assert.calledOnceWithExactly(functionSpy, voiceaPayload);
502
510
  assert.calledOnceWithExactly(triggerSpy, {
503
- isListening: true
511
+ isListening: true,
504
512
  });
505
513
  });
506
514
 
@@ -514,18 +522,19 @@ describe('plugin-voicea', () => {
514
522
  intent: 'decision',
515
523
  meeting: 'fd5bd0fc-06fb-4fd1-982b-554c4368f101',
516
524
  ts: 1616135828.2552843,
517
- type: 'eva_thanks'
525
+ type: 'eva_thanks',
518
526
  };
519
527
 
520
528
  // eslint-disable-next-line no-underscore-dangle
521
529
  await voiceaService.webex.internal.llm._emit('event:relay.event', {
522
530
  headers: {from: 'ws'},
523
- data: {relayType: 'voicea.transcription', voiceaPayload}
531
+ data: {relayType: 'voicea.transcription', voiceaPayload},
524
532
  });
525
533
 
526
534
  assert.calledOnceWithExactly(functionSpy, voiceaPayload);
527
535
  assert.calledOnceWithExactly(triggerSpy, {
528
- isListening: false, text: 'OK! Decision created.'
536
+ isListening: false,
537
+ text: 'OK! Decision created.',
529
538
  });
530
539
  });
531
540
 
@@ -539,19 +548,19 @@ describe('plugin-voicea', () => {
539
548
  intent: 'decision',
540
549
  meeting: 'fd5bd0fc-06fb-4fd1-982b-554c4368f101',
541
550
  ts: 1616135828.2552843,
542
- type: 'eva_cancel'
551
+ type: 'eva_cancel',
543
552
  };
544
553
 
545
554
  // eslint-disable-next-line no-underscore-dangle
546
555
  await voiceaService.webex.internal.llm._emit('event:relay.event', {
547
556
  headers: {from: 'ws'},
548
- data: {relayType: 'voicea.transcription', voiceaPayload}
557
+ data: {relayType: 'voicea.transcription', voiceaPayload},
549
558
  });
550
559
 
551
560
  assert.calledOnceWithExactly(functionSpy, voiceaPayload);
552
561
 
553
562
  assert.calledOnceWithExactly(triggerSpy, {
554
- isListening: false
563
+ isListening: false,
555
564
  });
556
565
  });
557
566
 
@@ -569,18 +578,18 @@ describe('plugin-voicea', () => {
569
578
  highlight_source: 'voice-command',
570
579
  start_millis: 652756,
571
580
  transcript: 'Create a decision to move ahead with the last proposal.',
572
- trigger_info: {type: 'live-hotword'}
581
+ trigger_info: {type: 'live-hotword'},
573
582
  },
574
583
  id: 'e6df0262-6289-db2e-581a-d44bb41b1c9c',
575
584
  meeting: 'fd5bd0fc-06fb-4fd1-982b-554c4368f101',
576
585
  ts: 1616135858.5349569,
577
- type: 'highlight_created'
586
+ type: 'highlight_created',
578
587
  };
579
588
 
580
589
  // eslint-disable-next-line no-underscore-dangle
581
590
  await voiceaService.webex.internal.llm._emit('event:relay.event', {
582
591
  headers: {from: 'ws'},
583
- data: {relayType: 'voicea.transcription', voiceaPayload}
592
+ data: {relayType: 'voicea.transcription', voiceaPayload},
584
593
  });
585
594
 
586
595
  assert.calledOnceWithExactly(functionSpy, voiceaPayload);
@@ -590,7 +599,7 @@ describe('plugin-voicea', () => {
590
599
  text: 'Create a decision to move ahead with the last proposal.',
591
600
  highlightLabel: 'Decision',
592
601
  highlightSource: 'voice-command',
593
- timestamp: '11:00'
602
+ timestamp: '11:00',
594
603
  });
595
604
  });
596
605
  });