{"version":3,"sources":["src/common.speech/IntentServiceRecognizer.ts"],"names":[],"mappings":"AAGA,OAAO,EAEH,YAAY,EAEf,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACH,qBAAqB,EACrB,kBAAkB,EAIlB,gBAAgB,EAInB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACH,aAAa,EAIb,qBAAqB,EAGxB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAC;AAGhF,qBAAa,uBAAwB,SAAQ,qBAAqB;IAC9D,OAAO,CAAC,oBAAoB,CAAmB;IAC/C,OAAO,CAAC,kBAAkB,CAAkC;IAC5D,OAAO,CAAC,kBAAkB,CAAU;IACpC,OAAO,CAAC,kBAAkB,CAAgB;IAC1C,OAAO,CAAC,qBAAqB,CAA6B;gBAGtD,cAAc,EAAE,eAAe,EAC/B,iBAAiB,EAAE,kBAAkB,EACrC,WAAW,EAAE,YAAY,EACzB,gBAAgB,EAAE,gBAAgB,EAClC,UAAU,EAAE,gBAAgB;IAOzB,UAAU,CAAC,YAAY,EAAE;QAAE,CAAC,EAAE,EAAE,MAAM,GAAG,aAAa,CAAA;KAAE,EAAE,cAAc,EAAE,aAAa,GAAG,IAAI;IAMrG,SAAS,CAAC,2BAA2B,CAAC,iBAAiB,EAAE,uBAAuB,GAAG,OAAO,CAAC,OAAO,CAAC;IAwMnG,SAAS,CAAC,iBAAiB,CACvB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,kBAAkB,EAAE,kBAAkB,EACtC,SAAS,EAAE,qBAAqB,EAChC,KAAK,EAAE,MAAM,GAAG,IAAI;CAwC3B","file":"IntentServiceRecognizer.d.ts","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nimport {\n    Deferred,\n    IAudioSource,\n    MessageType,\n} from \"../common/Exports.js\";\nimport {\n    CancellationErrorCode,\n    CancellationReason,\n    IntentRecognitionCanceledEventArgs,\n    IntentRecognitionEventArgs,\n    IntentRecognitionResult,\n    IntentRecognizer,\n    PropertyCollection,\n    PropertyId,\n    ResultReason,\n} from \"../sdk/Exports.js\";\nimport {\n    AddedLmIntent,\n    CancellationErrorCodePropertyName,\n    EnumTranslation,\n    IntentResponse,\n    ServiceRecognizerBase,\n    SimpleSpeechPhrase,\n    SpeechHypothesis,\n} from \"./Exports.js\";\nimport { IAuthentication } from \"./IAuthentication.js\";\nimport { IConnectionFactory } from \"./IConnectionFactory.js\";\nimport { RecognizerConfig } from \"./RecognizerConfig.js\";\nimport { SpeechConnectionMessage } from \"./SpeechConnectionMessage.Internal.js\";\n\n// eslint-disable-next-line max-classes-per-file\nexport class IntentServiceRecognizer extends ServiceRecognizerBase {\n    private privIntentRecognizer: IntentRecognizer;\n    private privAddedLmIntents: { [id: string]: AddedLmIntent };\n    private privIntentDataSent: boolean;\n    private privUmbrellaIntent: AddedLmIntent;\n    private privPendingIntentArgs: IntentRecognitionEventArgs;\n\n    public constructor(\n        authentication: IAuthentication,\n        connectionFactory: IConnectionFactory,\n        audioSource: IAudioSource,\n        recognizerConfig: RecognizerConfig,\n        recognizer: IntentRecognizer) {\n        super(authentication, connectionFactory, audioSource, recognizerConfig, recognizer);\n        this.privIntentRecognizer = recognizer;\n        this.privIntentDataSent = false;\n        recognizerConfig.recognitionEndpointVersion = \"1\";\n    }\n\n    public setIntents(addedIntents: { [id: string]: AddedLmIntent }, umbrellaIntent: AddedLmIntent): void {\n        this.privAddedLmIntents = addedIntents;\n        this.privUmbrellaIntent = umbrellaIntent;\n        this.privIntentDataSent = true;\n    }\n\n    protected processTypeSpecificMessages(connectionMessage: SpeechConnectionMessage): Promise<boolean> {\n\n        let result: IntentRecognitionResult;\n        let ev: IntentRecognitionEventArgs;\n        let processed: boolean = false;\n\n        const resultProps: PropertyCollection = new PropertyCollection();\n        if (connectionMessage.messageType === MessageType.Text) {\n            resultProps.setProperty(PropertyId.SpeechServiceResponse_JsonResult, connectionMessage.textBody);\n        }\n\n        switch (connectionMessage.path.toLowerCase()) {\n            case \"speech.hypothesis\":\n                const speechHypothesis: SpeechHypothesis = SpeechHypothesis.fromJSON(connectionMessage.textBody, this.privRequestSession.currentTurnAudioOffset);\n\n                result = new IntentRecognitionResult(\n                    undefined,\n                    this.privRequestSession.requestId,\n                    ResultReason.RecognizingIntent,\n                    speechHypothesis.Text,\n                    speechHypothesis.Duration,\n                    speechHypothesis.Offset,\n                    speechHypothesis.Language,\n                    speechHypothesis.LanguageDetectionConfidence,\n                    undefined,\n                    speechHypothesis.asJson(),\n                    resultProps);\n\n                this.privRequestSession.onHypothesis(result.offset);\n\n                ev = new IntentRecognitionEventArgs(result, speechHypothesis.Offset, this.privRequestSession.sessionId);\n\n                if (!!this.privIntentRecognizer.recognizing) {\n                    try {\n                        this.privIntentRecognizer.recognizing(this.privIntentRecognizer, ev);\n                        /* eslint-disable no-empty */\n                    } catch (error) {\n                        // Not going to let errors in the event handler\n                        // trip things up.\n                    }\n                }\n                processed = true;\n                break;\n            case \"speech.phrase\":\n                const simple: SimpleSpeechPhrase = SimpleSpeechPhrase.fromJSON(connectionMessage.textBody, this.privRequestSession.currentTurnAudioOffset);\n                result = new IntentRecognitionResult(\n                    undefined,\n                    this.privRequestSession.requestId,\n                    EnumTranslation.implTranslateRecognitionResult(simple.RecognitionStatus),\n                    simple.DisplayText,\n                    simple.Duration,\n                    simple.Offset,\n                    simple.Language,\n                    simple.LanguageDetectionConfidence,\n                    undefined,\n                    simple.asJson(),\n                    resultProps);\n\n                ev = new IntentRecognitionEventArgs(result, result.offset, this.privRequestSession.sessionId);\n\n                const sendEvent: () => void = (): void => {\n                    if (!!this.privIntentRecognizer.recognized) {\n                        try {\n                            this.privIntentRecognizer.recognized(this.privIntentRecognizer, ev);\n                            /* eslint-disable no-empty */\n                        } catch (error) {\n                            // Not going to let errors in the event handler\n                            // trip things up.\n                        }\n                    }\n\n                    // report result to promise.\n                    if (!!this.privSuccessCallback) {\n                        try {\n                            this.privSuccessCallback(result);\n                        } catch (e) {\n                            if (!!this.privErrorCallback) {\n                                this.privErrorCallback(e as string);\n                            }\n                        }\n                        // Only invoke the call back once.\n                        // and if it's successful don't invoke the\n                        // error after that.\n                        this.privSuccessCallback = undefined;\n                        this.privErrorCallback = undefined;\n                    }\n                };\n\n                // If intent data was sent, the terminal result for this recognizer is an intent being found.\n                // If no intent data was sent, the terminal event is speech recognition being successful.\n                if (false === this.privIntentDataSent || ResultReason.NoMatch === ev.result.reason) {\n                    // Advance the buffers.\n                    this.privRequestSession.onPhraseRecognized(ev.offset + ev.result.duration);\n                    sendEvent();\n                } else {\n                    // Squirrel away the args, when the response event arrives it will build upon them\n                    // and then return\n                    this.privPendingIntentArgs = ev;\n                }\n                processed = true;\n                break;\n            case \"response\":\n                // Response from LUIS\n                ev = this.privPendingIntentArgs;\n                this.privPendingIntentArgs = undefined;\n\n                if (undefined === ev) {\n                    if (\"\" === connectionMessage.textBody) {\n                        // This condition happens if there is nothing but silence in the\n                        // audio sent to the service.\n                        return;\n                    }\n\n                    // Odd... Not sure this can happen\n                    ev = new IntentRecognitionEventArgs(new IntentRecognitionResult(), 0, this.privRequestSession.sessionId);\n                }\n\n                const intentResponse: IntentResponse = IntentResponse.fromJSON(connectionMessage.textBody);\n\n                // If LUIS didn't return anything, send the existing event, else\n                // modify it to show the match.\n                // See if the intent found is in the list of intents asked for.\n\n                if (null !== intentResponse && !!intentResponse.topScoringIntent && !!intentResponse.topScoringIntent.intent) {\n                    let addedIntent: AddedLmIntent = this.privAddedLmIntents[intentResponse.topScoringIntent.intent];\n\n                    if (this.privUmbrellaIntent !== undefined) {\n                        addedIntent = this.privUmbrellaIntent;\n                    }\n\n                    if (!!addedIntent) {\n                        const intentId = addedIntent === undefined || addedIntent.intentName === undefined ? intentResponse.topScoringIntent.intent : addedIntent.intentName;\n                        let reason = ev.result.reason;\n\n                        if (undefined !== intentId) {\n                            reason = ResultReason.RecognizedIntent;\n                        }\n\n                        // make sure, properties is set.\n                        const properties = (undefined !== ev.result.properties) ?\n                            ev.result.properties : new PropertyCollection();\n\n                        properties.setProperty(PropertyId.LanguageUnderstandingServiceResponse_JsonResult, connectionMessage.textBody);\n\n                        ev = new IntentRecognitionEventArgs(\n                            new IntentRecognitionResult(\n                                intentId,\n                                ev.result.resultId,\n                                reason,\n                                ev.result.text,\n                                ev.result.duration,\n                                ev.result.offset,\n                                undefined,\n                                undefined,\n                                ev.result.errorDetails,\n                                ev.result.json,\n                                properties),\n                            ev.offset,\n                            ev.sessionId);\n\n                    }\n                }\n                this.privRequestSession.onPhraseRecognized(ev.offset + ev.result.duration);\n\n                if (!!this.privIntentRecognizer.recognized) {\n                    try {\n                        this.privIntentRecognizer.recognized(this.privIntentRecognizer, ev);\n                        /* eslint-disable no-empty */\n                    } catch (error) {\n                        // Not going to let errors in the event handler\n                        // trip things up.\n                    }\n                }\n\n                // report result to promise.\n                if (!!this.privSuccessCallback) {\n                    try {\n                        this.privSuccessCallback(ev.result);\n                    } catch (e) {\n                        if (!!this.privErrorCallback) {\n                            this.privErrorCallback(e as string);\n                        }\n                    }\n                    // Only invoke the call back once.\n                    // and if it's successful don't invoke the\n                    // error after that.\n                    this.privSuccessCallback = undefined;\n                    this.privErrorCallback = undefined;\n                }\n                processed = true;\n                break;\n            default:\n                break;\n        }\n        const defferal = new Deferred<boolean>();\n        defferal.resolve(processed);\n        return defferal.promise;\n    }\n\n    // Cancels recognition.\n    protected cancelRecognition(\n        sessionId: string,\n        requestId: string,\n        cancellationReason: CancellationReason,\n        errorCode: CancellationErrorCode,\n        error: string): void {\n\n        const properties: PropertyCollection = new PropertyCollection();\n        properties.setProperty(CancellationErrorCodePropertyName, CancellationErrorCode[errorCode]);\n\n        if (!!this.privIntentRecognizer.canceled) {\n\n            const cancelEvent: IntentRecognitionCanceledEventArgs = new IntentRecognitionCanceledEventArgs(\n                cancellationReason,\n                error,\n                errorCode,\n                undefined,\n                undefined,\n                sessionId);\n            try {\n                this.privIntentRecognizer.canceled(this.privIntentRecognizer, cancelEvent);\n                /* eslint-disable no-empty */\n            } catch { }\n        }\n\n        if (!!this.privSuccessCallback) {\n            const result: IntentRecognitionResult = new IntentRecognitionResult(\n                undefined, // Intent Id\n                requestId,\n                ResultReason.Canceled,\n                undefined, // Text\n                undefined, // Duration\n                undefined, // Offset\n                undefined, // Language\n                undefined, // LanguageDetectionConfidence\n                error,\n                undefined, // Json\n                properties);\n            try {\n                this.privSuccessCallback(result);\n                this.privSuccessCallback = undefined;\n                /* eslint-disable no-empty */\n            } catch { }\n        }\n    }\n}\n"]}