@webex/internal-plugin-voicea 3.12.0-llmrefactor.7 → 3.12.0-llmrefactor.8
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/types/voicea-plugin.d.ts +3 -3
- package/dist/types/voicea.d.ts +45 -7
- package/dist/voicea-plugin.js +2 -2
- package/dist/voicea-plugin.js.map +1 -1
- package/dist/voicea.js +157 -70
- package/dist/voicea.js.map +1 -1
- package/package.json +1 -1
- package/src/voicea-plugin.ts +3 -3
- package/src/voicea.ts +142 -50
- package/test/unit/spec/voicea-plugin.js +12 -0
- package/test/unit/spec/voicea.js +238 -4
package/dist/voicea.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_events","_interopRequireDefault","require","_uuid","_webexCore","_constants","_utils","ownKeys","e","r","t","_Object$keys","_Object$getOwnPropertySymbols","o","filter","_Object$getOwnPropertyDescriptor","enumerable","push","apply","_objectSpread","arguments","length","Object","forEach","_defineProperty2","default","_Object$getOwnPropertyDescriptors","_Object$defineProperties","_Object$defineProperty","_callSuper","_getPrototypeOf2","_possibleConstructorReturn2","_isNativeReflectConstruct","_Reflect$construct","constructor","Boolean","prototype","valueOf","call","VoiceaChannel","exports","_EventEmitter","llmChannel","request","_this","_classCallCheck2","_e$headers","seqNum","sequenceNumber","data","relayType","AIBRIDGE_RELAY_TYPES","VOICEA","ANNOUNCEMENT","onCaptionServiceIdUpdate","headers","from","announceStatus","ANNOUNCE_STATUS","JOINED","processAnnouncementMessage","voiceaPayload","TRANSLATION_RESPONSE","processCaptionLanguageResponse","TRANSCRIPTION","processTranscription","SPEAKER_NAME_UPDATE","processSpeakerNameUpdate","MANUAL","CAPTIONER","processManualTranscription","transcriptPayload","sender","data_source","type","TRANSCRIPTION_TYPE","MANUAL_CAPTION_FINAL_RESULT","MANUAL_CAPTION_INTERIM_RESULT","emit","EVENT_TRIGGERS","NEW_MANUAL_CAPTION","isFinal","transcriptId","id","transcripts","source","SPEAKER_NAME_UPDATED","_voiceaPayload$transc","_voiceaPayload$highli","_voiceaPayload$highli2","_voiceaPayload$highli3","_voiceaPayload$highli4","_voiceaPayload$highli5","_voiceaPayload$highli6","_voiceaPayload$highli7","TRANSCRIPT_INTERIM_RESULTS","NEW_CAPTION","transcript_id","TRANSCRIPT_FINAL_RESULT","map","transcript","timestamp","millisToMinutesAndSeconds","end_millis","HIGHLIGHT_CREATED","csis","highlight","highlightId","highlight_id","text","highlightLabel","highlight_label","highlightSource","highlight_source","EVA_THANKS","EVA_COMMAND","isListening","command_response","EVA_WAKE","EVA_CANCEL","LANGUAGE_DETECTED","isInSpokenLanguages","spokenLanguages","includes","language","languageCode","statusCode","CAPTION_LANGUAGE_UPDATE","errorCode","errorMessage","message","_voiceaPayload$transl","_voiceaPayload$transl2","_voiceaPayload$transl3","_voiceaPayload$transl4","_voiceaPayload$ASR$sp","_voiceaPayload$ASR","_voiceaPayload$ASR$sp2","_voiceaPayload$ASR2","voiceaLanguageOptions","captionLanguages","translation","allowed_languages","maxLanguages","max_languages","ASR","spoken_languages","currentSpokenLanguage","VOICEA_ANNOUNCEMENT","isConnected","keepTranscriptionSubscribed","JOINING","socket","getSocket","binding","getBinding","payload","concat","recipients","route","captionServiceId","to","clientPayload","version","eventType","CLIENT_ANNOUNCEMENT","trackingId","config","trackingIdPrefix","uuid","v4","toString","send","languageAssignment","method","url","getLocusUrl","body","transcribe","spokenLanguage","then","SPOKEN_LANGUAGE_UPDATE","isLLMConnected","translationLanguage","TRANSLATION_REQUEST","currentCaptionLanguage","timeStamp","start_millis","captionStatus","TURN_ON_CAPTION_STATUS","SENDING","locusUrl","caption","CAPTIONS_TURNED_ON","areCaptionsEnabled","ENABLED","announce","updateSubchannelSubscriptionsAndSyncCaptionState","subscribe","catch","error","IDLE","Error","isAnnounceProcessed","sendAnnouncement","_ref","_asyncToGenerator2","_regenerator","mark","_callee","wrap","_context","prev","next","abrupt","undefined","requestTurnOnCaptions","stop","_x","activate","transcribing","turnOnCaptions","enable","toggleManualCaptionStatus","TOGGLE_MANUAL_CAPTION_STATUS","manualCaption","meetingId","serviceId","requestLanguage","_callee2","_ref3","_ref3$subscribe","_ref3$unsubscribe","unsubscribe","isDataChannelTokenEnabled","datachannelUrl","_args2","_context2","sent","getDatachannelUrl","datachannelUri","options","keepSubscribed","updateSubchannelSubscriptions","DEFAULT_SPOKEN_LANGUAGE","on","eventProcessor","hasSubscribedToEvents","_inherits2","_createClass2","key","value","deregisterEvents","off","_switchLLMChannel","_callee3","newLLMChannel","captionsWereOn","_context3","switchLLMChannel","_x2","EventEmitter","_default"],"sources":["voicea.ts"],"sourcesContent":["import EventEmitter from 'events';\nimport uuid from 'uuid';\n// @ts-ignore - webex-core types\nimport {config} from '@webex/webex-core';\n\n// @ts-ignore - internal-plugin-llm types\nimport type LLMChannel from '@webex/internal-plugin-llm';\nimport {\n EVENT_TRIGGERS,\n AIBRIDGE_RELAY_TYPES,\n TRANSCRIPTION_TYPE,\n ANNOUNCE_STATUS,\n TURN_ON_CAPTION_STATUS,\n TOGGLE_MANUAL_CAPTION_STATUS,\n DEFAULT_SPOKEN_LANGUAGE,\n} from './constants';\nimport {\n AnnouncementPayload,\n CaptionLanguageResponse,\n SpeakerNameUpdatePayload,\n TranscriptionResponse,\n IVoiceaChannel,\n} from './voicea.types';\nimport {millisToMinutesAndSeconds} from './utils';\n\n/**\n * @description VoiceaChannel — handles voicea/transcription functionality for a single LLM connection.\n * Created via `webex.internal.voicea.createChannel(llmChannel)`. The caller owns the\n * channel and is responsible for its lifecycle.\n * @export\n * @class VoiceaChannel\n */\nexport class VoiceaChannel extends EventEmitter implements IVoiceaChannel {\n private request: (options: {method: string; url: string; body?: object}) => Promise<any>;\n private llmChannel: LLMChannel;\n\n private seqNum: number;\n private areCaptionsEnabled: boolean;\n private hasSubscribedToEvents = false;\n private captionServiceId?: string;\n private announceStatus: string;\n private captionStatus: string;\n\n private keepTranscriptionSubscribed: boolean;\n\n private toggleManualCaptionStatus: string;\n private currentSpokenLanguage?: string;\n private spokenLanguages: string[] = [];\n private currentCaptionLanguage?: string;\n\n /**\n * Creates a VoiceaChannel bound to the given LLMChannel\n * @param {LLMChannel} llmChannel - The LLM channel to use\n * @param {Function} request - The request function for making API calls (typically webex.request bound to webex)\n */\n constructor(\n llmChannel: LLMChannel,\n request: (options: {method: string; url: string; body?: object}) => Promise<any>\n ) {\n super();\n this.llmChannel = llmChannel;\n this.request = request;\n\n this.seqNum = 1;\n this.areCaptionsEnabled = false;\n this.captionServiceId = undefined;\n this.announceStatus = ANNOUNCE_STATUS.IDLE;\n this.captionStatus = TURN_ON_CAPTION_STATUS.IDLE;\n this.toggleManualCaptionStatus = TOGGLE_MANUAL_CAPTION_STATUS.IDLE;\n this.currentSpokenLanguage = DEFAULT_SPOKEN_LANGUAGE;\n this.currentCaptionLanguage = undefined;\n this.keepTranscriptionSubscribed = false;\n\n // Subscribe to relay events from the LLM channel\n this.llmChannel.on('event:relay.event', this.eventProcessor);\n this.hasSubscribedToEvents = true;\n }\n\n /**\n * Process events from LLM channel\n * @param {Object} e - Event data\n * @returns {void}\n */\n private eventProcessor = (e: any): void => {\n this.seqNum = e.sequenceNumber + 1;\n switch (e.data.relayType) {\n case AIBRIDGE_RELAY_TYPES.VOICEA.ANNOUNCEMENT:\n this.onCaptionServiceIdUpdate(e.headers.from);\n this.announceStatus = ANNOUNCE_STATUS.JOINED;\n this.processAnnouncementMessage(e.data.voiceaPayload);\n break;\n case AIBRIDGE_RELAY_TYPES.VOICEA.TRANSLATION_RESPONSE:\n this.processCaptionLanguageResponse(e.data.voiceaPayload);\n break;\n case AIBRIDGE_RELAY_TYPES.VOICEA.TRANSCRIPTION:\n this.processTranscription(e.data.voiceaPayload);\n break;\n case AIBRIDGE_RELAY_TYPES.VOICEA.SPEAKER_NAME_UPDATE:\n this.processSpeakerNameUpdate(e.data.voiceaPayload);\n break;\n case AIBRIDGE_RELAY_TYPES.MANUAL.TRANSCRIPTION:\n case AIBRIDGE_RELAY_TYPES.MANUAL.CAPTIONER:\n this.processManualTranscription({\n ...e.data.transcriptPayload,\n sender: e.headers?.from,\n data_source: e.data.relayType,\n });\n break;\n default:\n break;\n }\n };\n\n /**\n * Deregister events and clean up\n * @returns {void}\n */\n public deregisterEvents(): void {\n this.areCaptionsEnabled = false;\n this.keepTranscriptionSubscribed = false;\n this.captionServiceId = undefined;\n\n if (this.hasSubscribedToEvents) {\n this.llmChannel.off('event:relay.event', this.eventProcessor);\n this.hasSubscribedToEvents = false;\n }\n\n this.announceStatus = ANNOUNCE_STATUS.IDLE;\n this.captionStatus = TURN_ON_CAPTION_STATUS.IDLE;\n this.toggleManualCaptionStatus = TOGGLE_MANUAL_CAPTION_STATUS.IDLE;\n this.currentSpokenLanguage = undefined;\n this.currentCaptionLanguage = undefined;\n }\n\n /**\n * Switch to a different LLM channel while preserving caption state.\n * Used when transitioning between main meeting and practice session.\n * - Preserves keepTranscriptionSubscribed and spokenLanguage state\n * - Unsubscribes from old channel, subscribes to new channel\n * - Re-announces and re-enables captions if they were on\n * @param {LLMChannel} newLLMChannel - The new LLM channel to switch to\n * @returns {Promise<void>}\n */\n public async switchLLMChannel(newLLMChannel: LLMChannel): Promise<void> {\n // Save current state\n const captionsWereOn = this.keepTranscriptionSubscribed;\n const spokenLanguage = this.currentSpokenLanguage;\n\n // Unsubscribe from old channel\n if (this.hasSubscribedToEvents && this.llmChannel) {\n this.llmChannel.off('event:relay.event', this.eventProcessor);\n this.hasSubscribedToEvents = false;\n }\n\n // Switch to new channel\n this.llmChannel = newLLMChannel;\n\n // Subscribe to new channel\n this.llmChannel.on('event:relay.event', this.eventProcessor);\n this.hasSubscribedToEvents = true;\n\n // Reset announcement state for new connection\n this.announceStatus = ANNOUNCE_STATUS.IDLE;\n this.captionStatus = TURN_ON_CAPTION_STATUS.IDLE;\n this.captionServiceId = undefined;\n this.areCaptionsEnabled = false;\n\n // Re-announce and re-enable captions if they were on\n if (captionsWereOn) {\n await this.turnOnCaptions(spokenLanguage);\n }\n }\n\n /**\n * Process manual Transcript and send alert\n * @param {TranscriptionResponse} transcriptPayload\n * @returns {void}\n */\n private processManualTranscription = (transcriptPayload: TranscriptionResponse): void => {\n if (\n transcriptPayload.type === TRANSCRIPTION_TYPE.MANUAL_CAPTION_FINAL_RESULT ||\n transcriptPayload.type === TRANSCRIPTION_TYPE.MANUAL_CAPTION_INTERIM_RESULT\n ) {\n this.emit(EVENT_TRIGGERS.NEW_MANUAL_CAPTION, {\n isFinal: transcriptPayload.type === TRANSCRIPTION_TYPE.MANUAL_CAPTION_FINAL_RESULT,\n transcriptId: transcriptPayload.id,\n transcripts: transcriptPayload.transcripts,\n sender: transcriptPayload.sender,\n source: transcriptPayload.data_source,\n });\n }\n };\n\n /**\n * Process speaker name update and send alert\n * @param {SpeakerNameUpdatePayload} voiceaPayload\n * @returns {void}\n */\n private processSpeakerNameUpdate = (voiceaPayload: SpeakerNameUpdatePayload): void => {\n // @ts-ignore\n this.emit(EVENT_TRIGGERS.SPEAKER_NAME_UPDATED, voiceaPayload);\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 this.emit(EVENT_TRIGGERS.NEW_CAPTION, {\n isFinal: false,\n transcriptId: voiceaPayload.transcript_id,\n transcripts: voiceaPayload.transcripts,\n });\n break;\n\n case TRANSCRIPTION_TYPE.TRANSCRIPT_FINAL_RESULT:\n this.emit(EVENT_TRIGGERS.NEW_CAPTION, {\n isFinal: true,\n transcriptId: voiceaPayload.transcript_id,\n transcripts: voiceaPayload.transcripts?.map((transcript) => {\n transcript.timestamp = millisToMinutesAndSeconds(transcript.end_millis);\n\n return transcript;\n }),\n });\n break;\n\n case TRANSCRIPTION_TYPE.HIGHLIGHT_CREATED:\n this.emit(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 ?? 0),\n });\n break;\n\n case TRANSCRIPTION_TYPE.EVA_THANKS:\n this.emit(EVENT_TRIGGERS.EVA_COMMAND, {\n isListening: false,\n text: voiceaPayload.command_response,\n });\n break;\n\n case TRANSCRIPTION_TYPE.EVA_WAKE:\n case TRANSCRIPTION_TYPE.EVA_CANCEL:\n this.emit(EVENT_TRIGGERS.EVA_COMMAND, {\n isListening: voiceaPayload.type === TRANSCRIPTION_TYPE.EVA_WAKE,\n });\n break;\n\n case TRANSCRIPTION_TYPE.LANGUAGE_DETECTED: {\n const isInSpokenLanguages = this.spokenLanguages.includes(voiceaPayload.language);\n if (isInSpokenLanguages) {\n this.emit(EVENT_TRIGGERS.LANGUAGE_DETECTED, {\n languageCode: voiceaPayload.language,\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 this.emit(EVENT_TRIGGERS.CAPTION_LANGUAGE_UPDATE, {statusCode: 200});\n } else {\n this.emit(EVENT_TRIGGERS.CAPTION_LANGUAGE_UPDATE, {\n statusCode: voiceaPayload.errorCode,\n 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 currentSpokenLanguage: this.currentSpokenLanguage,\n };\n\n this.spokenLanguages = voiceaPayload?.ASR?.spoken_languages ?? [];\n this.emit(EVENT_TRIGGERS.VOICEA_ANNOUNCEMENT, voiceaLanguageOptions);\n };\n\n /**\n * Indicates whether the LLM channel is connected.\n * @returns {boolean}\n */\n public isLLMConnected = (): boolean => this.llmChannel.isConnected();\n\n public getKeepTranscriptionSubscribed = (): boolean => this.keepTranscriptionSubscribed;\n\n /**\n * Sends Announcement to add voicea to the meeting\n * @returns {void}\n */\n public sendAnnouncement = (): void => {\n this.announceStatus = ANNOUNCE_STATUS.JOINING;\n const socket = this.llmChannel.getSocket();\n const binding = this.llmChannel.getBinding();\n\n const payload = {\n id: `${this.seqNum}`,\n type: 'publishRequest',\n recipients: [\n {\n route: binding,\n },\n ],\n // If captionServiceId exists, send it as the 'to' header; otherwise keep headers empty.\n headers: this.captionServiceId ? {to: this.captionServiceId} : {},\n data: {\n clientPayload: {\n version: 'v2',\n },\n eventType: 'relay.event',\n relayType: AIBRIDGE_RELAY_TYPES.VOICEA.CLIENT_ANNOUNCEMENT,\n },\n trackingId: `${config.trackingIdPrefix}_${uuid.v4().toString()}`,\n };\n socket.send(payload);\n this.seqNum += 1;\n };\n\n /**\n * Set Spoken Language for the meeting\n * @param {string} languageCode\n * @param {\"DEFAULT\" | \"AUTO\" | \"MANUAL\"} languageAssignment\n * @returns {Promise}\n */\n public setSpokenLanguage = (\n languageCode: string,\n languageAssignment?: 'DEFAULT' | 'AUTO' | 'MANUAL'\n ): Promise<void> =>\n this.request({\n method: 'PUT',\n url: `${this.llmChannel.getLocusUrl()}/controls/`,\n body: {\n transcribe: {\n spokenLanguage: languageCode,\n ...(languageAssignment && {languageAssignment}),\n },\n },\n }).then(() => {\n this.emit(EVENT_TRIGGERS.SPOKEN_LANGUAGE_UPDATE, {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.isLLMConnected()) {\n return;\n }\n\n const socket = this.llmChannel.getSocket();\n const binding = this.llmChannel.getBinding();\n\n socket.send({\n id: `${this.seqNum}`,\n type: 'publishRequest',\n recipients: [\n {\n route: binding,\n },\n ],\n headers: {\n to: this.captionServiceId,\n },\n data: {\n clientPayload: {\n translationLanguage: languageCode,\n id: uuid.v4(),\n },\n eventType: 'relay.event',\n relayType: AIBRIDGE_RELAY_TYPES.VOICEA.TRANSLATION_REQUEST,\n },\n trackingId: `${config.trackingIdPrefix}_${uuid.v4().toString()}`,\n });\n this.currentCaptionLanguage = languageCode;\n this.seqNum += 1;\n };\n\n /**\n * Send manual closed captions to voicea service\n * @param {string} text\n * @param {number} timeStamp\n * @param {number[]} csis\n * @param {boolean} isFinal\n * @returns {void}\n */\n public sendManualClosedCaption = (\n text: string,\n timeStamp: number,\n csis: number[],\n isFinal: boolean\n ): void => {\n if (!this.isLLMConnected()) {\n return;\n }\n\n const socket = this.llmChannel.getSocket();\n const binding = this.llmChannel.getBinding();\n\n socket?.send({\n id: `${this.seqNum}`,\n type: 'publishRequest',\n recipients: [\n {\n route: binding,\n },\n ],\n headers: {},\n data: {\n eventType: 'relay.event',\n relayType: AIBRIDGE_RELAY_TYPES.MANUAL.CAPTIONER,\n transcriptPayload: {\n type: isFinal\n ? TRANSCRIPTION_TYPE.MANUAL_CAPTION_FINAL_RESULT\n : TRANSCRIPTION_TYPE.MANUAL_CAPTION_INTERIM_RESULT,\n id: uuid.v4(),\n transcripts: [\n {\n text,\n start_millis: timeStamp,\n end_millis: timeStamp,\n csis,\n },\n ],\n transcript_id: uuid.v4(),\n },\n },\n trackingId: `${config.trackingIdPrefix}_${uuid.v4().toString()}`,\n });\n this.seqNum += 1;\n };\n\n /**\n * request turn on Captions\n * @param {string} [languageCode] - Optional Parameter for spoken language code\n * @returns {Promise}\n */\n private requestTurnOnCaptions = (languageCode?: string): undefined | Promise<void> => {\n this.captionStatus = TURN_ON_CAPTION_STATUS.SENDING;\n\n const locusUrl = this.llmChannel.getLocusUrl();\n\n const body = {\n transcribe: {caption: true},\n languageCode,\n };\n\n return this.request({\n method: 'PUT',\n url: `${locusUrl}/controls/`,\n body,\n })\n .then(() => {\n this.emit(EVENT_TRIGGERS.CAPTIONS_TURNED_ON);\n\n this.areCaptionsEnabled = true;\n this.captionStatus = TURN_ON_CAPTION_STATUS.ENABLED;\n this.announce();\n this.updateSubchannelSubscriptionsAndSyncCaptionState({subscribe: ['transcription']}, true);\n })\n .catch((error) => {\n this.captionStatus = TURN_ON_CAPTION_STATUS.IDLE;\n throw new Error('turn on captions fail');\n });\n };\n\n /**\n * is announce processing\n * @returns {boolean}\n */\n private isAnnounceProcessing = (): boolean =>\n [ANNOUNCE_STATUS.JOINING, ANNOUNCE_STATUS.JOINED].includes(this.announceStatus);\n\n /**\n * is announce processed\n * @returns {boolean}\n */\n private isAnnounceProcessed = (): boolean => this.announceStatus === ANNOUNCE_STATUS.JOINED;\n\n /**\n * announce to voicea data channel\n * @returns {void}\n */\n public announce = (): void => {\n if (this.isAnnounceProcessed()) {\n return;\n }\n if (!this.isLLMConnected()) {\n throw new Error('voicea can not announce before llm connected');\n }\n this.sendAnnouncement();\n };\n\n /**\n * is turn on caption processing\n * @returns {boolean}\n */\n private isCaptionProcessing = (): boolean =>\n [TURN_ON_CAPTION_STATUS.SENDING, TURN_ON_CAPTION_STATUS.ENABLED].includes(this.captionStatus);\n\n /**\n * Turn on Captions\n * @param {string} [spokenLanguage] - Optional Spoken language code\n * @returns {Promise}\n */\n public turnOnCaptions = async (spokenLanguage?: string): Promise<void | undefined> => {\n if (this.captionStatus === TURN_ON_CAPTION_STATUS.SENDING) return undefined;\n\n if (!this.isLLMConnected()) {\n throw new Error('can not turn on captions before llm connected');\n }\n\n return this.requestTurnOnCaptions(spokenLanguage);\n };\n\n /**\n * Toggle transcribing for highlights\n * @param {boolean} activate true means to turn on transcribing and false means to turn off\n * @param {string} spokenLanguage language code for spoken language\n * @returns {Promise}\n */\n public toggleTranscribing = (\n activate: boolean,\n spokenLanguage?: string\n ): undefined | Promise<void> => {\n return this.request({\n method: 'PUT',\n url: `${this.llmChannel.getLocusUrl()}/controls/`,\n body: {\n transcribe: {\n transcribing: activate,\n },\n spokenLanguage,\n },\n }).then((): undefined | Promise<void> => {\n if (activate && !this.areCaptionsEnabled) {\n return this.turnOnCaptions(spokenLanguage);\n }\n\n return undefined;\n });\n };\n\n /**\n * Toggle turn on manual caption\n * @param {boolean} enable true means to turn on manual caption, false means to turn off\n * @returns {Promise}\n */\n public toggleManualCaption = (enable: boolean): undefined | Promise<void> => {\n if (this.toggleManualCaptionStatus === TOGGLE_MANUAL_CAPTION_STATUS.SENDING) return undefined;\n\n this.toggleManualCaptionStatus = TOGGLE_MANUAL_CAPTION_STATUS.SENDING;\n\n return this.request({\n method: 'PUT',\n url: `${this.llmChannel.getLocusUrl()}/controls/`,\n body: {\n manualCaption: {\n enable,\n },\n },\n })\n .then((): undefined | Promise<void> => {\n this.toggleManualCaptionStatus = TOGGLE_MANUAL_CAPTION_STATUS.IDLE;\n\n return undefined;\n })\n .catch(() => {\n this.toggleManualCaptionStatus = TOGGLE_MANUAL_CAPTION_STATUS.IDLE;\n throw new Error('toggle manual captions fail');\n });\n };\n\n /**\n * In meeting Spoken Language changed event\n * @param {string} languageCode\n * @param {string} meetingId\n * @returns {void}\n */\n public onSpokenLanguageUpdate = (languageCode: string, meetingId: string): void => {\n this.emit(EVENT_TRIGGERS.SPOKEN_LANGUAGE_UPDATE, {languageCode, meetingId});\n this.currentSpokenLanguage = languageCode;\n };\n\n /**\n * In meeting Spoken Language changed event\n * @param {string} serviceId\n * @returns {void}\n */\n public onCaptionServiceIdUpdate = (serviceId: string): void => {\n if (!serviceId) {\n return;\n }\n if (this.captionServiceId !== serviceId) {\n this.captionServiceId = serviceId;\n if (this.currentCaptionLanguage) {\n this.requestLanguage(this.currentCaptionLanguage);\n }\n }\n };\n\n /**\n * get caption status\n * @returns {string}\n */\n public getCaptionStatus = (): string => this.captionStatus;\n\n /**\n * get announce status\n * @returns {string}\n */\n public getAnnounceStatus = (): string => this.announceStatus;\n\n /**\n * update LLM sub‑channel subscriptions.\n *\n * @param {string[]} options.subscribe Sub‑channels to subscribe to.\n * @param {string[]} options.unsubscribe Sub‑channels to unsubscribe from.\n * @returns {Promise}\n */\n public updateSubchannelSubscriptions = async ({\n subscribe = [],\n unsubscribe = [],\n }: {\n subscribe?: string[];\n unsubscribe?: string[];\n } = {}): Promise<void> => {\n if (!this.isLLMConnected()) return;\n\n const isDataChannelTokenEnabled = await this.llmChannel.isDataChannelTokenEnabled();\n if (!isDataChannelTokenEnabled) return;\n\n const socket = this.llmChannel.getSocket();\n const datachannelUrl = this.llmChannel.getDatachannelUrl();\n\n socket.send({\n id: `${this.seqNum}`,\n type: 'subchannelSubscriptionRequest',\n data: {\n datachannelUri: datachannelUrl,\n subscribe,\n unsubscribe,\n },\n trackingId: `${config.trackingIdPrefix}_${uuid.v4().toString()}`,\n });\n\n this.seqNum += 1;\n };\n\n /**\n * Updates transcription subchannel subscriptions and records whether the\n * transcription subscription should be kept (and restored on reconnect).\n *\n * @param {Object} [options] - Subscription options.\n * @param {string[]} [options.subscribe] - Subchannels to subscribe to.\n * @param {string[]} [options.unsubscribe] - Subchannels to unsubscribe from.\n * @param {boolean} [keepSubscribed=false] - Whether the transcription\n * subscription should be kept and restored on reconnect.\n *\n * @returns {Promise<void>}\n */\n public updateSubchannelSubscriptionsAndSyncCaptionState = (\n options: {\n subscribe?: string[];\n unsubscribe?: string[];\n } = {},\n keepSubscribed = false\n ): Promise<void> => {\n this.keepTranscriptionSubscribed = keepSubscribed;\n\n return this.updateSubchannelSubscriptions(options);\n };\n}\n\nexport default VoiceaChannel;\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["_events","_interopRequireDefault","require","_uuid","_webexCore","_constants","_utils","ownKeys","e","r","t","_Object$keys","_Object$getOwnPropertySymbols","o","filter","_Object$getOwnPropertyDescriptor","enumerable","push","apply","_objectSpread","arguments","length","Object","forEach","_defineProperty2","default","_Object$getOwnPropertyDescriptors","_Object$defineProperties","_Object$defineProperty","_callSuper","_getPrototypeOf2","_possibleConstructorReturn2","_isNativeReflectConstruct","_Reflect$construct","constructor","Boolean","prototype","valueOf","call","VoiceaChannel","exports","_EventEmitter","llmChannel","request","_this","_classCallCheck2","_e$headers","seqNum","sequenceNumber","data","relayType","AIBRIDGE_RELAY_TYPES","VOICEA","ANNOUNCEMENT","onCaptionServiceIdUpdate","headers","from","announceStatus","ANNOUNCE_STATUS","JOINED","processAnnouncementMessage","voiceaPayload","TRANSLATION_RESPONSE","processCaptionLanguageResponse","TRANSCRIPTION","processTranscription","SPEAKER_NAME_UPDATE","processSpeakerNameUpdate","MANUAL","CAPTIONER","processManualTranscription","transcriptPayload","sender","data_source","type","TRANSCRIPTION_TYPE","MANUAL_CAPTION_FINAL_RESULT","MANUAL_CAPTION_INTERIM_RESULT","emit","EVENT_TRIGGERS","NEW_MANUAL_CAPTION","isFinal","transcriptId","id","transcripts","source","SPEAKER_NAME_UPDATED","_voiceaPayload$transc","_voiceaPayload$highli","_voiceaPayload$highli2","_voiceaPayload$highli3","_voiceaPayload$highli4","_voiceaPayload$highli5","_voiceaPayload$highli6","_voiceaPayload$highli7","TRANSCRIPT_INTERIM_RESULTS","NEW_CAPTION","transcript_id","TRANSCRIPT_FINAL_RESULT","map","transcript","timestamp","millisToMinutesAndSeconds","end_millis","HIGHLIGHT_CREATED","csis","highlight","highlightId","highlight_id","text","highlightLabel","highlight_label","highlightSource","highlight_source","EVA_THANKS","EVA_COMMAND","isListening","command_response","EVA_WAKE","EVA_CANCEL","LANGUAGE_DETECTED","isInSpokenLanguages","spokenLanguages","includes","language","languageCode","statusCode","CAPTION_LANGUAGE_UPDATE","errorCode","errorMessage","message","_voiceaPayload$transl","_voiceaPayload$transl2","_voiceaPayload$transl3","_voiceaPayload$transl4","_voiceaPayload$ASR$sp","_voiceaPayload$ASR","_voiceaPayload$ASR$sp2","_voiceaPayload$ASR2","voiceaLanguageOptions","captionLanguages","translation","allowed_languages","maxLanguages","max_languages","ASR","spoken_languages","currentSpokenLanguage","VOICEA_ANNOUNCEMENT","_this$llmChannel$isCo","_this$llmChannel","isConnected","keepTranscriptionSubscribed","llm","requireLLMChannel","JOINING","socket","getSocket","binding","getBinding","payload","concat","recipients","route","captionServiceId","to","clientPayload","version","eventType","CLIENT_ANNOUNCEMENT","trackingId","config","trackingIdPrefix","uuid","v4","toString","send","languageAssignment","method","url","getLocusUrl","body","transcribe","spokenLanguage","then","SPOKEN_LANGUAGE_UPDATE","isLLMConnected","translationLanguage","TRANSLATION_REQUEST","currentCaptionLanguage","timeStamp","start_millis","captionStatus","TURN_ON_CAPTION_STATUS","SENDING","locusUrl","caption","CAPTIONS_TURNED_ON","areCaptionsEnabled","ENABLED","announce","updateSubchannelSubscriptionsAndSyncCaptionState","subscribe","catch","error","IDLE","Error","cause","isAnnounceProcessed","sendAnnouncement","_ref","_asyncToGenerator2","_regenerator","mark","_callee","wrap","_context","prev","next","isCaptionProcessing","abrupt","undefined","requestTurnOnCaptions","stop","_x","activate","transcribing","turnOnCaptions","enable","toggleManualCaptionStatus","TOGGLE_MANUAL_CAPTION_STATUS","manualCaption","meetingId","serviceId","requestLanguage","_callee2","_ref3","_ref3$subscribe","_ref3$unsubscribe","unsubscribe","isDataChannelTokenEnabled","datachannelUrl","_args2","_context2","sent","getDatachannelUrl","datachannelUri","options","keepSubscribed","updateSubchannelSubscriptions","DEFAULT_SPOKEN_LANGUAGE","on","eventProcessor","hasSubscribedToEvents","_inherits2","_createClass2","key","value","deregisterEvents","targetLLMChannel","_pendingCaptionRestore","detachPendingOnline","_this$llmChannel2","off","attachPendingOnline","channel","callback","_pendingOnlineListener","once","resetAnnounceState","reconcile","_this2","target","_promise","resolve","switchLLMChannel","newLLMChannel","EventEmitter","_default"],"sources":["voicea.ts"],"sourcesContent":["import EventEmitter from 'events';\nimport uuid from 'uuid';\n// @ts-ignore - webex-core types\nimport {config} from '@webex/webex-core';\n\n// @ts-ignore - internal-plugin-llm types\nimport type LLMChannel from '@webex/internal-plugin-llm';\nimport {\n EVENT_TRIGGERS,\n AIBRIDGE_RELAY_TYPES,\n TRANSCRIPTION_TYPE,\n ANNOUNCE_STATUS,\n TURN_ON_CAPTION_STATUS,\n TOGGLE_MANUAL_CAPTION_STATUS,\n DEFAULT_SPOKEN_LANGUAGE,\n} from './constants';\nimport {\n AnnouncementPayload,\n CaptionLanguageResponse,\n SpeakerNameUpdatePayload,\n TranscriptionResponse,\n IVoiceaChannel,\n} from './voicea.types';\nimport {millisToMinutesAndSeconds} from './utils';\n\n/**\n * @description VoiceaChannel — handles voicea/transcription functionality for a single LLM connection.\n * Created via `webex.internal.voicea.createChannel(llmChannel)`. The caller owns the\n * channel and is responsible for its lifecycle.\n * @export\n * @class VoiceaChannel\n */\nexport class VoiceaChannel extends EventEmitter implements IVoiceaChannel {\n private request: (options: {method: string; url: string; body?: object}) => Promise<any>;\n private llmChannel?: LLMChannel;\n\n private seqNum: number;\n private areCaptionsEnabled: boolean;\n private hasSubscribedToEvents = false;\n private captionServiceId?: string;\n private announceStatus: string;\n private captionStatus: string;\n\n private keepTranscriptionSubscribed: boolean;\n\n private toggleManualCaptionStatus: string;\n private currentSpokenLanguage?: string;\n private spokenLanguages: string[] = [];\n private currentCaptionLanguage?: string;\n\n // Target channel for reconciler pattern - the channel voicea WANTS to be bound to\n private targetLLMChannel?: LLMChannel;\n // Single pending 'online' listener for deferred reconciliation\n private _pendingOnlineListener?: () => void;\n // Tracks whether caption restoration is pending (set on switch, cleared on restore)\n private _pendingCaptionRestore = false;\n\n /**\n * Creates a VoiceaChannel, optionally bound to an LLMChannel.\n * If no llmChannel is provided, call switchLLMChannel() later to attach one.\n * @param {LLMChannel} [llmChannel] - The LLM channel to use (optional)\n * @param {Function} request - The request function for making API calls (typically webex.request bound to webex)\n */\n constructor(\n llmChannel: LLMChannel | undefined,\n request: (options: {method: string; url: string; body?: object}) => Promise<any>\n ) {\n super();\n this.llmChannel = llmChannel;\n this.request = request;\n\n this.seqNum = 1;\n this.areCaptionsEnabled = false;\n this.captionServiceId = undefined;\n this.announceStatus = ANNOUNCE_STATUS.IDLE;\n this.captionStatus = TURN_ON_CAPTION_STATUS.IDLE;\n this.toggleManualCaptionStatus = TOGGLE_MANUAL_CAPTION_STATUS.IDLE;\n this.currentSpokenLanguage = DEFAULT_SPOKEN_LANGUAGE;\n this.currentCaptionLanguage = undefined;\n this.keepTranscriptionSubscribed = false;\n\n // Subscribe to relay events from the LLM channel if provided\n if (this.llmChannel) {\n this.llmChannel.on('event:relay.event', this.eventProcessor);\n this.hasSubscribedToEvents = true;\n }\n }\n\n /**\n * Returns the LLM channel, throwing if not available.\n * @private\n * @returns {LLMChannel}\n * @throws {Error} If LLM channel is not available\n */\n private requireLLMChannel(): LLMChannel {\n if (!this.llmChannel) {\n throw new Error('VoiceaChannel: LLM channel not available');\n }\n\n return this.llmChannel;\n }\n\n /**\n * Process events from LLM channel\n * @param {Object} e - Event data\n * @returns {void}\n */\n private eventProcessor = (e: any): void => {\n this.seqNum = e.sequenceNumber + 1;\n switch (e.data.relayType) {\n case AIBRIDGE_RELAY_TYPES.VOICEA.ANNOUNCEMENT:\n this.onCaptionServiceIdUpdate(e.headers.from);\n this.announceStatus = ANNOUNCE_STATUS.JOINED;\n this.processAnnouncementMessage(e.data.voiceaPayload);\n break;\n case AIBRIDGE_RELAY_TYPES.VOICEA.TRANSLATION_RESPONSE:\n this.processCaptionLanguageResponse(e.data.voiceaPayload);\n break;\n case AIBRIDGE_RELAY_TYPES.VOICEA.TRANSCRIPTION:\n this.processTranscription(e.data.voiceaPayload);\n break;\n case AIBRIDGE_RELAY_TYPES.VOICEA.SPEAKER_NAME_UPDATE:\n this.processSpeakerNameUpdate(e.data.voiceaPayload);\n break;\n case AIBRIDGE_RELAY_TYPES.MANUAL.TRANSCRIPTION:\n case AIBRIDGE_RELAY_TYPES.MANUAL.CAPTIONER:\n this.processManualTranscription({\n ...e.data.transcriptPayload,\n sender: e.headers?.from,\n data_source: e.data.relayType,\n });\n break;\n default:\n break;\n }\n };\n\n /**\n * Deregister events and clean up\n * @returns {void}\n */\n public deregisterEvents(): void {\n this.areCaptionsEnabled = false;\n this.keepTranscriptionSubscribed = false;\n this.captionServiceId = undefined;\n this.targetLLMChannel = undefined;\n this._pendingCaptionRestore = false;\n\n // Remove any pending online listener\n this.detachPendingOnline();\n\n if (this.hasSubscribedToEvents) {\n this.llmChannel?.off('event:relay.event', this.eventProcessor);\n this.hasSubscribedToEvents = false;\n }\n\n this.announceStatus = ANNOUNCE_STATUS.IDLE;\n this.captionStatus = TURN_ON_CAPTION_STATUS.IDLE;\n this.toggleManualCaptionStatus = TOGGLE_MANUAL_CAPTION_STATUS.IDLE;\n this.currentSpokenLanguage = undefined;\n this.currentCaptionLanguage = undefined;\n }\n\n /**\n * Attach a pending 'online' listener to a channel for deferred reconciliation.\n * Detaches any existing listener first.\n * @param {LLMChannel} channel - The channel to attach to\n * @param {Function} callback - The callback to run when 'online' fires\n * @private\n * @returns {void}\n */\n private attachPendingOnline(channel: LLMChannel, callback: () => void): void {\n this.detachPendingOnline();\n this._pendingOnlineListener = callback;\n channel.once('online', this._pendingOnlineListener);\n }\n\n /**\n * Detach any pending 'online' listener.\n * @private\n * @returns {void}\n */\n private detachPendingOnline(): void {\n if (this._pendingOnlineListener && this.llmChannel) {\n this.llmChannel.off('online', this._pendingOnlineListener);\n }\n this._pendingOnlineListener = undefined;\n }\n\n /**\n * Reset announcement state for a new connection.\n * @private\n * @returns {void}\n */\n private resetAnnounceState(): void {\n this.announceStatus = ANNOUNCE_STATUS.IDLE;\n this.captionStatus = TURN_ON_CAPTION_STATUS.IDLE;\n this.captionServiceId = undefined;\n this.areCaptionsEnabled = false;\n }\n\n /**\n * Reconcile voicea binding and caption state to match the desired target.\n * This is idempotent - always re-reads targetLLMChannel and current state.\n * A deferred 'online' callback that fires late self-corrects automatically.\n * @private\n * @returns {Promise<void>}\n */\n private reconcile(): Promise<void> {\n const target = this.targetLLMChannel;\n if (!target) return Promise.resolve();\n\n // 1. Rebind relay-event subscription if actual != desired\n if (this.llmChannel !== target) {\n if (this.hasSubscribedToEvents && this.llmChannel) {\n this.llmChannel.off('event:relay.event', this.eventProcessor);\n }\n this.detachPendingOnline();\n this.llmChannel = target;\n this.llmChannel.on('event:relay.event', this.eventProcessor);\n this.hasSubscribedToEvents = true;\n this.resetAnnounceState();\n // Mark caption restoration as pending if captions were subscribed\n this._pendingCaptionRestore = this.keepTranscriptionSubscribed;\n }\n\n // 2. Restore captions if pending\n if (!this._pendingCaptionRestore) return Promise.resolve();\n\n if (this.isLLMConnected()) {\n // Channel is connected, restore captions immediately\n this._pendingCaptionRestore = false;\n\n return this.turnOnCaptions(this.currentSpokenLanguage)\n .then(() => undefined)\n .catch(() => {\n // Best-effort restoration\n });\n }\n // Channel not yet connected - defer until 'online' then re-reconcile.\n // If target changes meanwhile, reconcile() self-corrects.\n this.attachPendingOnline(target, () => {\n this.reconcile();\n });\n\n return Promise.resolve();\n }\n\n /**\n * Switch to a different LLM channel while preserving caption state.\n * Used when transitioning between main meeting and practice session.\n * This is a thin intent-setter - actual binding happens in reconcile().\n * @param {LLMChannel} newLLMChannel - The new LLM channel to switch to\n * @returns {Promise<void>}\n */\n public switchLLMChannel(newLLMChannel: LLMChannel): Promise<void> {\n this.targetLLMChannel = newLLMChannel;\n\n return this.reconcile();\n }\n\n /**\n * Process manual Transcript and send alert\n * @param {TranscriptionResponse} transcriptPayload\n * @returns {void}\n */\n private processManualTranscription = (transcriptPayload: TranscriptionResponse): void => {\n if (\n transcriptPayload.type === TRANSCRIPTION_TYPE.MANUAL_CAPTION_FINAL_RESULT ||\n transcriptPayload.type === TRANSCRIPTION_TYPE.MANUAL_CAPTION_INTERIM_RESULT\n ) {\n this.emit(EVENT_TRIGGERS.NEW_MANUAL_CAPTION, {\n isFinal: transcriptPayload.type === TRANSCRIPTION_TYPE.MANUAL_CAPTION_FINAL_RESULT,\n transcriptId: transcriptPayload.id,\n transcripts: transcriptPayload.transcripts,\n sender: transcriptPayload.sender,\n source: transcriptPayload.data_source,\n });\n }\n };\n\n /**\n * Process speaker name update and send alert\n * @param {SpeakerNameUpdatePayload} voiceaPayload\n * @returns {void}\n */\n private processSpeakerNameUpdate = (voiceaPayload: SpeakerNameUpdatePayload): void => {\n // @ts-ignore\n this.emit(EVENT_TRIGGERS.SPEAKER_NAME_UPDATED, voiceaPayload);\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 this.emit(EVENT_TRIGGERS.NEW_CAPTION, {\n isFinal: false,\n transcriptId: voiceaPayload.transcript_id,\n transcripts: voiceaPayload.transcripts,\n });\n break;\n\n case TRANSCRIPTION_TYPE.TRANSCRIPT_FINAL_RESULT:\n this.emit(EVENT_TRIGGERS.NEW_CAPTION, {\n isFinal: true,\n transcriptId: voiceaPayload.transcript_id,\n transcripts: voiceaPayload.transcripts?.map((transcript) => {\n transcript.timestamp = millisToMinutesAndSeconds(transcript.end_millis);\n\n return transcript;\n }),\n });\n break;\n\n case TRANSCRIPTION_TYPE.HIGHLIGHT_CREATED:\n this.emit(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 ?? 0),\n });\n break;\n\n case TRANSCRIPTION_TYPE.EVA_THANKS:\n this.emit(EVENT_TRIGGERS.EVA_COMMAND, {\n isListening: false,\n text: voiceaPayload.command_response,\n });\n break;\n\n case TRANSCRIPTION_TYPE.EVA_WAKE:\n case TRANSCRIPTION_TYPE.EVA_CANCEL:\n this.emit(EVENT_TRIGGERS.EVA_COMMAND, {\n isListening: voiceaPayload.type === TRANSCRIPTION_TYPE.EVA_WAKE,\n });\n break;\n\n case TRANSCRIPTION_TYPE.LANGUAGE_DETECTED: {\n const isInSpokenLanguages = this.spokenLanguages.includes(voiceaPayload.language);\n if (isInSpokenLanguages) {\n this.emit(EVENT_TRIGGERS.LANGUAGE_DETECTED, {\n languageCode: voiceaPayload.language,\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 this.emit(EVENT_TRIGGERS.CAPTION_LANGUAGE_UPDATE, {statusCode: 200});\n } else {\n this.emit(EVENT_TRIGGERS.CAPTION_LANGUAGE_UPDATE, {\n statusCode: voiceaPayload.errorCode,\n 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 currentSpokenLanguage: this.currentSpokenLanguage,\n };\n\n this.spokenLanguages = voiceaPayload?.ASR?.spoken_languages ?? [];\n this.emit(EVENT_TRIGGERS.VOICEA_ANNOUNCEMENT, voiceaLanguageOptions);\n };\n\n /**\n * Indicates whether the LLM channel is connected.\n * @returns {boolean}\n */\n public isLLMConnected = (): boolean => this.llmChannel?.isConnected() ?? false;\n\n public getKeepTranscriptionSubscribed = (): boolean => this.keepTranscriptionSubscribed;\n\n /**\n * Sends Announcement to add voicea to the meeting\n * @returns {void}\n */\n public sendAnnouncement = (): void => {\n const llm = this.requireLLMChannel();\n this.announceStatus = ANNOUNCE_STATUS.JOINING;\n const socket = llm.getSocket();\n const binding = llm.getBinding();\n\n const payload = {\n id: `${this.seqNum}`,\n type: 'publishRequest',\n recipients: [\n {\n route: binding,\n },\n ],\n // If captionServiceId exists, send it as the 'to' header; otherwise keep headers empty.\n headers: this.captionServiceId ? {to: this.captionServiceId} : {},\n data: {\n clientPayload: {\n version: 'v2',\n },\n eventType: 'relay.event',\n relayType: AIBRIDGE_RELAY_TYPES.VOICEA.CLIENT_ANNOUNCEMENT,\n },\n trackingId: `${config.trackingIdPrefix}_${uuid.v4().toString()}`,\n };\n socket.send(payload);\n this.seqNum += 1;\n };\n\n /**\n * Set Spoken Language for the meeting\n * @param {string} languageCode\n * @param {\"DEFAULT\" | \"AUTO\" | \"MANUAL\"} languageAssignment\n * @returns {Promise}\n */\n public setSpokenLanguage = (\n languageCode: string,\n languageAssignment?: 'DEFAULT' | 'AUTO' | 'MANUAL'\n ): Promise<void> =>\n this.request({\n method: 'PUT',\n url: `${this.requireLLMChannel().getLocusUrl()}/controls/`,\n body: {\n transcribe: {\n spokenLanguage: languageCode,\n ...(languageAssignment && {languageAssignment}),\n },\n },\n }).then(() => {\n this.emit(EVENT_TRIGGERS.SPOKEN_LANGUAGE_UPDATE, {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.isLLMConnected()) {\n return;\n }\n\n const llm = this.requireLLMChannel();\n const socket = llm.getSocket();\n const binding = llm.getBinding();\n\n socket.send({\n id: `${this.seqNum}`,\n type: 'publishRequest',\n recipients: [\n {\n route: binding,\n },\n ],\n headers: {\n to: this.captionServiceId,\n },\n data: {\n clientPayload: {\n translationLanguage: languageCode,\n id: uuid.v4(),\n },\n eventType: 'relay.event',\n relayType: AIBRIDGE_RELAY_TYPES.VOICEA.TRANSLATION_REQUEST,\n },\n trackingId: `${config.trackingIdPrefix}_${uuid.v4().toString()}`,\n });\n this.currentCaptionLanguage = languageCode;\n this.seqNum += 1;\n };\n\n /**\n * Send manual closed captions to voicea service\n * @param {string} text\n * @param {number} timeStamp\n * @param {number[]} csis\n * @param {boolean} isFinal\n * @returns {void}\n */\n public sendManualClosedCaption = (\n text: string,\n timeStamp: number,\n csis: number[],\n isFinal: boolean\n ): void => {\n if (!this.isLLMConnected()) {\n return;\n }\n\n const llm = this.requireLLMChannel();\n const socket = llm.getSocket();\n const binding = llm.getBinding();\n\n socket?.send({\n id: `${this.seqNum}`,\n type: 'publishRequest',\n recipients: [\n {\n route: binding,\n },\n ],\n headers: {},\n data: {\n eventType: 'relay.event',\n relayType: AIBRIDGE_RELAY_TYPES.MANUAL.CAPTIONER,\n transcriptPayload: {\n type: isFinal\n ? TRANSCRIPTION_TYPE.MANUAL_CAPTION_FINAL_RESULT\n : TRANSCRIPTION_TYPE.MANUAL_CAPTION_INTERIM_RESULT,\n id: uuid.v4(),\n transcripts: [\n {\n text,\n start_millis: timeStamp,\n end_millis: timeStamp,\n csis,\n },\n ],\n transcript_id: uuid.v4(),\n },\n },\n trackingId: `${config.trackingIdPrefix}_${uuid.v4().toString()}`,\n });\n this.seqNum += 1;\n };\n\n /**\n * request turn on Captions\n * @param {string} [languageCode] - Optional Parameter for spoken language code\n * @returns {Promise}\n */\n private requestTurnOnCaptions = (languageCode?: string): undefined | Promise<void> => {\n this.captionStatus = TURN_ON_CAPTION_STATUS.SENDING;\n\n const locusUrl = this.requireLLMChannel().getLocusUrl();\n\n const body = {\n transcribe: {caption: true},\n languageCode,\n };\n\n return this.request({\n method: 'PUT',\n url: `${locusUrl}/controls/`,\n body,\n })\n .then(() => {\n this.emit(EVENT_TRIGGERS.CAPTIONS_TURNED_ON);\n\n this.areCaptionsEnabled = true;\n this.captionStatus = TURN_ON_CAPTION_STATUS.ENABLED;\n this.announce();\n this.updateSubchannelSubscriptionsAndSyncCaptionState({subscribe: ['transcription']}, true);\n })\n .catch((error) => {\n this.captionStatus = TURN_ON_CAPTION_STATUS.IDLE;\n throw new Error('turn on captions fail', {cause: error});\n });\n };\n\n /**\n * is announce processing\n * @returns {boolean}\n */\n private isAnnounceProcessing = (): boolean =>\n [ANNOUNCE_STATUS.JOINING, ANNOUNCE_STATUS.JOINED].includes(this.announceStatus);\n\n /**\n * is announce processed\n * @returns {boolean}\n */\n private isAnnounceProcessed = (): boolean => this.announceStatus === ANNOUNCE_STATUS.JOINED;\n\n /**\n * announce to voicea data channel\n * @returns {void}\n */\n public announce = (): void => {\n if (this.isAnnounceProcessed()) {\n return;\n }\n if (!this.isLLMConnected()) {\n throw new Error('voicea can not announce before llm connected');\n }\n this.sendAnnouncement();\n };\n\n /**\n * is turn on caption processing\n * @returns {boolean}\n */\n private isCaptionProcessing = (): boolean =>\n [TURN_ON_CAPTION_STATUS.SENDING, TURN_ON_CAPTION_STATUS.ENABLED].includes(this.captionStatus);\n\n /**\n * Turn on Captions\n * @param {string} [spokenLanguage] - Optional Spoken language code\n * @returns {Promise}\n */\n public turnOnCaptions = async (spokenLanguage?: string): Promise<void | undefined> => {\n if (this.isCaptionProcessing()) return undefined;\n\n if (!this.isLLMConnected()) {\n throw new Error('can not turn on captions before llm connected');\n }\n\n return this.requestTurnOnCaptions(spokenLanguage);\n };\n\n /**\n * Toggle transcribing for highlights\n * @param {boolean} activate true means to turn on transcribing and false means to turn off\n * @param {string} spokenLanguage language code for spoken language\n * @returns {Promise}\n */\n public toggleTranscribing = (\n activate: boolean,\n spokenLanguage?: string\n ): undefined | Promise<void> => {\n return this.request({\n method: 'PUT',\n url: `${this.requireLLMChannel().getLocusUrl()}/controls/`,\n body: {\n transcribe: {\n transcribing: activate,\n },\n spokenLanguage,\n },\n }).then((): undefined | Promise<void> => {\n if (activate && !this.areCaptionsEnabled) {\n return this.turnOnCaptions(spokenLanguage);\n }\n\n return undefined;\n });\n };\n\n /**\n * Toggle turn on manual caption\n * @param {boolean} enable true means to turn on manual caption, false means to turn off\n * @returns {Promise}\n */\n public toggleManualCaption = (enable: boolean): undefined | Promise<void> => {\n if (this.toggleManualCaptionStatus === TOGGLE_MANUAL_CAPTION_STATUS.SENDING) return undefined;\n\n this.toggleManualCaptionStatus = TOGGLE_MANUAL_CAPTION_STATUS.SENDING;\n\n return this.request({\n method: 'PUT',\n url: `${this.requireLLMChannel().getLocusUrl()}/controls/`,\n body: {\n manualCaption: {\n enable,\n },\n },\n })\n .then((): undefined | Promise<void> => {\n this.toggleManualCaptionStatus = TOGGLE_MANUAL_CAPTION_STATUS.IDLE;\n\n return undefined;\n })\n .catch(() => {\n this.toggleManualCaptionStatus = TOGGLE_MANUAL_CAPTION_STATUS.IDLE;\n throw new Error('toggle manual captions fail');\n });\n };\n\n /**\n * In meeting Spoken Language changed event\n * @param {string} languageCode\n * @param {string} meetingId\n * @returns {void}\n */\n public onSpokenLanguageUpdate = (languageCode: string, meetingId: string): void => {\n this.emit(EVENT_TRIGGERS.SPOKEN_LANGUAGE_UPDATE, {languageCode, meetingId});\n this.currentSpokenLanguage = languageCode;\n };\n\n /**\n * In meeting Spoken Language changed event\n * @param {string} serviceId\n * @returns {void}\n */\n public onCaptionServiceIdUpdate = (serviceId: string): void => {\n if (!serviceId) {\n return;\n }\n if (this.captionServiceId !== serviceId) {\n this.captionServiceId = serviceId;\n if (this.currentCaptionLanguage) {\n this.requestLanguage(this.currentCaptionLanguage);\n }\n }\n };\n\n /**\n * get caption status\n * @returns {string}\n */\n public getCaptionStatus = (): string => this.captionStatus;\n\n /**\n * get announce status\n * @returns {string}\n */\n public getAnnounceStatus = (): string => this.announceStatus;\n\n /**\n * update LLM sub‑channel subscriptions.\n *\n * @param {string[]} options.subscribe Sub‑channels to subscribe to.\n * @param {string[]} options.unsubscribe Sub‑channels to unsubscribe from.\n * @returns {Promise}\n */\n public updateSubchannelSubscriptions = async ({\n subscribe = [],\n unsubscribe = [],\n }: {\n subscribe?: string[];\n unsubscribe?: string[];\n } = {}): Promise<void> => {\n if (!this.isLLMConnected()) return;\n\n const llm = this.requireLLMChannel();\n const isDataChannelTokenEnabled = await llm.isDataChannelTokenEnabled();\n if (!isDataChannelTokenEnabled) return;\n\n const socket = llm.getSocket();\n const datachannelUrl = llm.getDatachannelUrl();\n\n socket.send({\n id: `${this.seqNum}`,\n type: 'subchannelSubscriptionRequest',\n data: {\n datachannelUri: datachannelUrl,\n subscribe,\n unsubscribe,\n },\n trackingId: `${config.trackingIdPrefix}_${uuid.v4().toString()}`,\n });\n\n this.seqNum += 1;\n };\n\n /**\n * Updates transcription subchannel subscriptions and records whether the\n * transcription subscription should be kept (and restored on reconnect).\n *\n * @param {Object} [options] - Subscription options.\n * @param {string[]} [options.subscribe] - Subchannels to subscribe to.\n * @param {string[]} [options.unsubscribe] - Subchannels to unsubscribe from.\n * @param {boolean} [keepSubscribed=false] - Whether the transcription\n * subscription should be kept and restored on reconnect.\n *\n * @returns {Promise<void>}\n */\n public updateSubchannelSubscriptionsAndSyncCaptionState = (\n options: {\n subscribe?: string[];\n unsubscribe?: string[];\n } = {},\n keepSubscribed = false\n ): Promise<void> => {\n this.keepTranscriptionSubscribed = keepSubscribed;\n\n return this.updateSubchannelSubscriptions(options);\n };\n}\n\nexport default VoiceaChannel;\n"],"mappings":"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","ignoreList":[]}
|
package/package.json
CHANGED
package/src/voicea-plugin.ts
CHANGED
|
@@ -13,16 +13,16 @@ export class VoiceaPlugin extends WebexPlugin {
|
|
|
13
13
|
namespace = VOICEA;
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
|
-
* Creates a VoiceaChannel bound to
|
|
16
|
+
* Creates a VoiceaChannel, optionally bound to an LLMChannel.
|
|
17
17
|
*
|
|
18
18
|
* Note: VoiceaChannel does not take ownership of the LLMChannel.
|
|
19
19
|
* The caller retains ownership and is responsible for the LLMChannel's
|
|
20
20
|
* lifecycle (connection, disconnection, cleanup).
|
|
21
21
|
*
|
|
22
|
-
* @param {LLMChannel} llmChannel - The LLM channel to use for voicea
|
|
22
|
+
* @param {LLMChannel} [llmChannel] - The LLM channel to use for voicea (optional)
|
|
23
23
|
* @returns {VoiceaChannel} A new VoiceaChannel instance
|
|
24
24
|
*/
|
|
25
|
-
public createChannel(llmChannel
|
|
25
|
+
public createChannel(llmChannel?: LLMChannel): VoiceaChannel {
|
|
26
26
|
// @ts-ignore - webex is available on WebexPlugin
|
|
27
27
|
const channel = new VoiceaChannel(llmChannel, this.webex.request.bind(this.webex));
|
|
28
28
|
|
package/src/voicea.ts
CHANGED
|
@@ -32,7 +32,7 @@ import {millisToMinutesAndSeconds} from './utils';
|
|
|
32
32
|
*/
|
|
33
33
|
export class VoiceaChannel extends EventEmitter implements IVoiceaChannel {
|
|
34
34
|
private request: (options: {method: string; url: string; body?: object}) => Promise<any>;
|
|
35
|
-
private llmChannel
|
|
35
|
+
private llmChannel?: LLMChannel;
|
|
36
36
|
|
|
37
37
|
private seqNum: number;
|
|
38
38
|
private areCaptionsEnabled: boolean;
|
|
@@ -48,13 +48,21 @@ export class VoiceaChannel extends EventEmitter implements IVoiceaChannel {
|
|
|
48
48
|
private spokenLanguages: string[] = [];
|
|
49
49
|
private currentCaptionLanguage?: string;
|
|
50
50
|
|
|
51
|
+
// Target channel for reconciler pattern - the channel voicea WANTS to be bound to
|
|
52
|
+
private targetLLMChannel?: LLMChannel;
|
|
53
|
+
// Single pending 'online' listener for deferred reconciliation
|
|
54
|
+
private _pendingOnlineListener?: () => void;
|
|
55
|
+
// Tracks whether caption restoration is pending (set on switch, cleared on restore)
|
|
56
|
+
private _pendingCaptionRestore = false;
|
|
57
|
+
|
|
51
58
|
/**
|
|
52
|
-
* Creates a VoiceaChannel bound to
|
|
53
|
-
*
|
|
59
|
+
* Creates a VoiceaChannel, optionally bound to an LLMChannel.
|
|
60
|
+
* If no llmChannel is provided, call switchLLMChannel() later to attach one.
|
|
61
|
+
* @param {LLMChannel} [llmChannel] - The LLM channel to use (optional)
|
|
54
62
|
* @param {Function} request - The request function for making API calls (typically webex.request bound to webex)
|
|
55
63
|
*/
|
|
56
64
|
constructor(
|
|
57
|
-
llmChannel: LLMChannel,
|
|
65
|
+
llmChannel: LLMChannel | undefined,
|
|
58
66
|
request: (options: {method: string; url: string; body?: object}) => Promise<any>
|
|
59
67
|
) {
|
|
60
68
|
super();
|
|
@@ -71,9 +79,25 @@ export class VoiceaChannel extends EventEmitter implements IVoiceaChannel {
|
|
|
71
79
|
this.currentCaptionLanguage = undefined;
|
|
72
80
|
this.keepTranscriptionSubscribed = false;
|
|
73
81
|
|
|
74
|
-
// Subscribe to relay events from the LLM channel
|
|
75
|
-
this.llmChannel
|
|
76
|
-
|
|
82
|
+
// Subscribe to relay events from the LLM channel if provided
|
|
83
|
+
if (this.llmChannel) {
|
|
84
|
+
this.llmChannel.on('event:relay.event', this.eventProcessor);
|
|
85
|
+
this.hasSubscribedToEvents = true;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Returns the LLM channel, throwing if not available.
|
|
91
|
+
* @private
|
|
92
|
+
* @returns {LLMChannel}
|
|
93
|
+
* @throws {Error} If LLM channel is not available
|
|
94
|
+
*/
|
|
95
|
+
private requireLLMChannel(): LLMChannel {
|
|
96
|
+
if (!this.llmChannel) {
|
|
97
|
+
throw new Error('VoiceaChannel: LLM channel not available');
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return this.llmChannel;
|
|
77
101
|
}
|
|
78
102
|
|
|
79
103
|
/**
|
|
@@ -119,9 +143,14 @@ export class VoiceaChannel extends EventEmitter implements IVoiceaChannel {
|
|
|
119
143
|
this.areCaptionsEnabled = false;
|
|
120
144
|
this.keepTranscriptionSubscribed = false;
|
|
121
145
|
this.captionServiceId = undefined;
|
|
146
|
+
this.targetLLMChannel = undefined;
|
|
147
|
+
this._pendingCaptionRestore = false;
|
|
148
|
+
|
|
149
|
+
// Remove any pending online listener
|
|
150
|
+
this.detachPendingOnline();
|
|
122
151
|
|
|
123
152
|
if (this.hasSubscribedToEvents) {
|
|
124
|
-
this.llmChannel
|
|
153
|
+
this.llmChannel?.off('event:relay.event', this.eventProcessor);
|
|
125
154
|
this.hasSubscribedToEvents = false;
|
|
126
155
|
}
|
|
127
156
|
|
|
@@ -133,42 +162,101 @@ export class VoiceaChannel extends EventEmitter implements IVoiceaChannel {
|
|
|
133
162
|
}
|
|
134
163
|
|
|
135
164
|
/**
|
|
136
|
-
*
|
|
137
|
-
*
|
|
138
|
-
* -
|
|
139
|
-
*
|
|
140
|
-
*
|
|
141
|
-
* @
|
|
142
|
-
* @returns {Promise<void>}
|
|
165
|
+
* Attach a pending 'online' listener to a channel for deferred reconciliation.
|
|
166
|
+
* Detaches any existing listener first.
|
|
167
|
+
* @param {LLMChannel} channel - The channel to attach to
|
|
168
|
+
* @param {Function} callback - The callback to run when 'online' fires
|
|
169
|
+
* @private
|
|
170
|
+
* @returns {void}
|
|
143
171
|
*/
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
172
|
+
private attachPendingOnline(channel: LLMChannel, callback: () => void): void {
|
|
173
|
+
this.detachPendingOnline();
|
|
174
|
+
this._pendingOnlineListener = callback;
|
|
175
|
+
channel.once('online', this._pendingOnlineListener);
|
|
176
|
+
}
|
|
148
177
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
178
|
+
/**
|
|
179
|
+
* Detach any pending 'online' listener.
|
|
180
|
+
* @private
|
|
181
|
+
* @returns {void}
|
|
182
|
+
*/
|
|
183
|
+
private detachPendingOnline(): void {
|
|
184
|
+
if (this._pendingOnlineListener && this.llmChannel) {
|
|
185
|
+
this.llmChannel.off('online', this._pendingOnlineListener);
|
|
153
186
|
}
|
|
187
|
+
this._pendingOnlineListener = undefined;
|
|
188
|
+
}
|
|
154
189
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
// Reset announcement state for new connection
|
|
190
|
+
/**
|
|
191
|
+
* Reset announcement state for a new connection.
|
|
192
|
+
* @private
|
|
193
|
+
* @returns {void}
|
|
194
|
+
*/
|
|
195
|
+
private resetAnnounceState(): void {
|
|
163
196
|
this.announceStatus = ANNOUNCE_STATUS.IDLE;
|
|
164
197
|
this.captionStatus = TURN_ON_CAPTION_STATUS.IDLE;
|
|
165
198
|
this.captionServiceId = undefined;
|
|
166
199
|
this.areCaptionsEnabled = false;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Reconcile voicea binding and caption state to match the desired target.
|
|
204
|
+
* This is idempotent - always re-reads targetLLMChannel and current state.
|
|
205
|
+
* A deferred 'online' callback that fires late self-corrects automatically.
|
|
206
|
+
* @private
|
|
207
|
+
* @returns {Promise<void>}
|
|
208
|
+
*/
|
|
209
|
+
private reconcile(): Promise<void> {
|
|
210
|
+
const target = this.targetLLMChannel;
|
|
211
|
+
if (!target) return Promise.resolve();
|
|
212
|
+
|
|
213
|
+
// 1. Rebind relay-event subscription if actual != desired
|
|
214
|
+
if (this.llmChannel !== target) {
|
|
215
|
+
if (this.hasSubscribedToEvents && this.llmChannel) {
|
|
216
|
+
this.llmChannel.off('event:relay.event', this.eventProcessor);
|
|
217
|
+
}
|
|
218
|
+
this.detachPendingOnline();
|
|
219
|
+
this.llmChannel = target;
|
|
220
|
+
this.llmChannel.on('event:relay.event', this.eventProcessor);
|
|
221
|
+
this.hasSubscribedToEvents = true;
|
|
222
|
+
this.resetAnnounceState();
|
|
223
|
+
// Mark caption restoration as pending if captions were subscribed
|
|
224
|
+
this._pendingCaptionRestore = this.keepTranscriptionSubscribed;
|
|
225
|
+
}
|
|
167
226
|
|
|
168
|
-
//
|
|
169
|
-
if (
|
|
170
|
-
|
|
227
|
+
// 2. Restore captions if pending
|
|
228
|
+
if (!this._pendingCaptionRestore) return Promise.resolve();
|
|
229
|
+
|
|
230
|
+
if (this.isLLMConnected()) {
|
|
231
|
+
// Channel is connected, restore captions immediately
|
|
232
|
+
this._pendingCaptionRestore = false;
|
|
233
|
+
|
|
234
|
+
return this.turnOnCaptions(this.currentSpokenLanguage)
|
|
235
|
+
.then(() => undefined)
|
|
236
|
+
.catch(() => {
|
|
237
|
+
// Best-effort restoration
|
|
238
|
+
});
|
|
171
239
|
}
|
|
240
|
+
// Channel not yet connected - defer until 'online' then re-reconcile.
|
|
241
|
+
// If target changes meanwhile, reconcile() self-corrects.
|
|
242
|
+
this.attachPendingOnline(target, () => {
|
|
243
|
+
this.reconcile();
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
return Promise.resolve();
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Switch to a different LLM channel while preserving caption state.
|
|
251
|
+
* Used when transitioning between main meeting and practice session.
|
|
252
|
+
* This is a thin intent-setter - actual binding happens in reconcile().
|
|
253
|
+
* @param {LLMChannel} newLLMChannel - The new LLM channel to switch to
|
|
254
|
+
* @returns {Promise<void>}
|
|
255
|
+
*/
|
|
256
|
+
public switchLLMChannel(newLLMChannel: LLMChannel): Promise<void> {
|
|
257
|
+
this.targetLLMChannel = newLLMChannel;
|
|
258
|
+
|
|
259
|
+
return this.reconcile();
|
|
172
260
|
}
|
|
173
261
|
|
|
174
262
|
/**
|
|
@@ -304,7 +392,7 @@ export class VoiceaChannel extends EventEmitter implements IVoiceaChannel {
|
|
|
304
392
|
* Indicates whether the LLM channel is connected.
|
|
305
393
|
* @returns {boolean}
|
|
306
394
|
*/
|
|
307
|
-
public isLLMConnected = (): boolean => this.llmChannel
|
|
395
|
+
public isLLMConnected = (): boolean => this.llmChannel?.isConnected() ?? false;
|
|
308
396
|
|
|
309
397
|
public getKeepTranscriptionSubscribed = (): boolean => this.keepTranscriptionSubscribed;
|
|
310
398
|
|
|
@@ -313,9 +401,10 @@ export class VoiceaChannel extends EventEmitter implements IVoiceaChannel {
|
|
|
313
401
|
* @returns {void}
|
|
314
402
|
*/
|
|
315
403
|
public sendAnnouncement = (): void => {
|
|
404
|
+
const llm = this.requireLLMChannel();
|
|
316
405
|
this.announceStatus = ANNOUNCE_STATUS.JOINING;
|
|
317
|
-
const socket =
|
|
318
|
-
const binding =
|
|
406
|
+
const socket = llm.getSocket();
|
|
407
|
+
const binding = llm.getBinding();
|
|
319
408
|
|
|
320
409
|
const payload = {
|
|
321
410
|
id: `${this.seqNum}`,
|
|
@@ -352,7 +441,7 @@ export class VoiceaChannel extends EventEmitter implements IVoiceaChannel {
|
|
|
352
441
|
): Promise<void> =>
|
|
353
442
|
this.request({
|
|
354
443
|
method: 'PUT',
|
|
355
|
-
url: `${this.
|
|
444
|
+
url: `${this.requireLLMChannel().getLocusUrl()}/controls/`,
|
|
356
445
|
body: {
|
|
357
446
|
transcribe: {
|
|
358
447
|
spokenLanguage: languageCode,
|
|
@@ -373,8 +462,9 @@ export class VoiceaChannel extends EventEmitter implements IVoiceaChannel {
|
|
|
373
462
|
return;
|
|
374
463
|
}
|
|
375
464
|
|
|
376
|
-
const
|
|
377
|
-
const
|
|
465
|
+
const llm = this.requireLLMChannel();
|
|
466
|
+
const socket = llm.getSocket();
|
|
467
|
+
const binding = llm.getBinding();
|
|
378
468
|
|
|
379
469
|
socket.send({
|
|
380
470
|
id: `${this.seqNum}`,
|
|
@@ -419,8 +509,9 @@ export class VoiceaChannel extends EventEmitter implements IVoiceaChannel {
|
|
|
419
509
|
return;
|
|
420
510
|
}
|
|
421
511
|
|
|
422
|
-
const
|
|
423
|
-
const
|
|
512
|
+
const llm = this.requireLLMChannel();
|
|
513
|
+
const socket = llm.getSocket();
|
|
514
|
+
const binding = llm.getBinding();
|
|
424
515
|
|
|
425
516
|
socket?.send({
|
|
426
517
|
id: `${this.seqNum}`,
|
|
@@ -463,7 +554,7 @@ export class VoiceaChannel extends EventEmitter implements IVoiceaChannel {
|
|
|
463
554
|
private requestTurnOnCaptions = (languageCode?: string): undefined | Promise<void> => {
|
|
464
555
|
this.captionStatus = TURN_ON_CAPTION_STATUS.SENDING;
|
|
465
556
|
|
|
466
|
-
const locusUrl = this.
|
|
557
|
+
const locusUrl = this.requireLLMChannel().getLocusUrl();
|
|
467
558
|
|
|
468
559
|
const body = {
|
|
469
560
|
transcribe: {caption: true},
|
|
@@ -485,7 +576,7 @@ export class VoiceaChannel extends EventEmitter implements IVoiceaChannel {
|
|
|
485
576
|
})
|
|
486
577
|
.catch((error) => {
|
|
487
578
|
this.captionStatus = TURN_ON_CAPTION_STATUS.IDLE;
|
|
488
|
-
throw new Error('turn on captions fail');
|
|
579
|
+
throw new Error('turn on captions fail', {cause: error});
|
|
489
580
|
});
|
|
490
581
|
};
|
|
491
582
|
|
|
@@ -529,7 +620,7 @@ export class VoiceaChannel extends EventEmitter implements IVoiceaChannel {
|
|
|
529
620
|
* @returns {Promise}
|
|
530
621
|
*/
|
|
531
622
|
public turnOnCaptions = async (spokenLanguage?: string): Promise<void | undefined> => {
|
|
532
|
-
if (this.
|
|
623
|
+
if (this.isCaptionProcessing()) return undefined;
|
|
533
624
|
|
|
534
625
|
if (!this.isLLMConnected()) {
|
|
535
626
|
throw new Error('can not turn on captions before llm connected');
|
|
@@ -550,7 +641,7 @@ export class VoiceaChannel extends EventEmitter implements IVoiceaChannel {
|
|
|
550
641
|
): undefined | Promise<void> => {
|
|
551
642
|
return this.request({
|
|
552
643
|
method: 'PUT',
|
|
553
|
-
url: `${this.
|
|
644
|
+
url: `${this.requireLLMChannel().getLocusUrl()}/controls/`,
|
|
554
645
|
body: {
|
|
555
646
|
transcribe: {
|
|
556
647
|
transcribing: activate,
|
|
@@ -578,7 +669,7 @@ export class VoiceaChannel extends EventEmitter implements IVoiceaChannel {
|
|
|
578
669
|
|
|
579
670
|
return this.request({
|
|
580
671
|
method: 'PUT',
|
|
581
|
-
url: `${this.
|
|
672
|
+
url: `${this.requireLLMChannel().getLocusUrl()}/controls/`,
|
|
582
673
|
body: {
|
|
583
674
|
manualCaption: {
|
|
584
675
|
enable,
|
|
@@ -652,11 +743,12 @@ export class VoiceaChannel extends EventEmitter implements IVoiceaChannel {
|
|
|
652
743
|
} = {}): Promise<void> => {
|
|
653
744
|
if (!this.isLLMConnected()) return;
|
|
654
745
|
|
|
655
|
-
const
|
|
746
|
+
const llm = this.requireLLMChannel();
|
|
747
|
+
const isDataChannelTokenEnabled = await llm.isDataChannelTokenEnabled();
|
|
656
748
|
if (!isDataChannelTokenEnabled) return;
|
|
657
749
|
|
|
658
|
-
const socket =
|
|
659
|
-
const datachannelUrl =
|
|
750
|
+
const socket = llm.getSocket();
|
|
751
|
+
const datachannelUrl = llm.getDatachannelUrl();
|
|
660
752
|
|
|
661
753
|
socket.send({
|
|
662
754
|
id: `${this.seqNum}`,
|
|
@@ -51,6 +51,18 @@ describe('plugin-voicea', () => {
|
|
|
51
51
|
assert.instanceOf(channel, VoiceaChannel);
|
|
52
52
|
});
|
|
53
53
|
|
|
54
|
+
it('creates a new VoiceaChannel instance without llmChannel', () => {
|
|
55
|
+
const channel = plugin.createChannel();
|
|
56
|
+
|
|
57
|
+
assert.instanceOf(channel, VoiceaChannel);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it('creates a new VoiceaChannel instance with undefined llmChannel', () => {
|
|
61
|
+
const channel = plugin.createChannel(undefined);
|
|
62
|
+
|
|
63
|
+
assert.instanceOf(channel, VoiceaChannel);
|
|
64
|
+
});
|
|
65
|
+
|
|
54
66
|
it('creates independent channels for multiple calls', () => {
|
|
55
67
|
const mockLLMChannel1 = createMockLLMChannel();
|
|
56
68
|
const mockLLMChannel2 = createMockLLMChannel();
|