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