From 514a402acdb2301997b61d6ec54a0d0fc7cb144a Mon Sep 17 00:00:00 2001 From: matiasroldan6 Date: Thu, 23 Jul 2020 17:14:15 -0300 Subject: [PATCH 01/17] Add changes to dialogs folder --- .../sample-skill/src/dialogs/mainDialog.ts | 91 +++++++++---------- .../sample-skill/src/dialogs/sampleAction.ts | 13 +-- .../sample-skill/src/dialogs/sampleDialog.ts | 20 ++-- .../src/dialogs/skillDialogBase.ts | 13 +-- 4 files changed, 61 insertions(+), 76 deletions(-) diff --git a/templates/typescript/samples/sample-skill/src/dialogs/mainDialog.ts b/templates/typescript/samples/sample-skill/src/dialogs/mainDialog.ts index a37f59e148..87da01d293 100644 --- a/templates/typescript/samples/sample-skill/src/dialogs/mainDialog.ts +++ b/templates/typescript/samples/sample-skill/src/dialogs/mainDialog.ts @@ -6,9 +6,7 @@ import { Activity, ActivityTypes, BotFrameworkAdapter, - BotTelemetryClient, - RecognizerResult, - StatePropertyAccessor } from 'botbuilder'; + RecognizerResult } from 'botbuilder'; import { LuisRecognizer } from 'botbuilder-ai'; import { DialogContext, @@ -20,7 +18,6 @@ import { ComponentDialog } from 'botbuilder-dialogs'; import { ICognitiveModelSet, LocaleTemplateManager } from 'bot-solutions'; import { TokenStatus } from 'botframework-connector'; -import { SkillState } from '../models/skillState'; import { BotServices } from '../services/botServices'; import { SampleDialog } from './sampleDialog'; import { StateProperties } from '../models'; @@ -37,25 +34,18 @@ export class MainDialog extends ComponentDialog { private readonly services: BotServices; private readonly sampleDialog: SampleDialog; private readonly sampleAction: SampleAction; - private readonly templateManager: LocaleTemplateManager; - private readonly stateAccessor: StatePropertyAccessor; + private readonly templateEngine: LocaleTemplateManager; // Constructor public constructor( services: BotServices, - telemetryClient: BotTelemetryClient, - stateAccessor: StatePropertyAccessor, sampleDialog: SampleDialog, sampleAction: SampleAction, - templateManager: LocaleTemplateManager + templateEngine: LocaleTemplateManager ) { super(MainDialog.name); this.services = services; - this.templateManager = templateManager; - this.telemetryClient = telemetryClient; - - // Create conversationstate properties - this.stateAccessor = stateAccessor; + this.templateEngine = templateEngine; const steps: ((sc: WaterfallStepContext) => Promise)[] = [ this.introStep.bind(this), @@ -76,7 +66,8 @@ export class MainDialog extends ComponentDialog { // Runs when the dialog is started. protected async onBeginDialog(innerDc: DialogContext, options: Object): Promise { - if (innerDc.context.activity.type == ActivityTypes.Message) { + const activity: Activity = innerDc.context.activity; + if (activity.type === ActivityTypes.Message && activity.text !== undefined && activity.text.trim().length > 0) { // Get cognitive models for the current locale. const localizedServices: Partial = this.services.getCognitiveModels(innerDc.context.activity.locale as string); @@ -96,11 +87,11 @@ export class MainDialog extends ComponentDialog { } // Check for any interruptions - const interrupted = await this.interruptDialog(innerDc); + const interrupted: DialogTurnResult = await this.interruptDialog(innerDc); - if (interrupted) { - // If dialog was interrupted, return EndOfTurn - return MainDialog.EndOfTurn; + if (Object.keys(interrupted).length > 0) { + // If dialog was interrupted, return interrupted result + return interrupted; } } @@ -109,10 +100,11 @@ export class MainDialog extends ComponentDialog { // Runs on every turn of the conversation. protected async onContinueDialog(innerDc: DialogContext): Promise { - if (innerDc.context.activity.type === ActivityTypes.Message) { - + const activity: Activity = innerDc.context.activity; + if (activity.type === ActivityTypes.Message && activity.text !== undefined && activity.text.trim().length > 0) { // Get cognitive models for the current locale. const localizedServices: Partial = this.services.getCognitiveModels(innerDc.context.activity.locale as string); + // Run LUIS recognition on Skill model and store result in turn state. const skillLuis: LuisRecognizer | undefined = localizedServices.luisServices ? localizedServices.luisServices.get('sampleSkill') : undefined; if (skillLuis !== undefined) { @@ -128,11 +120,11 @@ export class MainDialog extends ComponentDialog { } // Check for any interruptions - const interrupted = await this.interruptDialog(innerDc); + const interrupted: DialogTurnResult = await this.interruptDialog(innerDc); - if (interrupted) { - // If dialog was interrupted, return EndOfTurn - return MainDialog.EndOfTurn; + if (Object.keys(interrupted).length > 0) { + // If dialog was interrupted, return interrupted result + return interrupted; } } @@ -140,8 +132,8 @@ export class MainDialog extends ComponentDialog { } // Runs on every turn of the conversation to check if the conversation should be interrupted. - protected async interruptDialog(innerDc: DialogContext): Promise { - let interrupted = false; + protected async interruptDialog(innerDc: DialogContext): Promise { + let interrupted: DialogTurnResult = {} as DialogTurnResult; const activity: Activity = innerDc.context.activity; if (activity.type === ActivityTypes.Message && activity.text !== undefined && activity.text.trim().length > 0) { @@ -152,29 +144,34 @@ export class MainDialog extends ComponentDialog { if (generalResult.intents[intent].score > 0.5) { switch(intent) { case 'Cancel': { - - await innerDc.context.sendActivity(this.templateManager.generateActivityForLocale('CancelledMessage', innerDc.context.activity.locale)); + await innerDc.context.sendActivity(this.templateEngine.generateActivityForLocale('CancelledMessage', innerDc.context.activity.locale)); await innerDc.cancelAllDialogs(); - await innerDc.beginDialog(this.initialDialogId); - interrupted = true; + if (TurnContextEx.isSkill(innerDc.context)) { + interrupted = await innerDc.endDialog(); + } + else { + interrupted = await innerDc.beginDialog(this.initialDialogId); + } break; } case 'Help': { - - await innerDc.context.sendActivity(this.templateManager.generateActivityForLocale('HelpCard', innerDc.context.activity.locale)); + await innerDc.context.sendActivity(this.templateEngine.generateActivityForLocale('HelpCard', innerDc.context.activity.locale)); await innerDc.repromptDialog(); - interrupted = true; + interrupted = MainDialog.EndOfTurn; break; } case 'Logout': { - // Log user out of all accounts. await this.logUserOut(innerDc); - await innerDc.context.sendActivity(this.templateManager.generateActivityForLocale('LogoutMessage', innerDc.context.activity.locale)); + await innerDc.context.sendActivity(this.templateEngine.generateActivityForLocale('LogoutMessage', innerDc.context.activity.locale)); await innerDc.cancelAllDialogs(); - await innerDc.beginDialog(this.initialDialogId); - interrupted = true; + if (TurnContextEx.isSkill(innerDc.context)) { + interrupted = await innerDc.endDialog(); + } + else { + interrupted = await innerDc.beginDialog(this.initialDialogId); + } break; } } @@ -189,13 +186,13 @@ export class MainDialog extends ComponentDialog { if (TurnContextEx.isSkill(stepContext.context)) { // If the bot is in skill mode, skip directly to route and do not prompt return await stepContext.next(); - } else { - // If bot is in local mode, prompt with intro or continuation message - const promptOptions: PromptOptions = { - prompt: Object.keys(stepContext.options as Activity).length > 0 ? stepContext.options as Activity : this.templateManager.generateActivityForLocale('FirstPromptMessage', stepContext.context.activity.locale) - }; - return await stepContext.prompt(TextPrompt.name, promptOptions); } + + // If bot is in local mode, prompt with intro or continuation message + const promptOptions: PromptOptions = { + prompt: Object.keys(stepContext.options as Activity).length > 0 ? stepContext.options as Activity : this.templateEngine.generateActivityForLocale('FirstPromptMessage', stepContext.context.activity.locale) + }; + return await stepContext.prompt(TextPrompt.name, promptOptions); } // Handles routing to additional dialogs logic. @@ -223,7 +220,7 @@ export class MainDialog extends ComponentDialog { case 'None': default: { // intent was identified but not yet implemented - await stepContext.context.sendActivity(this.templateManager.generateActivityForLocale('UnsupportedMessage', stepContext.context.activity.locale)); + await stepContext.context.sendActivity(this.templateEngine.generateActivityForLocale('UnsupportedMessage', stepContext.context.activity.locale)); return await stepContext.next(); } } @@ -238,7 +235,7 @@ export class MainDialog extends ComponentDialog { case 'SampleAction': { let actionData: Object = {}; - if (ev.value !== undefined && actionData !== undefined) { + if (ev.value !== undefined) { actionData = ev.value as SampleActionInput; } @@ -274,7 +271,7 @@ export class MainDialog extends ComponentDialog { return await stepContext.endDialog(result); } else { - return await stepContext.replaceDialog(this.id, this.templateManager.generateActivityForLocale('CompletedMessage', stepContext.context.activity.locale)); + return await stepContext.replaceDialog(this.id, this.templateEngine.generateActivityForLocale('CompletedMessage', stepContext.context.activity.locale)); } } diff --git a/templates/typescript/samples/sample-skill/src/dialogs/sampleAction.ts b/templates/typescript/samples/sample-skill/src/dialogs/sampleAction.ts index cc5fffae2b..4cb2fac9f4 100644 --- a/templates/typescript/samples/sample-skill/src/dialogs/sampleAction.ts +++ b/templates/typescript/samples/sample-skill/src/dialogs/sampleAction.ts @@ -8,10 +8,10 @@ import { WaterfallDialog, TextPrompt } from 'botbuilder-dialogs'; import { SkillDialogBase } from './skillDialogBase'; -import { BotTelemetryClient, StatePropertyAccessor, Activity } from 'botbuilder'; +import { StatePropertyAccessor, Activity } from 'botbuilder'; import { BotServices } from '../services/botServices'; import { LocaleTemplateManager } from 'bot-solutions'; -import { SkillState } from '../models/skillState'; +import { SkillState } from '../models'; import { IBotSettings } from '../services/botSettings'; export class SampleActionInput { @@ -27,16 +27,13 @@ enum DialogIds { } export class SampleAction extends SkillDialogBase { - private readonly nameKey: string = 'name'; - public constructor( settings: Partial, services: BotServices, stateAccessor: StatePropertyAccessor, - telemetryClient: BotTelemetryClient, templateManager: LocaleTemplateManager ) { - super(SampleAction.name, settings, services, stateAccessor, telemetryClient, templateManager); + super(SampleAction.name, settings, services, stateAccessor, templateManager); const sample: ((sc: WaterfallStepContext) => Promise)[] = [ this.promptForName.bind(this), @@ -59,13 +56,13 @@ export class SampleAction extends SkillDialogBase { return await stepContext.next(actionInput.name); } - const prompt: Partial = this.templateManager.generateActivityForLocale('NamePrompt', stepContext.context.activity.locale); + const prompt: Partial = this.templateEngine.generateActivityForLocale('NamePrompt', stepContext.context.activity.locale); return await stepContext.prompt(DialogIds.namePrompt, { prompt: prompt }); } private async greetUser(stepContext: WaterfallStepContext): Promise { const data: Object = { name: stepContext.result as string }; - const response: Partial = this.templateManager.generateActivityForLocale('HaveNameMessage', stepContext.context.activity.locale, data); + const response: Partial = this.templateEngine.generateActivityForLocale('HaveNameMessage', stepContext.context.activity.locale, data); await stepContext.context.sendActivity(response); // Pass the response which we'll return to the user onto the next step diff --git a/templates/typescript/samples/sample-skill/src/dialogs/sampleDialog.ts b/templates/typescript/samples/sample-skill/src/dialogs/sampleDialog.ts index bfb6aef306..880e523d9f 100644 --- a/templates/typescript/samples/sample-skill/src/dialogs/sampleDialog.ts +++ b/templates/typescript/samples/sample-skill/src/dialogs/sampleDialog.ts @@ -5,14 +5,13 @@ import { Activity, - BotTelemetryClient, StatePropertyAccessor} from 'botbuilder'; import { DialogTurnResult, TextPrompt, WaterfallDialog, WaterfallStepContext } from 'botbuilder-dialogs'; -import { SkillState } from '../models/skillState'; +import { SkillState } from '../models'; import { BotServices } from '../services/botServices'; import { IBotSettings } from '../services/botSettings'; import { SkillDialogBase } from './skillDialogBase'; @@ -23,23 +22,19 @@ enum DialogIds { } export class SampleDialog extends SkillDialogBase { - - private readonly nameKey: string = 'name'; - // Constructor public constructor( settings: Partial, services: BotServices, stateAccessor: StatePropertyAccessor, - telemetryClient: BotTelemetryClient, templateManager: LocaleTemplateManager ) { - super(SampleDialog.name, settings, services, stateAccessor, telemetryClient, templateManager); + super(SampleDialog.name, settings, services, stateAccessor, templateManager); const sample: ((sc: WaterfallStepContext) => Promise)[] = [ // NOTE: Uncomment these lines to include authentication steps to this dialog - // GetAuthToken, - // AfterGetAuthToken, + // this.getAuthToken.bind(this), + // this.afterGetAuthToken.bind(this), this.promptForName.bind(this), this.greetUser.bind(this), this.end.bind(this) @@ -54,16 +49,15 @@ export class SampleDialog extends SkillDialogBase { private async promptForName(stepContext: WaterfallStepContext): Promise { // NOTE: Uncomment the following lines to access LUIS result for this turn. //const luisResult = sc.context.turnState.get(StateProperties.skillLuisResult); - const prompt: Partial = this.templateManager.generateActivityForLocale('NamePrompt', stepContext.context.activity.locale); + const prompt: Partial = this.templateEngine.generateActivityForLocale('NamePrompt', stepContext.context.activity.locale); return await stepContext.prompt(DialogIds.namePrompt, { prompt: prompt }); } private async greetUser(stepContext: WaterfallStepContext): Promise { - const tokens: Map = new Map(); - tokens.set(this.nameKey, stepContext.result as string); + const data: Object = { name: stepContext.result as string }; // eslint-disable-next-line @typescript-eslint/no-explicit-any - const response: any = this.templateManager.generateActivityForLocale('HaveNameMessage', stepContext.context.activity.locale, tokens); + const response: any = this.templateEngine.generateActivityForLocale('HaveNameMessage', stepContext.context.activity.locale, data); await stepContext.context.sendActivity(response); return await stepContext.next(); diff --git a/templates/typescript/samples/sample-skill/src/dialogs/skillDialogBase.ts b/templates/typescript/samples/sample-skill/src/dialogs/skillDialogBase.ts index f608d65e5b..f33a4a49fc 100644 --- a/templates/typescript/samples/sample-skill/src/dialogs/skillDialogBase.ts +++ b/templates/typescript/samples/sample-skill/src/dialogs/skillDialogBase.ts @@ -6,7 +6,6 @@ import { Activity, ActivityTypes, - BotTelemetryClient, StatePropertyAccessor } from 'botbuilder'; import { ComponentDialog, @@ -20,7 +19,7 @@ import { MultiProviderAuthDialog, LocaleTemplateManager } from 'bot-solutions'; import { TokenResponse } from 'botframework-schema'; -import { SkillState } from '../models/skillState'; +import { SkillState } from '../models'; import { BotServices} from '../services/botServices'; import { IBotSettings } from '../services/botSettings'; @@ -28,22 +27,20 @@ export class SkillDialogBase extends ComponentDialog { protected settings: Partial; protected services: BotServices; protected stateAccessor: StatePropertyAccessor; - protected templateManager: LocaleTemplateManager; + protected templateEngine: LocaleTemplateManager; public constructor( dialogId: string, settings: Partial, services: BotServices, stateAccessor: StatePropertyAccessor, - telemetryClient: BotTelemetryClient, - templateManager: LocaleTemplateManager + templateEngine: LocaleTemplateManager ) { super(dialogId); this.services = services; this.stateAccessor = stateAccessor; - this.telemetryClient = telemetryClient; this.settings = settings; - this.templateManager = templateManager; + this.templateEngine = templateEngine; // NOTE: Uncomment the following if your skill requires authentication // if (!services.authenticationConnections.any()) @@ -124,7 +121,7 @@ export class SkillDialogBase extends ComponentDialog { }); // send error message to bot user - await sc.context.sendActivity(this.templateManager.generateActivityForLocale('ErrorMessage', sc.context.activity.locale)); + await sc.context.sendActivity(this.templateEngine.generateActivityForLocale('ErrorMessage', sc.context.activity.locale)); // clear state // eslint-disable-next-line @typescript-eslint/no-explicit-any From bb4c28db5e31ff0f77bf317e362edb4ada634a3a Mon Sep 17 00:00:00 2001 From: matiasroldan6 Date: Thu, 23 Jul 2020 17:16:40 -0300 Subject: [PATCH 02/17] Add changes to deployment folder --- .../deployment/scripts/deploy.ps1 | 233 +++++++++++++----- .../scripts/deploy_cognitive_models.ps1 | 53 ++-- .../deployment/scripts/luis_functions.ps1 | 229 +++++++---------- 3 files changed, 279 insertions(+), 236 deletions(-) diff --git a/templates/typescript/samples/sample-skill/deployment/scripts/deploy.ps1 b/templates/typescript/samples/sample-skill/deployment/scripts/deploy.ps1 index c6861c8318..437bd4c788 100644 --- a/templates/typescript/samples/sample-skill/deployment/scripts/deploy.ps1 +++ b/templates/typescript/samples/sample-skill/deployment/scripts/deploy.ps1 @@ -19,6 +19,87 @@ Param( [string] $logFile = $(Join-Path $PSScriptRoot .. "deploy_log.txt") ) +function ParseValidationResult +( + [ValidateNotNullOrEmpty()] + [System.Collections.ArrayList] + $ValidationResult +) +{ + # If there is a single ErrorRecord item in the validation result array, then we take that to mean that + # the stderr output stream from running the 'az group deployment validate' command spat out an error. + # + if ($ValidationResult.Count -eq 1 -and $ValidationResult[0] -is [System.Management.Automation.ErrorRecord]) + { + # There are two error formats we could be dealing with: + # 1) We are dealing with a locally-throw exception with a regular exception message; or + # 2) A JSON service error was returned, and the exception message contains the JSON payload. + + # Per GitHub Issue https://github.com/Azure/azure-cli/issues/13037, validation errors are not returned as + # valid JSON. To handle this, parse out the error code and message manually and return an object containing + # the parsed details. + # + $expression = "('code'\s*:\s*['`"]{1}(?[^'`"]*)['`"]{1})|('message'\s*:\s*`"(?[^`"]*)`")" + $regex = New-Object System.Text.RegularExpressions.Regex($expression) + $matches = $regex.Matches($ValidationResult[0].Exception.Message) + + # Here, we parse out only successful match groups where the name matches the capture group names in the expression above. + # + $groupNames = @("code", "message") + $groups = if ($matches) { $matches.Groups | Where-Object { $_.Success -and $groupNames -contains $_.Name } } else { $null } + + # If we don't have any matches, then assume this is a non-service error, and take the exception message as-is. + # + # If we do match on at least one property, then build a Hashtable object that contains the unique properties. + # In JSON representation, this will look like the following: + # + # { + # "code": "ErrorCode", + # "message": "Description of the returned validation error code." + # } + # + # From that, we can concatenate the service error properties into a single message string. + # + if (-not $groups -or $groups.Count -eq 0) + { + $validationError = @{ + "message" = $ValidationResult[0].Exception.Message + } + } + else + { + $serviceError = @{} + foreach ($group in $groups) + { + $serviceError[$group.Name] = $group.Value + } + + $messageComponents = @() + foreach ($groupName in $groupNames) + { + if ($serviceError[$groupName]) + { + $messageComponents += $serviceError[$groupName] + } + } + + $validationError = @{ + "message" = [String]::Join(" : ", $messageComponents) + } + } + + return @{ + "error" = $validationError + } + } + + # If a single ErrorRecord was not returned in the validation results array, then we assume that the validation + # operation was successful, and that the contents of the array are each line of the returned JSON payload. + # In this case, pipe all lines into ConvertFrom-Json to return the parsed PSCustomObject. + # + return $ValidationResult | ConvertFrom-Json +} + # Src folder path $srcDir = $(Join-Path $projDir "src") @@ -93,7 +174,7 @@ if (-not $luisAuthoringKey) { else { $createLuisAuthoring = $true } - } + } } else { $createLuisAuthoring = $false @@ -142,72 +223,94 @@ Write-Host "Done." -ForegroundColor Green # Deploy Azure services (deploys LUIS, QnA Maker, Content Moderator, CosmosDB) if ($parametersFile) { - Write-Host "> Validating Azure deployment ..." -NoNewline - $validation = az deployment group validate ` - --resource-group $resourcegroup ` - --template-file "$(Join-Path $PSScriptRoot '..' 'Resources' 'template.json')" ` - --parameters "@$($parametersFile)" ` - --parameters name=$name microsoftAppId=$appId microsoftAppPassword="`"$($appPassword)`"" luisAuthoringLocation=$armLuisAuthoringRegion useLuisAuthoring=$createLuisAuthoring ` - --output json - - if ($validation) { - $validation >> $logFile - $validation = $validation | ConvertFrom-Json - - if (-not $validation.error) { - Write-Host "Done." -ForegroundColor Green - Write-Host "> Deploying Azure services (this could take a while)..." -ForegroundColor Yellow -NoNewline - $deployment = az deployment group create ` - --name $timestamp ` - --resource-group $resourceGroup ` - --template-file "$(Join-Path $PSScriptRoot '..' 'Resources' 'template.json')" ` - --parameters "@$($parametersFile)" ` - --parameters name=$name microsoftAppId=$appId microsoftAppPassword="`"$($appPassword)`"" luisAuthoringLocation=$armLuisAuthoringRegion useLuisAuthoring=$createLuisAuthoring ` - --output json 2>> $logFile | Out-Null - - Write-Host "Done." -ForegroundColor Green - } - else { - Write-Host "! Template is not valid with provided parameters. Review the log for more information." -ForegroundColor Red - Write-Host "! Error: $($validation.error.message)" -ForegroundColor Red - Write-Host "! Log: $($logFile)" -ForegroundColor Red - Write-Host "+ To delete this resource group, run 'az group delete -g $($resourceGroup) --no-wait'" -ForegroundColor Magenta - Break - } - } + Write-Host "> Validating Azure deployment ..." -NoNewline + + # To explain the syntax here: + # - 'az deployment group validate' is being executed with supplied parameters prefixed with '--' + # - 2>&1 merges the stderr output stream into stdout, ensuring all output from the executed command comes through stdout + # - stdout is piped into Tee-Object to write the contents of stdout to our log file, and capture the piped contents in a variable, $validation + # - The stream is finally piped on into Out-Null so that it does not get rendered to the host + # + az deployment group validate ` + --resource-group $resourcegroup ` + --template-file "$(Join-Path $PSScriptRoot '..' 'resources' 'template.json')" ` + --parameters "@$($parametersFile)" ` + --parameters name=$name microsoftAppId=$appId microsoftAppPassword="`"$($appPassword)`"" luisAuthoringLocation=$armLuisAuthoringRegion useLuisAuthoring=$createLuisAuthoring ` + --output json ` + 2>&1 ` + | Tee-Object -FilePath $logFile -OutVariable validation ` + | Out-Null + + # OutVariable always outputs the contents of the piped output stream as System.Collections.ArrayList, so now let's parse into + # a format that is a little easier to evaluate. + # + $validation = ParseValidationResult -ValidationResult $validation + + if ($validation.error) { + Write-Host "! Template is not valid with provided parameters. Review the log for more information." -ForegroundColor Red + Write-Host "! Error: $($validation.error.message)" -ForegroundColor Red + Write-Host "! Log: $($logFile)" -ForegroundColor Red + Write-Host "+ To delete this resource group, run 'az group delete -g $($resourceGroup) --no-wait'" -ForegroundColor Magenta + break + } + + Write-Host "Done." -ForegroundColor Green + + Write-Host "> Deploying Azure services (this could take a while)..." -ForegroundColor Yellow -NoNewline + + az deployment group create ` + --name $timestamp ` + --resource-group $resourceGroup ` + --template-file "$(Join-Path $PSScriptRoot '..' 'resources' 'template.json')" ` + --parameters "@$($parametersFile)" ` + --parameters name=$name microsoftAppId=$appId microsoftAppPassword="`"$($appPassword)`"" luisAuthoringLocation=$armLuisAuthoringRegion useLuisAuthoring=$createLuisAuthoring ` + --output json 2>> $logFile | Out-Null + + Write-Host "Done." -ForegroundColor Green } else { - Write-Host "> Validating Azure deployment ..." -NoNewline - $validation = az deployment group validate ` - --resource-group $resourcegroup ` - --template-file "$(Join-Path $PSScriptRoot '..' 'Resources' 'template.json')" ` - --parameters name=$name microsoftAppId=$appId microsoftAppPassword="`"$($appPassword)`"" luisAuthoringLocation=$armLuisAuthoringRegion useLuisAuthoring=$createLuisAuthoring ` - --output json - - if ($validation) { - $validation >> $logFile - $validation = $validation | ConvertFrom-Json - - if (-not $validation.error) { - Write-Host "Done." -ForegroundColor Green - Write-Host "> Deploying Azure services (this could take a while)..." -ForegroundColor Yellow -NoNewline - $deployment = az deployment group create ` - --name $timestamp ` - --resource-group $resourceGroup ` - --template-file "$(Join-Path $PSScriptRoot '..' 'Resources' 'template.json')" ` - --parameters name=$name microsoftAppId=$appId microsoftAppPassword="`"$($appPassword)`"" luisAuthoringLocation=$armLuisAuthoringRegion useLuisAuthoring=$createLuisAuthoring ` - --output json 2>> $logFile | Out-Null - - Write-Host "Done." -ForegroundColor Green - } - else { - Write-Host "! Template is not valid with provided parameters. Review the log for more information." -ForegroundColor Red - Write-Host "! Error: $($validation.error.message)" -ForegroundColor Red - Write-Host "! Log: $($logFile)" -ForegroundColor Red - Write-Host "+ To delete this resource group, run 'az group delete -g $($resourceGroup) --no-wait'" -ForegroundColor Magenta - Break - } - } + Write-Host "> Validating Azure deployment ..." -NoNewline + + # To explain the syntax here: + # - 'az deployment group validate' is being executed with supplied parameters prefixed with '--' + # - 2>&1 merges the stderr output stream into stdout, ensuring all output from the executed command comes through stdout + # - stdout is piped into Tee-Object to write the contents of stdout to our log file, and capture the piped contents in a variable, $validation + # - The stream is finally piped on into Out-Null so that it does not get rendered to the host + # + az deployment group validate ` + --resource-group $resourcegroup ` + --template-file "$(Join-Path $PSScriptRoot '..' 'resources' 'template.json')" ` + --parameters name=$name microsoftAppId=$appId microsoftAppPassword="`"$($appPassword)`"" luisAuthoringLocation=$armLuisAuthoringRegion useLuisAuthoring=$createLuisAuthoring ` + --output json ` + 2>&1 ` + | Tee-Object -FilePath $logFile -OutVariable validation ` + | Out-Null + + # OutVariable always outputs the contents of the piped output stream as System.Collections.ArrayList, so now let's parse into + # a format that is a little easier to evaluate. + # + $validation = ParseValidationResult -ValidationResult $validation + + if ($validation.error) { + Write-Host "! Template is not valid with provided parameters. Review the log for more information." -ForegroundColor Red + Write-Host "! Error: $($validation.error.message)" -ForegroundColor Red + Write-Host "! Log: $($logFile)" -ForegroundColor Red + Write-Host "+ To delete this resource group, run 'az group delete -g $($resourceGroup) --no-wait'" -ForegroundColor Magenta + break + } + + Write-Host "Done." -ForegroundColor Green + + Write-Host "> Deploying Azure services (this could take a while)..." -ForegroundColor Yellow -NoNewline + + az deployment group create ` + --name $timestamp ` + --resource-group $resourceGroup ` + --template-file "$(Join-Path $PSScriptRoot '..' 'resources' 'template.json')" ` + --parameters name=$name microsoftAppId=$appId microsoftAppPassword="`"$($appPassword)`"" luisAuthoringLocation=$armLuisAuthoringRegion useLuisAuthoring=$createLuisAuthoring ` + --output json 2>> $logFile | Out-Null + + Write-Host "Done." -ForegroundColor Green } # Get deployment outputs diff --git a/templates/typescript/samples/sample-skill/deployment/scripts/deploy_cognitive_models.ps1 b/templates/typescript/samples/sample-skill/deployment/scripts/deploy_cognitive_models.ps1 index 037f4419a0..0f191d5781 100644 --- a/templates/typescript/samples/sample-skill/deployment/scripts/deploy_cognitive_models.ps1 +++ b/templates/typescript/samples/sample-skill/deployment/scripts/deploy_cognitive_models.ps1 @@ -191,28 +191,27 @@ foreach ($language in $languageArr) # Deploy LUIS model $luisApp = DeployLUIS ` -name $name ` - -lu_file $lu ` - -region $luisAuthoringRegion ` - -authoringKey $luisAuthoringKey ` - -language $language ` - -gov $gov ` + -luFile $lu ` + -endpoint $luisEndpoint ` + -subscriptionKey $luisAuthoringKey ` + -culture $language ` -log $logFile Write-Host "> Setting LUIS subscription key ..." -NoNewline if ($luisApp) { # Setting subscription key - $addKeyResult = luis add appazureaccount ` - --appId $luisApp.id ` - --authoringKey $luisAuthoringKey ` - --region $luisAuthoringRegion ` - --accountName $luisAccountName ` - --azureSubscriptionId $azAccount.id ` - --resourceGroup $resourceGroup ` - --cloud $cloud ` - --armToken "$($azAccessToken.accessToken)" 2>> $logFile - - if (-not $addKeyResult) { + $addKeyResult = bf luis:application:assignazureaccount ` + --accountName $luisAccountName ` + --resourceGroup $resourceGroup ` + --armToken $azAccessToken.accessToken ` + --azureSubscriptionId $azAccount.id ` + --appId $luisApp.id ` + --endpoint $luisEndpoint ` + --subscriptionKey $luisAuthoringKey 2>> $logFile + + if ($addKeyResult -ne "Account successfully assigned.") { $luisKeySet = $false + $addKeyResult >> $logFile Write-Host "! Could not assign subscription key automatically. Review the log for more information. " -ForegroundColor DarkRed Write-Host "! Log: $($logFile)" -ForegroundColor DarkRed Write-Host "+ Please assign your subscription key manually in the LUIS portal." -ForegroundColor Magenta @@ -339,18 +338,18 @@ foreach ($language in $languageArr) # Setting subscription key Write-Host "> Setting LUIS subscription key ..." -NoNewline - $addKeyResult = luis add appazureaccount ` - --appId $dispatchApp.appId ` - --accountName $luisAccountName ` - --authoringKey $luisAuthoringKey ` - --region $luisAuthoringRegion ` - --azureSubscriptionId $azAccount.id ` - --resourceGroup $resourceGroup ` - --cloud $cloud ` - --armToken $azAccessToken.accessToken 2>> $logFile - - if (-not $addKeyResult) { + $addKeyResult = bf luis:application:assignazureaccount ` + --accountName $luisAccountName ` + --resourceGroup $resourceGroup ` + --armToken $azAccessToken.accessToken ` + --azureSubscriptionId $azAccount.id ` + --appId $dispatchApp.appId ` + --endpoint $luisEndpoint ` + --subscriptionKey $luisAuthoringKey 2>> $logFile + + if ($addKeyResult -ne "Account successfully assigned.") { $luisKeySet = $false + $addKeyResult >> $logFile Write-Host "! Could not assign subscription key automatically. Review the log for more information. " -ForegroundColor DarkRed Write-Host "! Log: $($logFile)" -ForegroundColor DarkRed Write-Host "+ Please assign your subscription key manually in the LUIS portal." -ForegroundColor Magenta diff --git a/templates/typescript/samples/sample-skill/deployment/scripts/luis_functions.ps1 b/templates/typescript/samples/sample-skill/deployment/scripts/luis_functions.ps1 index 9b75a9ee76..62739df8be 100644 --- a/templates/typescript/samples/sample-skill/deployment/scripts/luis_functions.ps1 +++ b/templates/typescript/samples/sample-skill/deployment/scripts/luis_functions.ps1 @@ -1,218 +1,159 @@ -function DeployLUIS ($name, $lu_file, $region, $authoringKey, $language, $gov, $log) +function DeployLUIS ($name, $luFile, $endpoint, $subscriptionKey, $culture, $log) { - $id = $lu_file.BaseName - $outFile = Join-Path $lu_file.DirectoryName "$($id).json" - $appName = "$($name)$($langCode)_$($id)" - - if ($gov) - { - $cloud = 'us' - } - else - { - $cloud = 'com' - } + $id = $luFile.BaseName + $outFile = Join-Path $luFile.DirectoryName "$($id).json" + $appName = "$($name)$($culture)_$($id)" - Write-Host "> Parsing $($language) $($id) LU file ..." -NoNewline + Write-Host "> Converting $($language) $($id) LU file ..." -NoNewline bf luis:convert ` - --name $appName ` - --in $lu_file ` - --culture $language ` + --in $luFile ` --out $outFile ` - --force 2>> $log | Out-Null + --name $appName ` + --culture $culture ` + --force Write-Host "Done." -ForegroundColor Green Write-Host "> Deploying $($language) $($id) LUIS app ..." -NoNewline - $luisApp = (luis import application ` - --appName $appName ` - --authoringKey $authoringKey ` - --subscriptionKey $authoringKey ` - --region $region ` + $result = bf luis:application:import ` --in $outFile ` - --cloud $cloud ` - --wait) 2>> $log | ConvertFrom-Json + --name $appName ` + --endpoint $endpoint ` + --subscriptionKey $subscriptionKey ` + --json ` + --save | ConvertFrom-Json - if (-not $luisApp) - { - Write-Host "! Could not deploy LUIS model. Review the log for more information." -ForegroundColor DarkRed - Write-Host "! Log: $($log)" -ForegroundColor DarkRed - Return $null - } - else - { + if ($result.Status -eq "Success") { Write-Host "Done." -ForegroundColor Green + + $luisApp = bf luis:application:show ` + --appId $result.id ` + --endpoint $endpoint ` + --subscriptionKey $subscriptionKey | ConvertFrom-Json + Write-Host "> Training and publishing LUIS app ..." -NoNewline - $(luis train version ` + $(bf luis:train:run ` --appId $luisApp.id ` - --region $region ` - --authoringKey $authoringKey ` + --endpoint $endpoint ` + --subscriptionKey $subscriptionKey ` --versionId $luisApp.activeVersion ` - --cloud $cloud ` --wait - & luis publish version ` + & bf luis:application:publish ` --appId $luisApp.id ` - --region $region ` - --authoringKey $authoringKey ` - --versionId $luisApp.activeVersion ` - --cloud $cloud ` - --wait) 2>> $log | Out-Null + --endpoint $endpoint ` + --subscriptionKey $subscriptionKey ` + --versionId $luisApp.activeVersion) 2>> $log | Out-Null Write-Host "Done." -ForegroundColor Green - Return $luisApp - } + Return $luisApp + } + else { + Write-Host "! Could not deploy LUIS model. Review the log for more information." -ForegroundColor DarkRed + Write-Host "! Log: $($log)" -ForegroundColor DarkRed + Return $null + } } -function UpdateLUIS ($lu_file, $appId, $version, $language, $region, $authoringKey, $subscriptionKey, $gov, $log) +function UpdateLUIS ($luFile, $appId, $endpoint, $subscriptionKey, $culture, $version, $log) { - $id = $lu_file.BaseName - $outFile = Join-Path $lu_file.DirectoryName "$($id).json" + $id = $luFile.BaseName + $outFile = Join-Path $luFile.DirectoryName "$($id).json" $appName = "$($name)$($culture)_$($id)" - - if ($gov) - { - $cloud = 'us' - } - else - { - $cloud = 'com' - } - Write-Host "> Getting hosted $($language) $($id) LUIS model settings..." -NoNewline - $luisApp = (luis get application ` + Write-Host "> Getting hosted $($culture) $($id) LUIS model settings..." -NoNewline + $luisApp = bf luis:application:show ` --appId $appId ` - --region $region ` - --authoringKey $authoringKey ` - --cloud $cloud) 2>> $log | ConvertFrom-Json + --endpoint $endpoint ` + --subscriptionKey $subscriptionKey | ConvertFrom-Json Write-Host "Done." -ForegroundColor Green - Write-Host "> Parsing $($language) $($id) LU file ..." -NoNewline - ($output = bf luis:convert ` - --name $appName ` - --in $lu_file ` - --culture $luisApp.culture ` + + Write-Host "> Converting $($culture) $($id) LU file ..." -NoNewline + bf luis:convert ` + --in $luFile ` --out $outFile ` - --force 2>&1) >> $log + --name $appName ` + --culture $culture ` + --force 2>> $log | Out-Null if (-not (Test-Path $outFile)) { Write-Host "Error." -ForegroundColor Red Write-Host "! File not created. Review the log for more information." -ForegroundColor Red - Write-Host "! Log: $($log)" -ForegroundColor Red - Break - } - - if ($output -match 'error') { - Write-Host "Error." -ForegroundColor Red - Write-Host "! Could not parse the LU file. Review the log for more information." -ForegroundColor Red - Write-Host "! Log: $($log)" -ForegroundColor Red + Write-Host "! Log: $($log)" -ForegroundColor Red Break } else { Write-Host "Done." -ForegroundColor Green } - + + Write-Host "> Getting current versions ..." -NoNewline - $versions = (luis list versions ` + $versions = bf luis:version:list ` --appId $appId ` - --region $region ` - --authoringKey $authoringKey ` - --cloud $cloud) 2>> $log | ConvertFrom-Json + --endpoint $endpoint ` + --subscriptionKey $subscriptionKey 2>> $log | ConvertFrom-Json Write-Host "Done." -ForegroundColor Green + if ($versions | Where { $_.version -eq $version }) { if ($versions | Where { $_.version -eq "backup" }) { Write-Host "> Deleting old backup version ..." -NoNewline - luis delete version ` + bf luis:version:delete ` + --versionId "backup" ` --appId $appId ` - --versionId backup ` - --region $region ` - --authoringKey $authoringKey ` - --cloud $cloud ` - --force ` - --wait 2>> $log | Out-Null + --endpoint $endpoint ` + --subscriptionKey $subscriptionKey 2>> $log | Out-Null Write-Host "Done." -ForegroundColor Green } Write-Host "> Saving current version as backup ..." -NoNewline - luis rename version ` - --appId $appId ` + bf luis:version:rename ` --versionId $version ` - --region $region ` - --newVersionId backup ` - --authoringKey $authoringKey ` - --subscriptionKey $subscriptionKey ` - --cloud $cloud ` - --wait 2>> $log | Out-Null + --newVersionId "backup" ` + --appId $appId ` + --endpoint $endpoint ` + --subscriptionKey $subscriptionKey 2>> $log | Out-Null Write-Host "Done." -ForegroundColor Green } Write-Host "> Importing new version ..." -NoNewline - ($output = luis import version ` + $result = bf luis:version:import ` + --in $outFile ` --appId $appId ` - --authoringKey $authoringKey ` + --endpoint $endpoint ` --subscriptionKey $subscriptionKey ` --versionId $version ` - --region $region ` - --cloud $cloud ` - --in $outFile ` - --wait 2>&1) >> $log - - if ($output) { - Write-Host "Error." -ForegroundColor Red + --json 2>> $log | ConvertFrom-Json - Write-Host "> Looking for backup versions ..." -NoNewline - $versions = (luis list versions ` - --appId $appId ` - --region $region ` - --authoringKey $authoringKey ` - --cloud $cloud) 2>> $log | ConvertFrom-Json - - if ($versions | Where { $_.version -eq 'backup' }) - { - Write-Host "Done." -ForegroundColor Green - - Write-Host "> Setting backup version as active ..." -NoNewline - luis set $appId ` - --versionId 'backup' ` - --authoringKey $authoringKey ` - --subscriptionKey $subscriptionKey ` - --region $region ` - --cloud $cloud ` - --force 2>> $log | Out-Null - Write-Host "Done." - } - else { - Write-Host "! No backup version found. Please review your LUIS application in the LUIS portal to resolve any issues." -ForegroundColor Red - Break - } + if ($result.Status -eq 'Success') { + Write-Host "Done." -ForegroundColor Green } else { - Write-Host "Done." -ForegroundColor Green + Write-Host "Error." -ForegroundColor Red + Write-Host "! Could not import new version. Please review your LUIS application in the LUIS portal to resolve any issues." -ForegroundColor Red + Break } Write-Host "> Training and publishing LUIS app ..." -NoNewline - $(luis train version ` + $(bf luis:train:run ` --appId $luisApp.id ` - --region $region ` - --authoringKey $authoringKey ` + --endpoint $endpoint ` + --subscriptionKey $subscriptionKey ` --versionId $luisApp.activeVersion ` - --cloud $cloud ` --wait - & luis publish version ` + & bf luis:application:publish ` --appId $luisApp.id ` - --region $region ` - --authoringKey $authoringKey ` - --versionId $luisApp.activeVersion ` - --cloud $cloud ` - --wait) 2>> $log | Out-Null + --endpoint $endpoint ` + --subscriptionKey $subscriptionKey ` + --versionId $luisApp.activeVersion) 2>> $log | Out-Null Write-Host "Done." -ForegroundColor Green } -function RunLuisGen($lu_file, $outName, $outFolder, $log) +function RunLuisGen($luFile, $outName, $outFolder, $log) { - $id = $lu_file.BaseName - $luisFolder = $lu_file.DirectoryName + $id = $luFile.BaseName + $luisFolder = $luFile.DirectoryName $luisFile = Join-Path $luisFolder "$($id).json" bf luis:generate:ts ` From 4fa948309f461b3acc58c0ec8bbc0650490d1ed8 Mon Sep 17 00:00:00 2001 From: matiasroldan6 Date: Thu, 23 Jul 2020 17:17:20 -0300 Subject: [PATCH 03/17] Add changes to services folder --- .../sample-skill/src/services/botServices.ts | 121 +++++++++--------- .../sample-skill/src/services/botSettings.ts | 4 +- 2 files changed, 64 insertions(+), 61 deletions(-) diff --git a/templates/typescript/samples/sample-skill/src/services/botServices.ts b/templates/typescript/samples/sample-skill/src/services/botServices.ts index 9ecafefea2..caf963a890 100644 --- a/templates/typescript/samples/sample-skill/src/services/botServices.ts +++ b/templates/typescript/samples/sample-skill/src/services/botServices.ts @@ -4,73 +4,81 @@ */ import { BotTelemetryClient } from 'botbuilder'; -import { LuisApplication, LuisPredictionOptions, LuisRecognizer, QnAMaker, QnAMakerEndpoint } from 'botbuilder-ai'; -import { ICognitiveModelConfiguration, ICognitiveModelSet } from 'bot-solutions'; -import { DispatchService, LuisService, QnaMakerService } from 'botframework-config'; +import { + LuisApplication, + LuisRecognizer, + LuisRecognizerOptionsV3, + QnAMaker, + QnAMakerEndpoint +} from 'botbuilder-ai'; +import { CognitiveModelConfiguration, ICognitiveModelSet } from 'bot-solutions'; +import { LuisService, QnaMakerService } from 'botframework-config'; import { IBotSettings } from './botSettings'; export class BotServices { public cognitiveModelSets: Map> = new Map(); - public constructor(settings: Partial, telemetryClient: BotTelemetryClient) { - const luisPredictionOptions: LuisPredictionOptions = { - telemetryClient: telemetryClient, - logPersonalInformation: true - }; + public constructor(settings: IBotSettings, client: BotTelemetryClient) { + settings.cognitiveModels.forEach((value: CognitiveModelConfiguration, key: string): void => { - if (settings.cognitiveModels !== undefined) { - settings.cognitiveModels.forEach((value: ICognitiveModelConfiguration, key: string): void => { + const language: string = key; + const config: CognitiveModelConfiguration = value; - const language: string = key; - const config: ICognitiveModelConfiguration = value; - const cognitiveModelSet: Partial = { - luisServices: new Map() - }; + const telemetryClient: BotTelemetryClient = client; - if (config.dispatchModel !== undefined) { - const dispatchModel: DispatchService = new DispatchService(config.dispatchModel); + const luisOptions: LuisRecognizerOptionsV3 = { + telemetryClient: telemetryClient, + logPersonalInformation: true, + apiVersion: 'v3' + }; - const dispatchApp: LuisApplication = { - applicationId: dispatchModel.appId, - endpointKey: dispatchModel.subscriptionKey, - endpoint: dispatchModel.getEndpoint() - }; + let set: Partial = { + luisServices: new Map(), + qnaConfiguration: new Map(), + qnaServices: new Map() + }; + if (config.dispatchModel !== undefined) { + const dispatchModel: LuisService = new LuisService(config.dispatchModel); + const dispatchApp: LuisApplication = { + applicationId: dispatchModel.appId, + endpointKey: dispatchModel.subscriptionKey, + endpoint: dispatchModel.getEndpoint() + }; - cognitiveModelSet.dispatchService = new LuisRecognizer(dispatchApp, luisPredictionOptions); - } + set.dispatchService= new LuisRecognizer(dispatchApp, luisOptions); + } + + if (config.languageModels !== undefined) { + config.languageModels.forEach((model: LuisService): void => { + const luisModel: LuisService = new LuisService(model); + const luisApp: LuisApplication = { + applicationId: luisModel.appId, + endpointKey: luisModel.subscriptionKey, + endpoint: luisModel.getEndpoint() + }; - if (config.languageModels !== undefined) { - config.languageModels.forEach((model: LuisService): void => { - const luisService: LuisService = new LuisService(model); - const luisApp: LuisApplication = { - applicationId: luisService.appId, - endpointKey: luisService.subscriptionKey, - endpoint: luisService.getEndpoint() - }; - if (cognitiveModelSet.luisServices !== undefined) { - cognitiveModelSet.luisServices.set(luisService.id, new LuisRecognizer(luisApp, luisPredictionOptions)); - } - }); - } + if (set.luisServices !== undefined) { + set.luisServices.set(model.id, new LuisRecognizer(luisApp, luisOptions)); + } + }); + } - if (config.knowledgeBases !== undefined) { - config.knowledgeBases.forEach((kb: QnaMakerService): void => { - const qnaEndpoint: QnAMakerEndpoint = { - knowledgeBaseId: kb.kbId, - endpointKey: kb.endpointKey, - host: kb.hostname - }; - const qnaMaker: QnAMaker = new QnAMaker(qnaEndpoint, undefined, telemetryClient, true); + if (config.knowledgeBases !== undefined) { + config.knowledgeBases.forEach((kb: QnaMakerService): void => { + const qnaEndpoint: QnAMakerEndpoint = { + knowledgeBaseId: kb.kbId, + endpointKey: kb.endpointKey, + host: kb.hostname + }; - if (cognitiveModelSet.qnaServices !== undefined) { - cognitiveModelSet.qnaServices.set(kb.id, qnaMaker); - } - }); - } - this.cognitiveModelSets.set(language, cognitiveModelSet); - }); - } + if (set.qnaServices !== undefined) { + set.qnaServices.set(kb.id, new QnAMaker(qnaEndpoint, undefined, client, true)); + } + }); + } + this.cognitiveModelSets.set(language, set); + }); } public getCognitiveModels(locale: string): Partial { @@ -79,12 +87,7 @@ export class BotServices { if (cognitiveModels === undefined) { const keyFound: string | undefined = Array.from(this.cognitiveModelSets.keys()) - // eslint-disable-next-line @typescript-eslint/explicit-function-return-type - .find((key: string) => { - if (key.substring(0, 2) === locale.substring(0, 2)) { - return key; - } - }); + .find((key: string) => { key.substring(0, 2) === locale.substring(0, 2); }); if (keyFound !== undefined) { cognitiveModels = this.cognitiveModelSets.get(keyFound); } diff --git a/templates/typescript/samples/sample-skill/src/services/botSettings.ts b/templates/typescript/samples/sample-skill/src/services/botSettings.ts index 61c6ccd28c..c07e7a19b7 100644 --- a/templates/typescript/samples/sample-skill/src/services/botSettings.ts +++ b/templates/typescript/samples/sample-skill/src/services/botSettings.ts @@ -2,9 +2,9 @@ * Copyright(c) Microsoft Corporation.All rights reserved. * Licensed under the MIT License. */ -import { IBotSettingsBase } from 'bot-solutions'; +import { BotSettingsBase } from 'bot-solutions'; // eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface IBotSettings extends IBotSettingsBase { +export interface IBotSettings extends BotSettingsBase { } From b2677076a2e180e8db0bd841a8b4649b96cf7717 Mon Sep 17 00:00:00 2001 From: matiasroldan6 Date: Thu, 23 Jul 2020 17:18:31 -0300 Subject: [PATCH 04/17] Add changes to adapters folder --- .../src/adapters/defaultAdapter.ts | 133 ++++++++++++------ 1 file changed, 88 insertions(+), 45 deletions(-) diff --git a/templates/typescript/samples/sample-skill/src/adapters/defaultAdapter.ts b/templates/typescript/samples/sample-skill/src/adapters/defaultAdapter.ts index 1d1ab55007..765487fd13 100644 --- a/templates/typescript/samples/sample-skill/src/adapters/defaultAdapter.ts +++ b/templates/typescript/samples/sample-skill/src/adapters/defaultAdapter.ts @@ -4,11 +4,12 @@ */ import { - ActivityTypes, BotFrameworkAdapter, BotFrameworkAdapterSettings, BotTelemetryClient, + ConversationState, ShowTypingMiddleware, + TelemetryException, TelemetryLoggerMiddleware, TranscriptLoggerMiddleware, TurnContext } from 'botbuilder'; @@ -16,66 +17,51 @@ import { EventDebuggerMiddleware, SetLocaleMiddleware, LocaleTemplateManager, - SetSpeakMiddleware } from 'bot-solutions'; + SetSpeakMiddleware, + ActivityEx } from 'bot-solutions'; import { IBotSettings } from '../services/botSettings'; import { TurnContextEx } from '../extensions/turnContextEx'; import { AzureBlobTranscriptStore, BlobStorageSettings } from 'botbuilder-azure'; import { TelemetryInitializerMiddleware } from 'botbuilder-applicationinsights'; -import { Activity } from 'botframework-schema'; export class DefaultAdapter extends BotFrameworkAdapter { + private readonly conversationState: ConversationState; + private readonly telemetryClient: BotTelemetryClient; + private readonly templateEngine: LocaleTemplateManager; + public constructor( settings: Partial, - adapterSettings: Partial, - templateManager: LocaleTemplateManager, + templateEngine: LocaleTemplateManager, + conversationState: ConversationState, telemetryMiddleware: TelemetryInitializerMiddleware, telemetryClient: BotTelemetryClient, + adapterSettings: Partial ) { super(adapterSettings); - this.onTurnError = async (context: TurnContext, error: Error): Promise => { - await context.sendActivity({ - type: ActivityTypes.Trace, - text: error.message || JSON.stringify(error) - }); - await context.sendActivity({ - type: ActivityTypes.Trace, - text: error.stack - }); - - await context.sendActivity(templateManager.generateActivityForLocale('ErrorMessage', context.activity.locale)); - telemetryClient.trackException({ exception: error }); - - if (TurnContextEx.isSkill(context)){ - // Send and EndOfConversation activity to the skill caller with the error to end the conversation - // and let the caller decide what to do. - const endOfconversation: Partial = { - type: ActivityTypes.EndOfConversation, - code: 'SkillError', - text: error.message - }; - await context.sendActivity(endOfconversation); - } - }; - - this.onTurnError = async (context: TurnContext, error: Error): Promise => { - await context.sendActivity({ - type: ActivityTypes.Trace, - text: error.message || JSON.stringify(error) - }); - await context.sendActivity({ - type: ActivityTypes.Trace, - text: error.stack - }); - await context.sendActivity(templateManager.generateActivityForLocale('ErrorMessage', context.activity.locale)); - telemetryClient.trackException({ exception: error }); - }; - - if (settings.blobStorage === undefined) { - throw new Error('There is no blobStorage value in appsettings file'); + + if (conversationState === undefined) { + throw new Error('conversationState parameter is null'); + } + this.conversationState = conversationState; + + if (templateEngine === undefined) { + throw new Error('templateEngine parameter is null'); } + this.templateEngine = templateEngine; + + if (telemetryClient === undefined) { + throw new Error('telemetryClient parameter is null'); + } + this.telemetryClient = telemetryClient; + + this.onTurnError = this.handleTurnError; this.use(telemetryMiddleware); + + if (settings.blobStorage === undefined) { + throw new Error('There is no blobStorage value in appsettings file'); + } // Uncomment the following line for local development without Azure Storage // this.use(new TranscriptLoggerMiddleware(new MemoryTranscriptStore())); @@ -87,4 +73,61 @@ export class DefaultAdapter extends BotFrameworkAdapter { this.use(new EventDebuggerMiddleware()); this.use(new SetSpeakMiddleware()); } + + private async handleTurnError(turnContext: TurnContext, error: Error): Promise { + // Log any leaked exception from the application. + console.error(`[onTurnError] unhandled error : ${ error }`); + + await this.sendErrorMessage(turnContext, error); + await this.sendEndOfConversationToParent(turnContext, error); + await this.clearConversationStateAsync(turnContext); + } + + private async sendErrorMessage(turnContext: TurnContext, error: Error): Promise { + try { + const telemetryException: TelemetryException = { + exception: error + }; + this.telemetryClient.trackException(telemetryException); + + // Send a message to the user. + await turnContext.sendActivity(this.templateEngine.generateActivityForLocale('ErrorMessage', turnContext.activity.locale)); + + // Send a trace activity, which will be displayed in the Bot Framework Emulator. + // Note: we return the entire exception in the value property to help the developer; + // this should not be done in production. + await turnContext.sendTraceActivity('OnTurnError Trace', error.message, 'https://www.botframework.com/schemas/error', 'TurnError'); + } + catch (err) { + console.error(`Exception caught in sendErrorMessage : ${ err }`); + } + } + + private async sendEndOfConversationToParent(turnContext: TurnContext, error: Error): Promise { + try { + if (TurnContextEx.isSkill(turnContext)) { + // Send and EndOfConversation activity to the skill caller with the error to end the conversation + // and let the caller decide what to do. + const endOfConversation = ActivityEx.createEndOfConversationActivity(); + endOfConversation.code = 'SkillError'; + endOfConversation.text = error.message; + await turnContext.sendActivity(endOfConversation); + } + } + catch (err) { + console.error(`Exception caught in sendEoCToParent : ${ err }`); + } + } + + private async clearConversationStateAsync(turnContext: TurnContext): Promise { + try { + // Delete the conversationState for the current conversation to prevent the + // bot from getting stuck in a error-loop caused by being in a bad state. + // ConversationState should be thought of as similar to "cookie-state" for a Web page. + await this.conversationState.delete(turnContext); + } + catch (err) { + console.error(`Exception caught on attempting to Delete ConversationState : ${ err }`); + } + } } From f70808967adb1ebfcf7aa93bbdb5ca1c51f9b065 Mon Sep 17 00:00:00 2001 From: matiasroldan6 Date: Thu, 23 Jul 2020 17:19:02 -0300 Subject: [PATCH 05/17] Add changes to bots folder --- .../sample-skill/src/bots/defaultActivityHandler.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/templates/typescript/samples/sample-skill/src/bots/defaultActivityHandler.ts b/templates/typescript/samples/sample-skill/src/bots/defaultActivityHandler.ts index 41383fbdd9..e2f91680c1 100644 --- a/templates/typescript/samples/sample-skill/src/bots/defaultActivityHandler.ts +++ b/templates/typescript/samples/sample-skill/src/bots/defaultActivityHandler.ts @@ -8,6 +8,7 @@ import { ActivityHandler, ActivityTypes, BotState, + BotTelemetryClient, Channels, StatePropertyAccessor, TurnContext } from 'botbuilder'; @@ -20,16 +21,17 @@ export class DefaultActivityHandler extends ActivityHandler { private readonly dialog: Dialog; private readonly conversationState: BotState; private readonly userState: BotState; - private dialogStateAccessor: StatePropertyAccessor; - private templateManager: LocaleTemplateManager; + private readonly dialogStateAccessor: StatePropertyAccessor; + private readonly templateEngine: LocaleTemplateManager; - public constructor(conversationState: BotState, userState: BotState, templateManager: LocaleTemplateManager, dialog: T) { + public constructor(conversationState: BotState, userState: BotState, templateManager: LocaleTemplateManager, telemetryClient: BotTelemetryClient, dialog: T) { super(); this.dialog = dialog; + this.dialog.telemetryClient = telemetryClient; this.conversationState = conversationState; this.userState = userState; this.dialogStateAccessor = conversationState.createProperty('DialogState'); - this.templateManager = templateManager; + this.templateEngine = templateManager; super.onMembersAdded(this.membersAdded.bind(this)); } @@ -42,7 +44,7 @@ export class DefaultActivityHandler extends ActivityHandler { } protected async membersAdded(turnContext: TurnContext, next: () => Promise): Promise { - await turnContext.sendActivity(this.templateManager.generateActivityForLocale('IntroMessage', turnContext.activity.locale)); + await turnContext.sendActivity(this.templateEngine.generateActivityForLocale('IntroMessage', turnContext.activity.locale)); await DialogEx.run(this.dialog, turnContext, this.dialogStateAccessor); } From 12910cdd65c6b5930451dd0524786f73a0d3e5ed Mon Sep 17 00:00:00 2001 From: matiasroldan6 Date: Thu, 23 Jul 2020 17:19:14 -0300 Subject: [PATCH 06/17] Add changes to extensions folder --- .../samples/sample-skill/src/extensions/turnContextEx.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/typescript/samples/sample-skill/src/extensions/turnContextEx.ts b/templates/typescript/samples/sample-skill/src/extensions/turnContextEx.ts index e72ba4cc48..9fd5892cf8 100644 --- a/templates/typescript/samples/sample-skill/src/extensions/turnContextEx.ts +++ b/templates/typescript/samples/sample-skill/src/extensions/turnContextEx.ts @@ -10,7 +10,7 @@ export namespace TurnContextEx { export function isSkill(turnContext: TurnContext): boolean { // eslint-disable-next-line @typescript-eslint/no-explicit-any - const botIdentity = turnContext.turnState.get((turnContext.adapter as any).BotIdentityKey); + const botIdentity = turnContext.turnState.get(turnContext.adapter.BotIdentityKey); return botIdentity instanceof ClaimsIdentity && SkillValidation.isSkillClaim(botIdentity.claims) ? true : false; } From 6db611d9d375577e35a26f1472d319038200e943 Mon Sep 17 00:00:00 2001 From: matiasroldan6 Date: Thu, 23 Jul 2020 17:19:58 -0300 Subject: [PATCH 07/17] Add authentication folder --- .../allowedCallersClaimsValidator.ts | 39 +++++++++++++++++++ .../sample-skill/src/authentication/index.ts | 6 +++ 2 files changed, 45 insertions(+) create mode 100644 templates/typescript/samples/sample-skill/src/authentication/allowedCallersClaimsValidator.ts create mode 100644 templates/typescript/samples/sample-skill/src/authentication/index.ts diff --git a/templates/typescript/samples/sample-skill/src/authentication/allowedCallersClaimsValidator.ts b/templates/typescript/samples/sample-skill/src/authentication/allowedCallersClaimsValidator.ts new file mode 100644 index 0000000000..7e3da61c8f --- /dev/null +++ b/templates/typescript/samples/sample-skill/src/authentication/allowedCallersClaimsValidator.ts @@ -0,0 +1,39 @@ +/** + * Copyright(c) Microsoft Corporation.All rights reserved. + * Licensed under the MIT License. + */ + +import { Claim, JwtTokenValidation, SkillValidation } from 'botframework-connector'; + +/** + * Sample claims validator that loads an allowed list from configuration + * and checks that requests are coming from allowed parent bots. + */ +export class AllowedCallersClaimsValidator { + private readonly configKey: string = 'allowedCallers'; + private readonly allowedCallers: string[]; + + public constructor(allowedCallers: string[]) { + // AllowedCallers is the setting in the appsettings.json file + // that consists of the list of parent bot IDs that are allowed to access the skill. + // To add a new parent bot, simply edit the AllowedCallers and add + // the parent bot's Microsoft app ID to the list. + // In this sample, we allow all callers if AllowedCallers contains an "*". + if (allowedCallers === undefined) { + throw new Error('allowedCallers parameter is undefined.'); + } + + this.allowedCallers = allowedCallers; + } + + public validateClaims(claims: Claim[]): void { + // If _allowedCallers contains an "*", we allow all callers. + if (SkillValidation.isSkillClaim(claims) && !this.allowedCallers.includes('*')) { + // Check that the appId claim in the skill request is in the list of callers configured for this bot. + const appId: string = JwtTokenValidation.getAppIdFromClaims(claims); + if (!this.allowedCallers.includes(appId)) { + throw new Error(`Received a request from a bot with an app ID of ${ appId }. To enable requests from this caller, add the app ID to your configuration file.`); + } + } + } +} \ No newline at end of file diff --git a/templates/typescript/samples/sample-skill/src/authentication/index.ts b/templates/typescript/samples/sample-skill/src/authentication/index.ts new file mode 100644 index 0000000000..88d0178322 --- /dev/null +++ b/templates/typescript/samples/sample-skill/src/authentication/index.ts @@ -0,0 +1,6 @@ +/** + * Copyright(c) Microsoft Corporation.All rights reserved. + * Licensed under the MIT License. + */ + +export * from './allowedCallersClaimsValidator'; \ No newline at end of file From 260d92cd42bf8626dcc431f0a2de88fba03166f9 Mon Sep 17 00:00:00 2001 From: matiasroldan6 Date: Thu, 23 Jul 2020 17:21:28 -0300 Subject: [PATCH 08/17] Add changes to src folder --- .../samples/sample-skill/src/appsettings.json | 7 +-- .../sample-skill/src/cognitivemodels.json | 2 +- .../samples/sample-skill/src/index.ts | 52 ++++++++----------- 3 files changed, 28 insertions(+), 33 deletions(-) diff --git a/templates/typescript/samples/sample-skill/src/appsettings.json b/templates/typescript/samples/sample-skill/src/appsettings.json index 9f1a046da9..74c7a270cb 100644 --- a/templates/typescript/samples/sample-skill/src/appsettings.json +++ b/templates/typescript/samples/sample-skill/src/appsettings.json @@ -1,6 +1,7 @@ { "microsoftAppId": "", "microsoftAppPassword": "", + "allowedCallers": [ "*" ], "oauthConnections": [], "skillAuthenticationWhitelist": [], "appInsights": { @@ -8,13 +9,13 @@ }, "blobStorage": { "connectionString": "", - "container": "" + "container": "transcripts" }, "cosmosDb": { "authKey": "", "cosmosDbEndpoint": "", - "containerId": "", - "databaseId": "" + "containerId": "botstate-collection", + "databaseId": "botstate-db" }, "properties": {} } \ No newline at end of file diff --git a/templates/typescript/samples/sample-skill/src/cognitivemodels.json b/templates/typescript/samples/sample-skill/src/cognitivemodels.json index e82c80af6b..e1aca5936d 100644 --- a/templates/typescript/samples/sample-skill/src/cognitivemodels.json +++ b/templates/typescript/samples/sample-skill/src/cognitivemodels.json @@ -13,7 +13,7 @@ "subscriptionKey": "" }, { - "id": "skill", + "id": "sampleSkill", "name": "", "appId": "", "version": "0.1", diff --git a/templates/typescript/samples/sample-skill/src/index.ts b/templates/typescript/samples/sample-skill/src/index.ts index 16a2fad493..6a22019a0b 100644 --- a/templates/typescript/samples/sample-skill/src/index.ts +++ b/templates/typescript/samples/sample-skill/src/index.ts @@ -4,7 +4,6 @@ */ import { - BotFrameworkAdapter, BotFrameworkAdapterSettings, BotTelemetryClient, ConversationState, @@ -18,7 +17,7 @@ import { CosmosDbPartitionedStorageOptions, CosmosDbPartitionedStorage } from 'b import { Dialog } from 'botbuilder-dialogs'; import { - ICognitiveModelConfiguration, + CognitiveModelConfiguration, LocaleTemplateManager } from 'bot-solutions'; import { join } from 'path'; import * as restify from 'restify'; @@ -29,19 +28,19 @@ import * as cognitiveModelsRaw from './cognitivemodels.json'; import { MainDialog } from './dialogs/mainDialog'; import { SampleDialog } from './dialogs/sampleDialog'; import { SampleAction } from './dialogs/sampleAction'; -import { SkillState } from './models/skillState'; +import { SkillState } from './models'; import { BotServices } from './services/botServices'; import { IBotSettings } from './services/botSettings'; -const cognitiveModels: Map = new Map(); +const cognitiveModels: Map = new Map(); const cognitiveModelDictionary: { [key: string]: Object } = cognitiveModelsRaw.cognitiveModels; const cognitiveModelMap: Map = new Map(Object.entries(cognitiveModelDictionary)); cognitiveModelMap.forEach((value: Object, key: string): void => { - cognitiveModels.set(key, value as ICognitiveModelConfiguration); + cognitiveModels.set(key, value as CognitiveModelConfiguration); }); // Load settings -const botSettings: Partial = { +const settings: Partial = { appInsights: appsettings.appInsights, blobStorage: appsettings.blobStorage, cognitiveModels: cognitiveModels, @@ -50,7 +49,7 @@ const botSettings: Partial = { microsoftAppId: appsettings.microsoftAppId, microsoftAppPassword: appsettings.microsoftAppPassword }; -if (botSettings.appInsights === undefined) { +if (settings.appInsights === undefined) { throw new Error('There is no appInsights value in appsettings file'); } @@ -65,20 +64,20 @@ function getTelemetryClient(settings: Partial): BotTelemetryClient } // Configure telemetry -const telemetryClient: BotTelemetryClient = getTelemetryClient(botSettings); +const telemetryClient: BotTelemetryClient = getTelemetryClient(settings); const telemetryLoggerMiddleware: TelemetryLoggerMiddleware = new TelemetryLoggerMiddleware(telemetryClient); const telemetryInitializerMiddleware: TelemetryInitializerMiddleware = new TelemetryInitializerMiddleware(telemetryLoggerMiddleware); -if (botSettings.cosmosDb === undefined) { +if (settings.cosmosDb === undefined) { throw new Error(); } // Configure storage const cosmosDbStorageOptions: CosmosDbPartitionedStorageOptions = { - authKey: botSettings.cosmosDb.authKey, - containerId: botSettings.cosmosDb.containerId, - databaseId: botSettings.cosmosDb.databaseId, - cosmosDbEndpoint: botSettings.cosmosDb.cosmosDbEndpoint + authKey: settings.cosmosDb.authKey, + containerId: settings.cosmosDb.containerId, + databaseId: settings.cosmosDb.databaseId, + cosmosDbEndpoint: settings.cosmosDb.cosmosDbEndpoint }; const storage: CosmosDbPartitionedStorage = new CosmosDbPartitionedStorage(cosmosDbStorageOptions); const userState: UserState = new UserState(storage); @@ -98,52 +97,47 @@ supportedLocales.forEach((locale: string) => { localizedTemplates.set(locale, localTemplateFile); }); -const localeTemplateManager: LocaleTemplateManager = new LocaleTemplateManager(localizedTemplates, botSettings.defaultLocale || 'en-us'); +const localeTemplateManager: LocaleTemplateManager = new LocaleTemplateManager(localizedTemplates, settings.defaultLocale || 'en-us'); const adapterSettings: Partial = { - appId: botSettings.microsoftAppId, - appPassword: botSettings.microsoftAppPassword + appId: settings.microsoftAppId, + appPassword: settings.microsoftAppPassword }; const defaultAdapter: DefaultAdapter = new DefaultAdapter( - botSettings, - adapterSettings, + settings, localeTemplateManager, + conversationState, telemetryInitializerMiddleware, - telemetryClient); - -const adapter: BotFrameworkAdapter = defaultAdapter; + telemetryClient, + adapterSettings); let bot: DefaultActivityHandler; try { // Configure bot services - const botServices: BotServices = new BotServices(botSettings, telemetryClient); + const botServices: BotServices = new BotServices(settings as IBotSettings, telemetryClient); // Register dialogs const sampleDialog: SampleDialog = new SampleDialog( - botSettings, + settings, botServices, stateAccessor, - telemetryClient, localeTemplateManager ); const sampleAction: SampleAction = new SampleAction( - botSettings, + settings, botServices, stateAccessor, - telemetryClient, localeTemplateManager ); const mainDialog: MainDialog = new MainDialog( botServices, - telemetryClient, - stateAccessor, sampleDialog, sampleAction, localeTemplateManager ); - bot = new DefaultActivityHandler(conversationState, userState, localeTemplateManager, mainDialog); + bot = new DefaultActivityHandler(conversationState, userState, localeTemplateManager, telemetryClient, mainDialog); } catch (err) { throw err; } From 4d6dafa050d9d6b3a2fc07138c86ca60f86dd51f Mon Sep 17 00:00:00 2001 From: matiasroldan6 Date: Thu, 23 Jul 2020 17:21:53 -0300 Subject: [PATCH 09/17] Add changes to root folder --- .../samples/sample-skill/.eslintrc.json | 4 +- .../samples/sample-skill/package-lock.json | 405 +++++++++--------- .../samples/sample-skill/package.json | 1 + 3 files changed, 197 insertions(+), 213 deletions(-) diff --git a/templates/typescript/samples/sample-skill/.eslintrc.json b/templates/typescript/samples/sample-skill/.eslintrc.json index 02aebb9da8..2b593c4e7d 100644 --- a/templates/typescript/samples/sample-skill/.eslintrc.json +++ b/templates/typescript/samples/sample-skill/.eslintrc.json @@ -25,9 +25,7 @@ "@typescript-eslint/indent": ["error", 4], "@typescript-eslint/interface-name-prefix": 0, "@typescript-eslint/no-explicit-any": 0, - "@typescript-eslint/no-object-literal-type-assertion": ["error", { - "allowAsParameter": true - }], + "@typescript-eslint/consistent-type-assertions": ["error"], "@typescript-eslint/no-use-before-define": ["error", { "functions": false, "classes": true }], "@typescript-eslint/ban-types": 0 } diff --git a/templates/typescript/samples/sample-skill/package-lock.json b/templates/typescript/samples/sample-skill/package-lock.json index e35d8d119b..9eadeb6826 100644 --- a/templates/typescript/samples/sample-skill/package-lock.json +++ b/templates/typescript/samples/sample-skill/package-lock.json @@ -339,7 +339,7 @@ "dependencies": { "extsprintf": { "version": "1.4.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/extsprintf/-/extsprintf-1.4.0.tgz", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.0.tgz", "integrity": "sha1-4mifjzVvrWLMplo6kcXfX5VRaS8=" } } @@ -434,7 +434,7 @@ }, "@types/express-jwt": { "version": "0.0.34", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/@types/express-jwt/-/@types/express-jwt-0.0.34.tgz", + "resolved": "https://registry.npmjs.org/@types/express-jwt/-/express-jwt-0.0.34.tgz", "integrity": "sha1-/b7kxq9cCiRu8qkz9VGZc8dxfwI=", "requires": { "@types/express": "*", @@ -469,21 +469,6 @@ "@types/node": "*" } }, - "@types/i18next": { - "version": "2.3.41", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/@types/i18next/-/@types/i18next-2.3.41.tgz", - "integrity": "sha1-Wj69y0lCBSyi73HE9jQUOMV8sYw=", - "dev": true - }, - "@types/i18next-node-fs-backend": { - "version": "0.0.30", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/@types/i18next-node-fs-backend/-/@types/i18next-node-fs-backend-0.0.30.tgz", - "integrity": "sha1-dFT46SN5ii6/FjCb78/f3jLpCnw=", - "dev": true, - "requires": { - "@types/i18next": "^2" - } - }, "@types/json-schema": { "version": "7.0.4", "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/@types/json-schema/-/@types/json-schema-7.0.4.tgz", @@ -586,7 +571,7 @@ }, "@types/xmldom": { "version": "0.1.29", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/@types/xmldom/-/@types/xmldom-0.1.29.tgz", + "resolved": "https://registry.npmjs.org/@types/xmldom/-/xmldom-0.1.29.tgz", "integrity": "sha1-xEKLDKhtO4gUdXJv2UmAs4onw4E=" }, "@typescript-eslint/eslint-plugin": { @@ -868,7 +853,7 @@ }, "archy": { "version": "1.0.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/archy/-/archy-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", "dev": true }, @@ -899,7 +884,7 @@ }, "assert-plus": { "version": "1.0.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/assert-plus/-/assert-plus-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" }, "assertion-error": { @@ -941,7 +926,7 @@ }, "asynckit": { "version": "0.4.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/asynckit/-/asynckit-0.4.0.tgz", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" }, "atob": { @@ -951,7 +936,7 @@ }, "aws-sign2": { "version": "0.7.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/aws-sign2/-/aws-sign2-0.7.0.tgz", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" }, "aws4": { @@ -995,17 +980,17 @@ "dependencies": { "sax": { "version": "0.5.8", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/sax/-/sax-0.5.8.tgz", + "resolved": "https://registry.npmjs.org/sax/-/sax-0.5.8.tgz", "integrity": "sha1-1HLbIo6zMcJQaw6MFVJK25OdEsE=" }, "underscore": { "version": "1.8.3", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/underscore/-/underscore-1.8.3.tgz", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" }, "xml2js": { "version": "0.2.8", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/xml2js/-/xml2js-0.2.8.tgz", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.2.8.tgz", "integrity": "sha1-m4FpCTFjH/CdGVdUn69U9PmAs8I=", "requires": { "sax": "0.5.x" @@ -1013,14 +998,14 @@ }, "xmlbuilder": { "version": "9.0.7", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/xmlbuilder/-/xmlbuilder-9.0.7.tgz", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=" } } }, "balanced-match": { "version": "1.0.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/balanced-match/-/balanced-match-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" }, "base64url": { @@ -1030,7 +1015,7 @@ }, "bcrypt-pbkdf": { "version": "1.0.2", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", "requires": { "tweetnacl": "^0.14.3" @@ -1054,7 +1039,7 @@ }, "binary-search-bounds": { "version": "2.0.3", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/binary-search-bounds/-/binary-search-bounds-2.0.3.tgz", + "resolved": "https://registry.npmjs.org/binary-search-bounds/-/binary-search-bounds-2.0.3.tgz", "integrity": "sha1-X/hhbW3SylOIvIWy1iZuK52lAtw=" }, "bot-solutions": { @@ -1382,17 +1367,17 @@ }, "browserify-mime": { "version": "1.2.9", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/browserify-mime/-/browserify-mime-1.2.9.tgz", + "resolved": "https://registry.npmjs.org/browserify-mime/-/browserify-mime-1.2.9.tgz", "integrity": "sha1-rrGvKN5sDXpqLOQK22j/GEIq8x8=" }, "buffer-equal-constant-time": { "version": "1.0.1", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" }, "bunyan": { "version": "1.8.12", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/bunyan/-/bunyan-1.8.12.tgz", + "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.8.12.tgz", "integrity": "sha1-8VDw9nSKvdcq6uhPBEA74u8RN5c=", "requires": { "dtrace-provider": "~0.8", @@ -1482,7 +1467,7 @@ }, "caseless": { "version": "0.12.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/caseless/-/caseless-0.12.0.tgz", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" }, "chai": { @@ -1544,13 +1529,13 @@ }, "charenc": { "version": "0.0.2", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/charenc/-/charenc-0.0.2.tgz", + "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=", "dev": true }, "check-error": { "version": "1.0.2", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/check-error/-/check-error-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", "dev": true }, @@ -1589,7 +1574,7 @@ }, "cli-cursor": { "version": "2.1.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/cli-cursor/-/cli-cursor-2.1.0.tgz", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", "dev": true, "requires": { @@ -1615,7 +1600,7 @@ }, "clone-response": { "version": "1.0.2", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/clone-response/-/clone-response-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", "dev": true, "requires": { @@ -1657,13 +1642,13 @@ }, "commondir": { "version": "1.0.1", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/commondir/-/commondir-1.0.1.tgz", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", "dev": true }, "concat-map": { "version": "0.0.1", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/concat-map/-/concat-map-0.0.1.tgz", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, "configstore": { @@ -1744,7 +1729,7 @@ }, "core-util-is": { "version": "1.0.2", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/core-util-is/-/core-util-is-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, "cp-file": { @@ -1786,7 +1771,7 @@ }, "crypt": { "version": "0.0.2", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/crypt/-/crypt-0.0.2.tgz", + "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=", "dev": true }, @@ -1824,7 +1809,7 @@ }, "dashdash": { "version": "1.14.1", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/dashdash/-/dashdash-1.14.1.tgz", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", "requires": { "assert-plus": "^1.0.0" @@ -1832,7 +1817,7 @@ }, "date-utils": { "version": "1.2.21", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/date-utils/-/date-utils-1.2.21.tgz", + "resolved": "https://registry.npmjs.org/date-utils/-/date-utils-1.2.21.tgz", "integrity": "sha1-YfsWzcEnSzyayq/+n8ad+HIKK2Q=" }, "dayjs": { @@ -1850,13 +1835,13 @@ }, "decamelize": { "version": "1.2.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/decamelize/-/decamelize-1.2.0.tgz", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", "dev": true }, "decompress-response": { "version": "3.3.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/decompress-response/-/decompress-response-3.3.0.tgz", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", "dev": true, "requires": { @@ -1894,13 +1879,13 @@ }, "deep-is": { "version": "0.1.3", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/deep-is/-/deep-is-0.1.3.tgz", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", "dev": true }, "default-require-extensions": { "version": "2.0.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/default-require-extensions/-/default-require-extensions-2.0.0.tgz", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-2.0.0.tgz", "integrity": "sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc=", "dev": true, "requires": { @@ -1924,17 +1909,17 @@ }, "delayed-stream": { "version": "1.0.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/delayed-stream/-/delayed-stream-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" }, "depd": { "version": "1.1.2", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/depd/-/depd-1.1.2.tgz", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" }, "destroy": { "version": "1.0.4", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/destroy/-/destroy-1.0.4.tgz", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" }, "detect-node": { @@ -1944,7 +1929,7 @@ }, "diagnostic-channel": { "version": "0.2.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/diagnostic-channel/-/diagnostic-channel-0.2.0.tgz", + "resolved": "https://registry.npmjs.org/diagnostic-channel/-/diagnostic-channel-0.2.0.tgz", "integrity": "sha1-zJmvlhLCP7H/8TYSxy8sv6qNWhc=", "requires": { "semver": "^5.3.0" @@ -1986,7 +1971,7 @@ "dependencies": { "semaphore": { "version": "1.0.5", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/semaphore/-/semaphore-1.0.5.tgz", + "resolved": "https://registry.npmjs.org/semaphore/-/semaphore-1.0.5.tgz", "integrity": "sha1-tJJXbmavGT25XWXiXsU/Xxl5jWA=" }, "tunnel": { @@ -1996,7 +1981,7 @@ }, "underscore": { "version": "1.8.3", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/underscore/-/underscore-1.8.3.tgz", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" } } @@ -2026,18 +2011,18 @@ }, "duplexer": { "version": "0.1.1", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/duplexer/-/duplexer-0.1.1.tgz", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=" }, "duplexer3": { "version": "0.1.4", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/duplexer3/-/duplexer3-0.1.4.tgz", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", "dev": true }, "ecc-jsbn": { "version": "0.1.2", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", "requires": { "jsbn": "~0.1.0", @@ -2054,7 +2039,7 @@ }, "ee-first": { "version": "1.1.1", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/ee-first/-/ee-first-1.1.1.tgz", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, "emitter-listener": { @@ -2073,7 +2058,7 @@ }, "encodeurl": { "version": "1.0.2", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/encodeurl/-/encodeurl-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" }, "end-of-stream": { @@ -2137,17 +2122,17 @@ }, "escape-html": { "version": "1.0.3", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/escape-html/-/escape-html-1.0.3.tgz", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" }, "escape-regexp-component": { "version": "1.0.2", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/escape-regexp-component/-/escape-regexp-component-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/escape-regexp-component/-/escape-regexp-component-1.0.2.tgz", "integrity": "sha1-nGO20LJf8qiMOtvRjFthrMO5+qI=" }, "escape-string-regexp": { "version": "1.0.5", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, "eslint": { @@ -2196,7 +2181,7 @@ "dependencies": { "ansi-regex": { "version": "3.0.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/ansi-regex/-/ansi-regex-3.0.0.tgz", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", "dev": true }, @@ -2256,7 +2241,7 @@ }, "strip-ansi": { "version": "4.0.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/strip-ansi/-/strip-ansi-4.0.0.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "dev": true, "requires": { @@ -2352,7 +2337,7 @@ }, "etag": { "version": "1.8.1", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/etag/-/etag-1.8.1.tgz", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" }, "eventemitter3": { @@ -2400,7 +2385,7 @@ }, "extsprintf": { "version": "1.3.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/extsprintf/-/extsprintf-1.3.0.tgz", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" }, "fast-decode-uri-component": { @@ -2420,13 +2405,13 @@ }, "fast-levenshtein": { "version": "2.0.6", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, "figures": { "version": "2.0.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/figures/-/figures-2.0.0.tgz", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", "dev": true, "requires": { @@ -2444,7 +2429,7 @@ }, "filename-reserved-regex": { "version": "2.0.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", + "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", "integrity": "sha1-q/c9+rc10EVECr/qLZHzieu/oik=" }, "filenamify": { @@ -2576,7 +2561,7 @@ }, "foreground-child": { "version": "1.5.6", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/foreground-child/-/foreground-child-1.5.6.tgz", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-1.5.6.tgz", "integrity": "sha1-T9ca0t/elnibmApcCilZN8svXOk=", "dev": true, "requires": { @@ -2586,7 +2571,7 @@ "dependencies": { "cross-spawn": { "version": "4.0.2", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/cross-spawn/-/cross-spawn-4.0.2.tgz", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=", "dev": true, "requires": { @@ -2606,7 +2591,7 @@ }, "yallist": { "version": "2.1.2", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/yallist/-/yallist-2.1.2.tgz", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", "dev": true } @@ -2614,7 +2599,7 @@ }, "forever-agent": { "version": "0.6.1", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/forever-agent/-/forever-agent-0.6.1.tgz", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" }, "form-data": { @@ -2634,7 +2619,7 @@ }, "fresh": { "version": "0.5.2", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/fresh/-/fresh-0.5.2.tgz", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" }, "fs-extra": { @@ -2649,7 +2634,7 @@ }, "fs.realpath": { "version": "1.0.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/fs.realpath/-/fs.realpath-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, @@ -2668,7 +2653,7 @@ }, "functional-red-black-tree": { "version": "1.0.1", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", "dev": true }, @@ -2680,7 +2665,7 @@ }, "get-func-name": { "version": "2.0.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/get-func-name/-/get-func-name-2.0.0.tgz", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", "dev": true }, @@ -2694,7 +2679,7 @@ }, "getpass": { "version": "0.1.7", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/getpass/-/getpass-0.1.7.tgz", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", "requires": { "assert-plus": "^1.0.0" @@ -2702,7 +2687,7 @@ }, "glob": { "version": "6.0.4", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/glob/-/glob-6.0.4.tgz", + "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", "optional": true, "requires": { @@ -2787,7 +2772,7 @@ }, "har-schema": { "version": "2.0.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/har-schema/-/har-schema-2.0.0.tgz", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" }, "har-validator": { @@ -2810,7 +2795,7 @@ }, "has-flag": { "version": "3.0.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/has-flag/-/has-flag-3.0.0.tgz", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true }, @@ -2855,7 +2840,7 @@ }, "hasha": { "version": "3.0.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/hasha/-/hasha-3.0.0.tgz", + "resolved": "https://registry.npmjs.org/hasha/-/hasha-3.0.0.tgz", "integrity": "sha1-UqMvq4Vp1BymmmH/GiFPjrfIvTk=", "dev": true, "requires": { @@ -2876,7 +2861,7 @@ }, "hpack.js": { "version": "2.1.6", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/hpack.js/-/hpack.js-2.1.6.tgz", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=", "requires": { "inherits": "^2.0.1", @@ -2899,12 +2884,12 @@ }, "http-deceiver": { "version": "1.2.7", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/http-deceiver/-/http-deceiver-1.2.7.tgz", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=" }, "http-errors": { "version": "1.6.3", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/http-errors/-/http-errors-1.6.3.tgz", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", "requires": { "depd": "~1.1.2", @@ -2915,14 +2900,14 @@ "dependencies": { "inherits": { "version": "2.0.3", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/inherits/-/inherits-2.0.3.tgz", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" } } }, "http-signature": { "version": "1.2.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/http-signature/-/http-signature-1.2.0.tgz", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", "requires": { "assert-plus": "^1.0.0", @@ -2963,7 +2948,7 @@ }, "ignore-by-default": { "version": "1.0.1", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=", "dev": true }, @@ -2979,19 +2964,19 @@ }, "import-lazy": { "version": "2.1.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/import-lazy/-/import-lazy-2.1.0.tgz", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", "dev": true }, "imurmurhash": { "version": "0.1.4", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/imurmurhash/-/imurmurhash-0.1.4.tgz", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", "dev": true }, "inflight": { "version": "1.0.6", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/inflight/-/inflight-1.0.6.tgz", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "requires": { "once": "^1.3.0", @@ -3000,7 +2985,7 @@ }, "inherits": { "version": "2.0.1", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/inherits/-/inherits-2.0.1.tgz", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=" }, "ini": { @@ -3032,7 +3017,7 @@ "dependencies": { "ansi-regex": { "version": "3.0.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/ansi-regex/-/ansi-regex-3.0.0.tgz", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", "dev": true }, @@ -3054,7 +3039,7 @@ "dependencies": { "strip-ansi": { "version": "4.0.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/strip-ansi/-/strip-ansi-4.0.0.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "dev": true, "requires": { @@ -3084,7 +3069,7 @@ }, "int64-buffer": { "version": "0.1.10", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/int64-buffer/-/int64-buffer-0.1.10.tgz", + "resolved": "https://registry.npmjs.org/int64-buffer/-/int64-buffer-0.1.10.tgz", "integrity": "sha1-J3siiofZWtd30HwTgyAiQGpHNCM=" }, "is-arguments": { @@ -3095,7 +3080,7 @@ }, "is-arrayish": { "version": "0.2.1", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/is-arrayish/-/is-arrayish-0.2.1.tgz", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", "dev": true }, @@ -3136,7 +3121,7 @@ }, "is-extglob": { "version": "2.1.1", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/is-extglob/-/is-extglob-2.1.1.tgz", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", "dev": true }, @@ -3200,7 +3185,7 @@ }, "is-stream": { "version": "1.1.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/is-stream/-/is-stream-1.1.0.tgz", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" }, "is-symbol": { @@ -3214,7 +3199,7 @@ }, "is-typedarray": { "version": "1.0.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/is-typedarray/-/is-typedarray-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" }, "is-yarn-global": { @@ -3225,17 +3210,17 @@ }, "isarray": { "version": "1.0.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/isarray/-/isarray-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, "isexe": { "version": "2.0.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/isexe/-/isexe-2.0.0.tgz", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" }, "isstream": { "version": "0.1.2", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/isstream/-/isstream-0.1.2.tgz", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" }, "istanbul-lib-coverage": { @@ -3380,7 +3365,7 @@ }, "jsbn": { "version": "0.1.1", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/jsbn/-/jsbn-0.1.1.tgz", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" }, "jschardet": { @@ -3396,13 +3381,13 @@ }, "json-buffer": { "version": "3.0.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/json-buffer/-/json-buffer-3.0.0.tgz", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", "dev": true }, "json-edm-parser": { "version": "0.1.2", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/json-edm-parser/-/json-edm-parser-0.1.2.tgz", + "resolved": "https://registry.npmjs.org/json-edm-parser/-/json-edm-parser-0.1.2.tgz", "integrity": "sha1-HmCw/vG8CvZ7wNFG393lSGzWFbQ=", "requires": { "jsonparse": "~1.2.0" @@ -3416,7 +3401,7 @@ }, "json-schema": { "version": "0.2.3", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/json-schema/-/json-schema-0.2.3.tgz", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" }, "json-schema-traverse": { @@ -3426,13 +3411,13 @@ }, "json-stable-stringify-without-jsonify": { "version": "1.0.1", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", "dev": true }, "json-stringify-safe": { "version": "5.0.1", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" }, "json5": { @@ -3445,7 +3430,7 @@ }, "jsonfile": { "version": "4.0.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/jsonfile/-/jsonfile-4.0.0.tgz", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", "requires": { "graceful-fs": "^4.1.6" @@ -3453,12 +3438,12 @@ }, "jsonparse": { "version": "1.2.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/jsonparse/-/jsonparse-1.2.0.tgz", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.2.0.tgz", "integrity": "sha1-XAxWhRBxYOcv50ib3eoLRMK8Z70=" }, "jsonwebtoken": { "version": "8.0.1", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/jsonwebtoken/-/jsonwebtoken-8.0.1.tgz", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.0.1.tgz", "integrity": "sha1-UNrvjQqMfeLNBrwQE7dbBMzz8M8=", "requires": { "jws": "^3.1.4", @@ -3480,7 +3465,7 @@ }, "jsprim": { "version": "1.4.1", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/jsprim/-/jsprim-1.4.1.tgz", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", "requires": { "assert-plus": "1.0.0", @@ -3551,7 +3536,7 @@ }, "levn": { "version": "0.3.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/levn/-/levn-0.3.0.tgz", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", "dev": true, "requires": { @@ -3566,7 +3551,7 @@ }, "load-json-file": { "version": "4.0.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/load-json-file/-/load-json-file-4.0.0.tgz", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", "dev": true, "requires": { @@ -3578,7 +3563,7 @@ "dependencies": { "pify": { "version": "3.0.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/pify/-/pify-3.0.0.tgz", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", "dev": true } @@ -3595,7 +3580,7 @@ }, "lock": { "version": "0.1.4", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/lock/-/lock-0.1.4.tgz", + "resolved": "https://registry.npmjs.org/lock/-/lock-0.1.4.tgz", "integrity": "sha1-/sfervF+fDoKVeHaBCgD4l2RdF0=" }, "lodash": { @@ -3605,78 +3590,78 @@ }, "lodash.escaperegexp": { "version": "4.1.2", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", + "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", "integrity": "sha1-ZHYsSGGAglGKw99Mz11YhtriA0c=" }, "lodash.flattendeep": { "version": "4.4.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", + "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", "dev": true }, "lodash.includes": { "version": "4.3.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/lodash.includes/-/lodash.includes-4.3.0.tgz", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", "integrity": "sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=" }, "lodash.isboolean": { "version": "3.0.3", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", "integrity": "sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=" }, "lodash.isequal": { "version": "4.5.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=" }, "lodash.isinteger": { "version": "4.0.4", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", "integrity": "sha1-YZwK89A/iwTDH1iChAt3sRzWg0M=" }, "lodash.isnumber": { "version": "3.0.3", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", "integrity": "sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w=" }, "lodash.isplainobject": { "version": "4.0.6", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=" }, "lodash.isstring": { "version": "4.0.1", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=" }, "lodash.last": { "version": "3.0.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/lodash.last/-/lodash.last-3.0.0.tgz", + "resolved": "https://registry.npmjs.org/lodash.last/-/lodash.last-3.0.0.tgz", "integrity": "sha1-JC9mMRLdTG5jcoxgo8kJ0b2tvUw=" }, "lodash.max": { "version": "4.0.1", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/lodash.max/-/lodash.max-4.0.1.tgz", + "resolved": "https://registry.npmjs.org/lodash.max/-/lodash.max-4.0.1.tgz", "integrity": "sha1-hzVWbGGLNan3YFILSHrnllivE2o=" }, "lodash.once": { "version": "4.1.1", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/lodash.once/-/lodash.once-4.1.1.tgz", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=" }, "lodash.sortby": { "version": "4.7.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=" }, "lodash.tonumber": { "version": "4.0.3", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/lodash.tonumber/-/lodash.tonumber-4.0.3.tgz", + "resolved": "https://registry.npmjs.org/lodash.tonumber/-/lodash.tonumber-4.0.3.tgz", "integrity": "sha1-C5azGzVnJ5Prf1pj7nkfG56QJdk=" }, "lodash.trimend": { "version": "4.5.1", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/lodash.trimend/-/lodash.trimend-4.5.1.tgz", + "resolved": "https://registry.npmjs.org/lodash.trimend/-/lodash.trimend-4.5.1.tgz", "integrity": "sha1-EoBENyhrmMrYmWt5QU4RMAEUCC8=" }, "log-symbols": { @@ -3715,7 +3700,7 @@ "dependencies": { "lru-cache": { "version": "4.0.2", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/lru-cache/-/lru-cache-4.0.2.tgz", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.0.2.tgz", "integrity": "sha1-HRdnnAac2l0ECZGgnbwsDbN35V4=", "requires": { "pseudomap": "^1.0.1", @@ -3724,7 +3709,7 @@ }, "yallist": { "version": "2.1.2", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/yallist/-/yallist-2.1.2.tgz", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" } } @@ -3753,7 +3738,7 @@ }, "md5": { "version": "2.2.1", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/md5/-/md5-2.2.1.tgz", + "resolved": "https://registry.npmjs.org/md5/-/md5-2.2.1.tgz", "integrity": "sha1-U6s41f48iJG6RlMp6iP6wFQBJvk=", "dev": true, "requires": { @@ -3764,7 +3749,7 @@ }, "md5.js": { "version": "1.3.4", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/md5.js/-/md5.js-1.3.4.tgz", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz", "integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=", "requires": { "hash-base": "^3.0.0", @@ -4090,7 +4075,7 @@ "dependencies": { "ansi-regex": { "version": "3.0.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/ansi-regex/-/ansi-regex-3.0.0.tgz", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", "dev": true }, @@ -4105,7 +4090,7 @@ }, "strip-ansi": { "version": "4.0.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/strip-ansi/-/strip-ansi-4.0.0.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "dev": true, "requires": { @@ -4129,7 +4114,7 @@ }, "ms": { "version": "2.0.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/ms/-/ms-2.0.0.tgz", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, "ms-rest": { @@ -4174,7 +4159,7 @@ }, "adal-node": { "version": "0.1.28", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/adal-node/-/adal-node-0.1.28.tgz", + "resolved": "https://registry.npmjs.org/adal-node/-/adal-node-0.1.28.tgz", "integrity": "sha1-RoxLs+u9lrEnBmn0ucuk4AZepIU=", "requires": { "@types/node": "^8.0.47", @@ -4200,13 +4185,13 @@ }, "mute-stream": { "version": "0.0.7", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/mute-stream/-/mute-stream-0.0.7.tgz", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", "dev": true }, "mv": { "version": "2.1.1", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/mv/-/mv-2.1.1.tgz", + "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", "integrity": "sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI=", "optional": true, "requires": { @@ -4217,7 +4202,7 @@ "dependencies": { "rimraf": { "version": "2.4.5", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/rimraf/-/rimraf-2.4.5.tgz", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", "integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=", "optional": true, "requires": { @@ -4234,13 +4219,13 @@ }, "natural-compare": { "version": "1.4.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/natural-compare/-/natural-compare-1.4.0.tgz", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, "ncp": { "version": "2.0.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/ncp/-/ncp-2.0.0.tgz", + "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=", "optional": true }, @@ -4351,7 +4336,7 @@ }, "noms": { "version": "0.0.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/noms/-/noms-0.0.0.tgz", + "resolved": "https://registry.npmjs.org/noms/-/noms-0.0.0.tgz", "integrity": "sha1-2o69nzr51nYJGbJ9nNyAkqczKFk=", "dev": true, "requires": { @@ -4361,13 +4346,13 @@ "dependencies": { "isarray": { "version": "0.0.1", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/isarray/-/isarray-0.0.1.tgz", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", "dev": true }, "readable-stream": { "version": "1.0.34", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/readable-stream/-/readable-stream-1.0.34.tgz", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "dev": true, "requires": { @@ -4379,7 +4364,7 @@ }, "string_decoder": { "version": "0.10.31", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/string_decoder/-/string_decoder-0.10.31.tgz", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", "dev": true } @@ -4387,7 +4372,7 @@ }, "nopt": { "version": "1.0.10", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/nopt/-/nopt-1.0.10.tgz", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", "dev": true, "requires": { @@ -4420,7 +4405,7 @@ }, "npm-run-path": { "version": "2.0.2", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/npm-run-path/-/npm-run-path-2.0.2.tgz", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", "requires": { "path-key": "^2.0.0" @@ -4638,7 +4623,7 @@ }, "object-assign": { "version": "4.1.1", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/object-assign/-/object-assign-4.1.1.tgz", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" }, "object-inspect": { @@ -4692,7 +4677,7 @@ }, "on-finished": { "version": "2.3.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/on-finished/-/on-finished-2.3.0.tgz", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", "requires": { "ee-first": "1.1.1" @@ -4700,7 +4685,7 @@ }, "once": { "version": "1.4.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/once/-/once-1.4.0.tgz", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "requires": { "wrappy": "1" @@ -4708,7 +4693,7 @@ }, "onetime": { "version": "2.0.1", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/onetime/-/onetime-2.0.1.tgz", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", "dev": true, "requires": { @@ -4731,7 +4716,7 @@ }, "os-homedir": { "version": "1.0.2", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/os-homedir/-/os-homedir-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", "dev": true }, @@ -4746,7 +4731,7 @@ }, "os-tmpdir": { "version": "1.0.2", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", "dev": true }, @@ -4758,7 +4743,7 @@ }, "p-finally": { "version": "1.0.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/p-finally/-/p-finally-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" }, "p-limit": { @@ -4836,7 +4821,7 @@ }, "parse-json": { "version": "4.0.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/parse-json/-/parse-json-4.0.0.tgz", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", "dev": true, "requires": { @@ -4846,7 +4831,7 @@ }, "path": { "version": "0.12.7", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/path/-/path-0.12.7.tgz", + "resolved": "https://registry.npmjs.org/path/-/path-0.12.7.tgz", "integrity": "sha1-1NwqUGxM4hl+tIHr/NWzbAFAsQ8=", "requires": { "process": "^0.11.1", @@ -4861,18 +4846,18 @@ }, "path-is-absolute": { "version": "1.0.1", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" }, "path-is-inside": { "version": "1.0.2", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/path-is-inside/-/path-is-inside-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", "dev": true }, "path-key": { "version": "2.0.1", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/path-key/-/path-key-2.0.1.tgz", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" }, "path-parse": { @@ -4892,7 +4877,7 @@ "dependencies": { "pify": { "version": "3.0.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/pify/-/pify-3.0.0.tgz", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", "dev": true } @@ -4900,13 +4885,13 @@ }, "pathval": { "version": "1.1.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/pathval/-/pathval-1.1.0.tgz", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", "dev": true }, "performance-now": { "version": "2.1.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/performance-now/-/performance-now-2.1.0.tgz", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" }, "picomatch": { @@ -4976,29 +4961,29 @@ }, "prelude-ls": { "version": "1.1.2", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/prelude-ls/-/prelude-ls-1.1.2.tgz", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", "dev": true }, "prepend-http": { "version": "2.0.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/prepend-http/-/prepend-http-2.0.0.tgz", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", "dev": true }, "priorityqueuejs": { "version": "1.0.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/priorityqueuejs/-/priorityqueuejs-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/priorityqueuejs/-/priorityqueuejs-1.0.0.tgz", "integrity": "sha1-LuTyPCVgkT4IwHzlzN1t498sWvg=" }, "process": { "version": "0.11.10", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/process/-/process-0.11.10.tgz", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=" }, "process-nextick-args": { "version": "1.0.7", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" }, "progress": { @@ -5009,13 +4994,13 @@ }, "propagate": { "version": "1.0.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/propagate/-/propagate-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/propagate/-/propagate-1.0.0.tgz", "integrity": "sha1-AMLa7t2iDofjeCs0Stuhzd1q1wk=", "dev": true }, "pseudomap": { "version": "1.0.2", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/pseudomap/-/pseudomap-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" }, "psl": { @@ -5081,7 +5066,7 @@ }, "read-pkg": { "version": "3.0.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/read-pkg/-/read-pkg-3.0.0.tgz", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", "dev": true, "requires": { @@ -5138,7 +5123,7 @@ }, "read-text-file": { "version": "1.1.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/read-text-file/-/read-text-file-1.1.0.tgz", + "resolved": "https://registry.npmjs.org/read-text-file/-/read-text-file-1.1.0.tgz", "integrity": "sha1-0MPxh2iCj5EH1huws2jue5D3GJM=", "requires": { "iconv-lite": "^0.4.17", @@ -5147,7 +5132,7 @@ }, "readable-stream": { "version": "2.0.6", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/readable-stream/-/readable-stream-2.0.6.tgz", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", "requires": { "core-util-is": "~1.0.0", @@ -5160,7 +5145,7 @@ "dependencies": { "string_decoder": { "version": "0.10.31", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/string_decoder/-/string_decoder-0.10.31.tgz", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" } } @@ -5215,7 +5200,7 @@ }, "release-zalgo": { "version": "1.0.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/release-zalgo/-/release-zalgo-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", "dev": true, "requires": { @@ -5292,7 +5277,7 @@ }, "require-directory": { "version": "2.1.1", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/require-directory/-/require-directory-2.1.1.tgz", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", "dev": true }, @@ -5304,7 +5289,7 @@ }, "requires-port": { "version": "1.0.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/requires-port/-/requires-port-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=" }, "resolve": { @@ -5324,7 +5309,7 @@ }, "responselike": { "version": "1.0.2", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/responselike/-/responselike-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", "dev": true, "requires": { @@ -5385,7 +5370,7 @@ }, "restore-cursor": { "version": "2.0.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/restore-cursor/-/restore-cursor-2.0.0.tgz", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", "dev": true, "requires": { @@ -5425,7 +5410,7 @@ }, "rsa-pem-from-mod-exp": { "version": "0.8.4", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/rsa-pem-from-mod-exp/-/rsa-pem-from-mod-exp-0.8.4.tgz", + "resolved": "https://registry.npmjs.org/rsa-pem-from-mod-exp/-/rsa-pem-from-mod-exp-0.8.4.tgz", "integrity": "sha1-NipCxtMEBW1JOz8SvOq7LGV2ptQ=" }, "run-async": { @@ -5474,7 +5459,7 @@ }, "select-hose": { "version": "2.0.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/select-hose/-/select-hose-2.0.0.tgz", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=" }, "semaphore": { @@ -5546,7 +5531,7 @@ }, "set-blocking": { "version": "2.0.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/set-blocking/-/set-blocking-2.0.0.tgz", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "dev": true }, @@ -5557,7 +5542,7 @@ }, "shebang-command": { "version": "1.2.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/shebang-command/-/shebang-command-1.2.0.tgz", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", "requires": { "shebang-regex": "^1.0.0" @@ -5565,7 +5550,7 @@ }, "shebang-regex": { "version": "1.0.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/shebang-regex/-/shebang-regex-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" }, "shimmer": { @@ -5623,7 +5608,7 @@ }, "source-map": { "version": "0.5.7", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/source-map/-/source-map-0.5.7.tgz", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true }, @@ -5745,7 +5730,7 @@ }, "sprintf-js": { "version": "1.0.3", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/sprintf-js/-/sprintf-js-1.0.3.tgz", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" }, "sshpk": { @@ -5766,7 +5751,7 @@ }, "stack-chain": { "version": "1.3.7", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/stack-chain/-/stack-chain-1.3.7.tgz", + "resolved": "https://registry.npmjs.org/stack-chain/-/stack-chain-1.3.7.tgz", "integrity": "sha1-0ZLJ/06moiyUxN1FkXHj8AzqEoU=" }, "statuses": { @@ -5776,7 +5761,7 @@ }, "stealthy-require": { "version": "1.1.1", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/stealthy-require/-/stealthy-require-1.1.1.tgz", + "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=" }, "stream-transform": { @@ -5859,18 +5844,18 @@ }, "strip-bom": { "version": "3.0.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/strip-bom/-/strip-bom-3.0.0.tgz", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", "dev": true }, "strip-eof": { "version": "1.0.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/strip-eof/-/strip-eof-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" }, "strip-json-comments": { "version": "2.0.1", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", "dev": true }, @@ -5979,13 +5964,13 @@ }, "text-table": { "version": "0.2.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/text-table/-/text-table-0.2.0.tgz", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", "dev": true }, "through": { "version": "2.3.8", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/through/-/through-2.3.8.tgz", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" }, "through2": { @@ -6053,7 +6038,7 @@ }, "to-fast-properties": { "version": "2.0.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", "dev": true }, @@ -6092,7 +6077,7 @@ }, "trim-repeated": { "version": "1.0.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/trim-repeated/-/trim-repeated-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", "integrity": "sha1-42RqLqTokTEr9+rObPsFOAvAHCE=", "requires": { "escape-string-regexp": "^1.0.2" @@ -6119,7 +6104,7 @@ }, "tunnel-agent": { "version": "0.6.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", "requires": { "safe-buffer": "^5.0.1" @@ -6127,12 +6112,12 @@ }, "tweetnacl": { "version": "0.14.5", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/tweetnacl/-/tweetnacl-0.14.5.tgz", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" }, "type-check": { "version": "0.3.2", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/type-check/-/type-check-0.3.2.tgz", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", "dev": true, "requires": { @@ -6272,7 +6257,7 @@ }, "url-parse-lax": { "version": "3.0.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", "dev": true, "requires": { @@ -6281,7 +6266,7 @@ }, "util": { "version": "0.10.3", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/util/-/util-0.10.3.tgz", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", "requires": { "inherits": "2.0.1" @@ -6289,7 +6274,7 @@ }, "util-deprecate": { "version": "1.0.2", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/util-deprecate/-/util-deprecate-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, "uuid": { @@ -6314,7 +6299,7 @@ }, "vasync": { "version": "2.2.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/vasync/-/vasync-2.2.0.tgz", + "resolved": "https://registry.npmjs.org/vasync/-/vasync-2.2.0.tgz", "integrity": "sha1-z951GGChWCLbOxMrxZsRakra8Bs=", "requires": { "verror": "1.10.0" @@ -6322,7 +6307,7 @@ }, "verror": { "version": "1.10.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/verror/-/verror-1.10.0.tgz", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", "requires": { "assert-plus": "^1.0.0", @@ -6332,7 +6317,7 @@ }, "very-fast-args": { "version": "1.1.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/very-fast-args/-/very-fast-args-1.1.0.tgz", + "resolved": "https://registry.npmjs.org/very-fast-args/-/very-fast-args-1.1.0.tgz", "integrity": "sha1-4W0dH6+KbllqJGQh/ZCneWPQs5Y=" }, "wbuf": { @@ -6353,7 +6338,7 @@ }, "which-module": { "version": "2.0.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/which-module/-/which-module-2.0.0.tgz", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", "dev": true }, @@ -6368,7 +6353,7 @@ "dependencies": { "ansi-regex": { "version": "3.0.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/ansi-regex/-/ansi-regex-3.0.0.tgz", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", "dev": true }, @@ -6390,7 +6375,7 @@ }, "strip-ansi": { "version": "4.0.0", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/strip-ansi/-/strip-ansi-4.0.0.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "dev": true, "requires": { @@ -6435,7 +6420,7 @@ }, "wrappy": { "version": "1.0.2", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/wrappy/-/wrappy-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "write": { @@ -6472,7 +6457,7 @@ }, "xml": { "version": "1.0.1", - "resolved": "https://botbuilder.myget.org/F/aitemplates/npm/xml/-/xml-1.0.1.tgz", + "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz", "integrity": "sha1-eLpyAgApxbyHuKgaPPzXS0ovweU=", "dev": true }, diff --git a/templates/typescript/samples/sample-skill/package.json b/templates/typescript/samples/sample-skill/package.json index ddaef17ab4..0f17cbb227 100644 --- a/templates/typescript/samples/sample-skill/package.json +++ b/templates/typescript/samples/sample-skill/package.json @@ -24,6 +24,7 @@ "botbuilder-applicationinsights": "^4.9.2", "botbuilder-azure": "^4.9.2", "botbuilder-dialogs": "^4.9.2", + "botbuilder-lg": "^4.9.2", "bot-solutions": "^1.0.0", "botframework-config": "^4.9.2", "botframework-connector": "^4.9.2", From f8936a2e9a5b7b31bca50120c7bd3db91f6842c6 Mon Sep 17 00:00:00 2001 From: matiasroldan6 Date: Thu, 23 Jul 2020 17:22:56 -0300 Subject: [PATCH 10/17] Add changes to test folder --- .../test/helpers/skillTestBase.js | 15 +- .../sample-skill/test/interruption.test.js | 8 +- .../interruption_cancel_response.json | 206 +++++++++------ .../interruption_help_response.json | 236 ++++++++++-------- .../mainDialog_help_response.json | 66 +++-- .../mainDialog_unhandled_response.json | 132 ++++++---- .../nockFixtures/sampleDialog_response.json | 232 +++++++++-------- 7 files changed, 524 insertions(+), 371 deletions(-) diff --git a/templates/typescript/samples/sample-skill/test/helpers/skillTestBase.js b/templates/typescript/samples/sample-skill/test/helpers/skillTestBase.js index 5c8286e3c0..cf7e013547 100644 --- a/templates/typescript/samples/sample-skill/test/helpers/skillTestBase.js +++ b/templates/typescript/samples/sample-skill/test/helpers/skillTestBase.js @@ -11,6 +11,7 @@ const { UserState } = require("botbuilder"); const { join } = require("path"); +const { TemplatesParser } = require("botbuilder-lg"); const { ApplicationInsightsTelemetryClient } = require("botbuilder-applicationinsights"); @@ -102,25 +103,21 @@ const initialize = async function() { botSettings, botServices, stateAccessor, - telemetryClient, templateManager ); const sampleAction = new SampleAction( botSettings, botServices, stateAccessor, - telemetryClient, templateManager ); const mainDialog = new MainDialog( botServices, - telemetryClient, - stateAccessor, sampleDialog, sampleAction, templateManager ); - this.bot = new DefaultActivityHandler(conversationState, userState, templateManager, mainDialog); + this.bot = new DefaultActivityHandler(conversationState, userState, templateManager, telemetryClient, mainDialog); }; /** @@ -166,8 +163,12 @@ const getTelemetryClient = function(settings) { return new NullTelemetryClient(); }; -const getTemplates = function(locale, name) { - return templateManager.lgPerLocale.get(locale).expandTemplate(name); +const getTemplates = function(locale, name, data) { + const path = locale === 'en-us' + ? join(__dirname, '..', '..', 'lib', 'responses', 'AllResponses.lg') + : join(__dirname, '..', '..', 'lib', 'responses', `AllResponses.${locale}.lg`) + + return TemplatesParser.parseFile(path).expandTemplate(name, data); }; module.exports = { diff --git a/templates/typescript/samples/sample-skill/test/interruption.test.js b/templates/typescript/samples/sample-skill/test/interruption.test.js index 4783274a52..8c313c32ca 100644 --- a/templates/typescript/samples/sample-skill/test/interruption.test.js +++ b/templates/typescript/samples/sample-skill/test/interruption.test.js @@ -16,9 +16,9 @@ describe("interruption", function() { it("send 'help' during the sample dialog", function(done) { const testAdapter = skillTestBase.getTestAdapter(); const flow = testAdapter - .send("sample dialog") + .send("run sample dialog") .assertReplyOneOf(skillTestBase.getTemplates('en-us','FirstPromptText')) - .send("sample dialog") + .send("run sample dialog") .assertReplyOneOf(skillTestBase.getTemplates('en-us','NamePromptText')) .send("help") .assertReply(function (activity) { @@ -33,9 +33,9 @@ describe("interruption", function() { it("send 'cancel' during the sample dialog", function(done) { const testAdapter = skillTestBase.getTestAdapter(); const flow = testAdapter - .send("sample dialog") + .send("run sample dialog") .assertReplyOneOf(skillTestBase.getTemplates('en-us','FirstPromptText')) - .send("sample dialog") + .send("run sample dialog") .assertReplyOneOf(skillTestBase.getTemplates('en-us','NamePromptText')) .send("cancel") .assertReplyOneOf(skillTestBase.getTemplates('en-us','CancelledText')); diff --git a/templates/typescript/samples/sample-skill/test/mocks/nockFixtures/interruption_cancel_response.json b/templates/typescript/samples/sample-skill/test/mocks/nockFixtures/interruption_cancel_response.json index 8c1cc0a1e9..8670090f20 100644 --- a/templates/typescript/samples/sample-skill/test/mocks/nockFixtures/interruption_cancel_response.json +++ b/templates/typescript/samples/sample-skill/test/mocks/nockFixtures/interruption_cancel_response.json @@ -2,16 +2,25 @@ { "scope": "https://westus.api.cognitive.microsoft.com:443", "method": "POST", - "path": "/luis/v2.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554?verbose=false&staging=false&spellCheck=false&log=true", - "body": "sample dialog", + "path": "/luis/prediction/v3.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554/slots/production/predict?verbose=true&log=true&show-all-intents=false", + "body": { + "query": "run sample dialog", + "options": { + "preferExternalEntities": true + } + }, "status": 200, "response": { - "query": "sample dialog", - "topScoringIntent": { - "intent": "Sample", - "score": 0.9705775 - }, - "entities": [] + "query": "run sample dialog", + "prediction": { + "topIntent": "Sample", + "intents": { + "Sample": { + "score": 0.9705775 + } + }, + "entities": {} + } }, "rawHeaders": [ "Cache-Control", @@ -19,15 +28,15 @@ "Pragma", "no-cache", "Content-Length", - "131", + "116", "Content-Type", "application/json; charset=utf-8", "Apim-Request-Id", - "a894c379-cfec-4b0f-8c4e-42806ff34da0", + "d9155560-6898-4d9b-9ff4-98a34b38cae1", "Request-Id", - "a894c379-cfec-4b0f-8c4e-42806ff34da0", + "d9155560-6898-4d9b-9ff4-98a34b38cae1", "CSP-Billing-Usage", - "CognitiveServices.LUIS.Transaction|1", + "CognitiveServices.LUIS.Transaction=1", "Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload", "X-Content-Type-Options", @@ -35,7 +44,7 @@ "X-Frame-Options", "SAMEORIGIN", "Date", - "Tue, 07 Apr 2020 15:15:21 GMT", + "Thu, 16 Jul 2020 18:21:31 GMT", "Connection", "close" ] @@ -43,16 +52,25 @@ { "scope": "https://westus.api.cognitive.microsoft.com:443", "method": "POST", - "path": "/luis/v2.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554?verbose=false&staging=false&spellCheck=false&log=true", - "body": "sample dialog", + "path": "/luis/prediction/v3.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554/slots/production/predict?verbose=true&log=true&show-all-intents=false", + "body": { + "query": "run sample dialog", + "options": { + "preferExternalEntities": true + } + }, "status": 200, "response": { - "query": "sample dialog", - "topScoringIntent": { - "intent": "Confirm", - "score": 0.12141446 - }, - "entities": [] + "query": "run sample dialog", + "prediction": { + "topIntent": "Confirm", + "intents": { + "Confirm": { + "score": 0.148891255 + } + }, + "entities": {} + } }, "rawHeaders": [ "Cache-Control", @@ -60,15 +78,15 @@ "Pragma", "no-cache", "Content-Length", - "133", + "120", "Content-Type", "application/json; charset=utf-8", "Apim-Request-Id", - "3f40e459-6baa-4812-a2ec-0f1504a2785c", + "390e15ac-6a40-4b10-a909-16d19051e30e", "Request-Id", - "3f40e459-6baa-4812-a2ec-0f1504a2785c", + "390e15ac-6a40-4b10-a909-16d19051e30e", "CSP-Billing-Usage", - "CognitiveServices.LUIS.Transaction|1", + "CognitiveServices.LUIS.Transaction=1", "Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload", "X-Content-Type-Options", @@ -76,7 +94,7 @@ "X-Frame-Options", "SAMEORIGIN", "Date", - "Tue, 07 Apr 2020 15:15:21 GMT", + "Thu, 16 Jul 2020 18:21:32 GMT", "Connection", "close" ] @@ -84,16 +102,25 @@ { "scope": "https://westus.api.cognitive.microsoft.com:443", "method": "POST", - "path": "/luis/v2.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554?verbose=false&staging=false&spellCheck=false&log=true", - "body": "sample dialog", + "path": "/luis/prediction/v3.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554/slots/production/predict?verbose=true&log=true&show-all-intents=false", + "body": { + "query": "run sample dialog", + "options": { + "preferExternalEntities": true + } + }, "status": 200, "response": { - "query": "sample dialog", - "topScoringIntent": { - "intent": "Sample", - "score": 0.9705775 - }, - "entities": [] + "query": "run sample dialog", + "prediction": { + "topIntent": "Sample", + "intents": { + "Sample": { + "score": 0.9705775 + } + }, + "entities": {} + } }, "rawHeaders": [ "Cache-Control", @@ -101,15 +128,15 @@ "Pragma", "no-cache", "Content-Length", - "131", + "116", "Content-Type", "application/json; charset=utf-8", "Apim-Request-Id", - "8621a3e9-54df-41bc-8970-ae5da208d7e6", + "539dd476-9f3d-421c-ae44-70f9e0674b2b", "Request-Id", - "8621a3e9-54df-41bc-8970-ae5da208d7e6", + "539dd476-9f3d-421c-ae44-70f9e0674b2b", "CSP-Billing-Usage", - "CognitiveServices.LUIS.Transaction|1", + "CognitiveServices.LUIS.Transaction=1", "Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload", "X-Content-Type-Options", @@ -117,7 +144,7 @@ "X-Frame-Options", "SAMEORIGIN", "Date", - "Tue, 07 Apr 2020 15:15:22 GMT", + "Thu, 16 Jul 2020 18:21:33 GMT", "Connection", "close" ] @@ -125,16 +152,25 @@ { "scope": "https://westus.api.cognitive.microsoft.com:443", "method": "POST", - "path": "/luis/v2.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554?verbose=false&staging=false&spellCheck=false&log=true", - "body": "sample dialog", + "path": "/luis/prediction/v3.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554/slots/production/predict?verbose=true&log=true&show-all-intents=false", + "body": { + "query": "run sample dialog", + "options": { + "preferExternalEntities": true + } + }, "status": 200, "response": { - "query": "sample dialog", - "topScoringIntent": { - "intent": "Confirm", - "score": 0.12141446 - }, - "entities": [] + "query": "run sample dialog", + "prediction": { + "topIntent": "Confirm", + "intents": { + "Confirm": { + "score": 0.148891255 + } + }, + "entities": {} + } }, "rawHeaders": [ "Cache-Control", @@ -142,15 +178,15 @@ "Pragma", "no-cache", "Content-Length", - "133", + "120", "Content-Type", "application/json; charset=utf-8", "Apim-Request-Id", - "dda572b9-f94a-4168-a471-3f54f07fff7c", + "26a36063-fab8-4228-9e40-8a72978a038f", "Request-Id", - "dda572b9-f94a-4168-a471-3f54f07fff7c", + "26a36063-fab8-4228-9e40-8a72978a038f", "CSP-Billing-Usage", - "CognitiveServices.LUIS.Transaction|1", + "CognitiveServices.LUIS.Transaction=1", "Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload", "X-Content-Type-Options", @@ -158,7 +194,7 @@ "X-Frame-Options", "SAMEORIGIN", "Date", - "Tue, 07 Apr 2020 15:15:23 GMT", + "Thu, 16 Jul 2020 18:21:34 GMT", "Connection", "close" ] @@ -166,16 +202,25 @@ { "scope": "https://westus.api.cognitive.microsoft.com:443", "method": "POST", - "path": "/luis/v2.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554?verbose=false&staging=false&spellCheck=false&log=true", - "body": "cancel", + "path": "/luis/prediction/v3.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554/slots/production/predict?verbose=true&log=true&show-all-intents=false", + "body": { + "query": "cancel", + "options": { + "preferExternalEntities": true + } + }, "status": 200, "response": { "query": "cancel", - "topScoringIntent": { - "intent": "None", - "score": 0.873317 - }, - "entities": [] + "prediction": { + "topIntent": "None", + "intents": { + "None": { + "score": 0.873317 + } + }, + "entities": {} + } }, "rawHeaders": [ "Cache-Control", @@ -183,15 +228,15 @@ "Pragma", "no-cache", "Content-Length", - "121", + "104", "Content-Type", "application/json; charset=utf-8", "Apim-Request-Id", - "7f6ce299-a76d-4648-92c2-733ee9c1b5f6", + "1a93915c-061f-47c8-8b95-2d039a224427", "Request-Id", - "7f6ce299-a76d-4648-92c2-733ee9c1b5f6", + "1a93915c-061f-47c8-8b95-2d039a224427", "CSP-Billing-Usage", - "CognitiveServices.LUIS.Transaction|1", + "CognitiveServices.LUIS.Transaction=1", "Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload", "X-Content-Type-Options", @@ -199,7 +244,7 @@ "X-Frame-Options", "SAMEORIGIN", "Date", - "Tue, 07 Apr 2020 15:15:24 GMT", + "Thu, 16 Jul 2020 18:21:34 GMT", "Connection", "close" ] @@ -207,16 +252,25 @@ { "scope": "https://westus.api.cognitive.microsoft.com:443", "method": "POST", - "path": "/luis/v2.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554?verbose=false&staging=false&spellCheck=false&log=true", - "body": "cancel", + "path": "/luis/prediction/v3.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554/slots/production/predict?verbose=true&log=true&show-all-intents=false", + "body": { + "query": "cancel", + "options": { + "preferExternalEntities": true + } + }, "status": 200, "response": { "query": "cancel", - "topScoringIntent": { - "intent": "Cancel", - "score": 0.9978573 - }, - "entities": [] + "prediction": { + "topIntent": "Cancel", + "intents": { + "Cancel": { + "score": 0.9978573 + } + }, + "entities": {} + } }, "rawHeaders": [ "Cache-Control", @@ -224,15 +278,15 @@ "Pragma", "no-cache", "Content-Length", - "124", + "109", "Content-Type", "application/json; charset=utf-8", "Apim-Request-Id", - "9ebf28b2-785b-442e-bd5a-c26f9c5f88e9", + "e468b79a-3e1e-4b11-b16f-fae3e919163e", "Request-Id", - "9ebf28b2-785b-442e-bd5a-c26f9c5f88e9", + "e468b79a-3e1e-4b11-b16f-fae3e919163e", "CSP-Billing-Usage", - "CognitiveServices.LUIS.Transaction|1", + "CognitiveServices.LUIS.Transaction=1", "Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload", "X-Content-Type-Options", @@ -240,7 +294,7 @@ "X-Frame-Options", "SAMEORIGIN", "Date", - "Tue, 07 Apr 2020 15:15:24 GMT", + "Thu, 16 Jul 2020 18:21:36 GMT", "Connection", "close" ] diff --git a/templates/typescript/samples/sample-skill/test/mocks/nockFixtures/interruption_help_response.json b/templates/typescript/samples/sample-skill/test/mocks/nockFixtures/interruption_help_response.json index edb3beb316..63c695e8ab 100644 --- a/templates/typescript/samples/sample-skill/test/mocks/nockFixtures/interruption_help_response.json +++ b/templates/typescript/samples/sample-skill/test/mocks/nockFixtures/interruption_help_response.json @@ -1,47 +1,26 @@ [ - { - "scope": "https://dc.services.visualstudio.com:443", - "method": "GET", - "path": "/api/profiles/f7c2ee78-8679-4a3e-b384-0cd10c67e554/appId", - "body": "", - "status": 200, - "response": "6b757982-4de3-4003-b373-49821deabe2a", - "rawHeaders": [ - "Content-Type", - "text/plain", - "x-ms-session-id", - "0BEF36A2-4A13-4D0C-9C48-C387F85C03BD", - "Strict-Transport-Security", - "max-age=31536000", - "Access-Control-Allow-Headers", - "Origin, X-Requested-With, Content-Name, Content-Type, Accept, Sdk-Context", - "Access-Control-Allow-Origin", - "*", - "Access-Control-Max-Age", - "3600", - "X-Content-Type-Options", - "nosniff", - "Date", - "Tue, 07 Apr 2020 15:15:16 GMT", - "Connection", - "close", - "Content-Length", - "36" - ] - }, { "scope": "https://westus.api.cognitive.microsoft.com:443", "method": "POST", - "path": "/luis/v2.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554?verbose=false&staging=false&spellCheck=false&log=true", - "body": "sample dialog", + "path": "/luis/prediction/v3.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554/slots/production/predict?verbose=true&log=true&show-all-intents=false", + "body": { + "query": "run sample dialog", + "options": { + "preferExternalEntities": true + } + }, "status": 200, "response": { - "query": "sample dialog", - "topScoringIntent": { - "intent": "Sample", - "score": 0.9705775 - }, - "entities": [] + "query": "run sample dialog", + "prediction": { + "topIntent": "Sample", + "intents": { + "Sample": { + "score": 0.9750285 + } + }, + "entities": {} + } }, "rawHeaders": [ "Cache-Control", @@ -49,15 +28,15 @@ "Pragma", "no-cache", "Content-Length", - "131", + "120", "Content-Type", "application/json; charset=utf-8", "Apim-Request-Id", - "97aefb89-2819-4b04-a981-c880e2010f46", + "a3e0b6ac-5171-47f7-a1fd-ddb69f01f8a0", "Request-Id", - "97aefb89-2819-4b04-a981-c880e2010f46", + "a3e0b6ac-5171-47f7-a1fd-ddb69f01f8a0", "CSP-Billing-Usage", - "CognitiveServices.LUIS.Transaction|1", + "CognitiveServices.LUIS.Transaction=1", "Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload", "X-Content-Type-Options", @@ -65,7 +44,7 @@ "X-Frame-Options", "SAMEORIGIN", "Date", - "Tue, 07 Apr 2020 15:15:17 GMT", + "Thu, 16 Jul 2020 18:21:27 GMT", "Connection", "close" ] @@ -73,16 +52,25 @@ { "scope": "https://westus.api.cognitive.microsoft.com:443", "method": "POST", - "path": "/luis/v2.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554?verbose=false&staging=false&spellCheck=false&log=true", - "body": "sample dialog", + "path": "/luis/prediction/v3.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554/slots/production/predict?verbose=true&log=true&show-all-intents=false", + "body": { + "query": "run sample dialog", + "options": { + "preferExternalEntities": true + } + }, "status": 200, "response": { - "query": "sample dialog", - "topScoringIntent": { - "intent": "Confirm", - "score": 0.12141446 - }, - "entities": [] + "query": "run sample dialog", + "prediction": { + "topIntent": "Confirm", + "intents": { + "Confirm": { + "score": 0.061984323 + } + }, + "entities": {} + } }, "rawHeaders": [ "Cache-Control", @@ -90,15 +78,15 @@ "Pragma", "no-cache", "Content-Length", - "133", + "124", "Content-Type", "application/json; charset=utf-8", "Apim-Request-Id", - "6a76c7a8-259a-4c3c-80e7-33e16b5a2d07", + "8796a5af-9627-4304-b3fb-55bdbcb72587", "Request-Id", - "6a76c7a8-259a-4c3c-80e7-33e16b5a2d07", + "8796a5af-9627-4304-b3fb-55bdbcb72587", "CSP-Billing-Usage", - "CognitiveServices.LUIS.Transaction|1", + "CognitiveServices.LUIS.Transaction=1", "Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload", "X-Content-Type-Options", @@ -106,7 +94,7 @@ "X-Frame-Options", "SAMEORIGIN", "Date", - "Tue, 07 Apr 2020 15:15:17 GMT", + "Thu, 16 Jul 2020 18:21:28 GMT", "Connection", "close" ] @@ -114,16 +102,25 @@ { "scope": "https://westus.api.cognitive.microsoft.com:443", "method": "POST", - "path": "/luis/v2.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554?verbose=false&staging=false&spellCheck=false&log=true", - "body": "sample dialog", + "path": "/luis/prediction/v3.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554/slots/production/predict?verbose=true&log=true&show-all-intents=false", + "body": { + "query": "run sample dialog", + "options": { + "preferExternalEntities": true + } + }, "status": 200, "response": { - "query": "sample dialog", - "topScoringIntent": { - "intent": "Sample", - "score": 0.9705775 - }, - "entities": [] + "query": "run sample dialog", + "prediction": { + "topIntent": "Sample", + "intents": { + "Sample": { + "score": 0.9750285 + } + }, + "entities": {} + } }, "rawHeaders": [ "Cache-Control", @@ -131,15 +128,15 @@ "Pragma", "no-cache", "Content-Length", - "131", + "120", "Content-Type", "application/json; charset=utf-8", "Apim-Request-Id", - "05dccbd7-55f9-4860-a88c-95d60e30b320", + "25ff97a1-5b45-4f5c-a99b-23c8bd3c3435", "Request-Id", - "05dccbd7-55f9-4860-a88c-95d60e30b320", + "25ff97a1-5b45-4f5c-a99b-23c8bd3c3435", "CSP-Billing-Usage", - "CognitiveServices.LUIS.Transaction|1", + "CognitiveServices.LUIS.Transaction=1", "Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload", "X-Content-Type-Options", @@ -147,7 +144,7 @@ "X-Frame-Options", "SAMEORIGIN", "Date", - "Tue, 07 Apr 2020 15:15:18 GMT", + "Thu, 16 Jul 2020 18:21:29 GMT", "Connection", "close" ] @@ -155,16 +152,25 @@ { "scope": "https://westus.api.cognitive.microsoft.com:443", "method": "POST", - "path": "/luis/v2.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554?verbose=false&staging=false&spellCheck=false&log=true", - "body": "sample dialog", + "path": "/luis/prediction/v3.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554/slots/production/predict?verbose=true&log=true&show-all-intents=false", + "body": { + "query": "run sample dialog", + "options": { + "preferExternalEntities": true + } + }, "status": 200, "response": { - "query": "sample dialog", - "topScoringIntent": { - "intent": "Confirm", - "score": 0.12141446 - }, - "entities": [] + "query": "run sample dialog", + "prediction": { + "topIntent": "Confirm", + "intents": { + "Confirm": { + "score": 0.061984323 + } + }, + "entities": {} + } }, "rawHeaders": [ "Cache-Control", @@ -172,15 +178,15 @@ "Pragma", "no-cache", "Content-Length", - "133", + "124", "Content-Type", "application/json; charset=utf-8", "Apim-Request-Id", - "f110c39d-efc5-4447-9f42-70941fcc885e", + "099f4182-7bfb-43d1-9f50-002c87541729", "Request-Id", - "f110c39d-efc5-4447-9f42-70941fcc885e", + "099f4182-7bfb-43d1-9f50-002c87541729", "CSP-Billing-Usage", - "CognitiveServices.LUIS.Transaction|1", + "CognitiveServices.LUIS.Transaction=1", "Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload", "X-Content-Type-Options", @@ -188,7 +194,7 @@ "X-Frame-Options", "SAMEORIGIN", "Date", - "Tue, 07 Apr 2020 15:15:18 GMT", + "Thu, 16 Jul 2020 18:21:30 GMT", "Connection", "close" ] @@ -196,16 +202,25 @@ { "scope": "https://westus.api.cognitive.microsoft.com:443", "method": "POST", - "path": "/luis/v2.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554?verbose=false&staging=false&spellCheck=false&log=true", - "body": "help", + "path": "/luis/prediction/v3.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554/slots/production/predict?verbose=true&log=true&show-all-intents=false", + "body": { + "query": "help", + "options": { + "preferExternalEntities": true + } + }, "status": 200, "response": { "query": "help", - "topScoringIntent": { - "intent": "None", - "score": 0.873317 - }, - "entities": [] + "prediction": { + "topIntent": "None", + "intents": { + "None": { + "score": 0.873317 + } + }, + "entities": {} + } }, "rawHeaders": [ "Cache-Control", @@ -213,15 +228,15 @@ "Pragma", "no-cache", "Content-Length", - "119", + "102", "Content-Type", "application/json; charset=utf-8", "Apim-Request-Id", - "c24f8385-f433-472f-897c-daa568b6e49b", + "b4b7e80b-92ba-49ce-afac-5b36a7af61d0", "Request-Id", - "c24f8385-f433-472f-897c-daa568b6e49b", + "b4b7e80b-92ba-49ce-afac-5b36a7af61d0", "CSP-Billing-Usage", - "CognitiveServices.LUIS.Transaction|1", + "CognitiveServices.LUIS.Transaction=1", "Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload", "X-Content-Type-Options", @@ -229,7 +244,7 @@ "X-Frame-Options", "SAMEORIGIN", "Date", - "Tue, 07 Apr 2020 15:15:20 GMT", + "Thu, 16 Jul 2020 18:21:30 GMT", "Connection", "close" ] @@ -237,16 +252,25 @@ { "scope": "https://westus.api.cognitive.microsoft.com:443", "method": "POST", - "path": "/luis/v2.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554?verbose=false&staging=false&spellCheck=false&log=true", - "body": "help", + "path": "/luis/prediction/v3.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554/slots/production/predict?verbose=true&log=true&show-all-intents=false", + "body": { + "query": "help", + "options": { + "preferExternalEntities": true + } + }, "status": 200, "response": { "query": "help", - "topScoringIntent": { - "intent": "Help", - "score": 0.9882712 - }, - "entities": [] + "prediction": { + "topIntent": "Help", + "intents": { + "Help": { + "score": 0.9895731 + } + }, + "entities": {} + } }, "rawHeaders": [ "Cache-Control", @@ -254,15 +278,15 @@ "Pragma", "no-cache", "Content-Length", - "120", + "103", "Content-Type", "application/json; charset=utf-8", "Apim-Request-Id", - "8ffdfce3-b4d1-41b0-8ea6-8defc97e25b2", + "7f86c6d4-1d48-4bbd-83c6-769ccfd83a1b", "Request-Id", - "8ffdfce3-b4d1-41b0-8ea6-8defc97e25b2", + "7f86c6d4-1d48-4bbd-83c6-769ccfd83a1b", "CSP-Billing-Usage", - "CognitiveServices.LUIS.Transaction|1", + "CognitiveServices.LUIS.Transaction=1", "Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload", "X-Content-Type-Options", @@ -270,7 +294,7 @@ "X-Frame-Options", "SAMEORIGIN", "Date", - "Tue, 07 Apr 2020 15:15:20 GMT", + "Thu, 16 Jul 2020 18:21:31 GMT", "Connection", "close" ] diff --git a/templates/typescript/samples/sample-skill/test/mocks/nockFixtures/mainDialog_help_response.json b/templates/typescript/samples/sample-skill/test/mocks/nockFixtures/mainDialog_help_response.json index 803fb31a7e..383e37d2bd 100644 --- a/templates/typescript/samples/sample-skill/test/mocks/nockFixtures/mainDialog_help_response.json +++ b/templates/typescript/samples/sample-skill/test/mocks/nockFixtures/mainDialog_help_response.json @@ -2,16 +2,25 @@ { "scope": "https://westus.api.cognitive.microsoft.com:443", "method": "POST", - "path": "/luis/v2.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554?verbose=false&staging=false&spellCheck=false&log=true", - "body": "help", + "path": "/luis/prediction/v3.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554/slots/production/predict?verbose=true&log=true&show-all-intents=false", + "body": { + "query": "help", + "options": { + "preferExternalEntities": true + } + }, "status": 200, "response": { "query": "help", - "topScoringIntent": { - "intent": "None", - "score": 0.873317 - }, - "entities": [] + "prediction": { + "topIntent": "None", + "intents": { + "None": { + "score": 0.873317 + } + }, + "entities": {} + } }, "rawHeaders": [ "Cache-Control", @@ -19,15 +28,15 @@ "Pragma", "no-cache", "Content-Length", - "119", + "102", "Content-Type", "application/json; charset=utf-8", "Apim-Request-Id", - "c65270f7-f705-4921-a3c2-876984f7eeaa", + "767f65bd-23ba-4fc4-9564-66d610c17a81", "Request-Id", - "c65270f7-f705-4921-a3c2-876984f7eeaa", + "767f65bd-23ba-4fc4-9564-66d610c17a81", "CSP-Billing-Usage", - "CognitiveServices.LUIS.Transaction|1", + "CognitiveServices.LUIS.Transaction=1", "Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload", "X-Content-Type-Options", @@ -35,7 +44,7 @@ "X-Frame-Options", "SAMEORIGIN", "Date", - "Tue, 07 Apr 2020 15:15:26 GMT", + "Thu, 16 Jul 2020 18:23:43 GMT", "Connection", "close" ] @@ -43,16 +52,25 @@ { "scope": "https://westus.api.cognitive.microsoft.com:443", "method": "POST", - "path": "/luis/v2.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554?verbose=false&staging=false&spellCheck=false&log=true", - "body": "help", + "path": "/luis/prediction/v3.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554/slots/production/predict?verbose=true&log=true&show-all-intents=false", + "body": { + "query": "help", + "options": { + "preferExternalEntities": true + } + }, "status": 200, "response": { "query": "help", - "topScoringIntent": { - "intent": "Help", - "score": 0.9882712 - }, - "entities": [] + "prediction": { + "topIntent": "Help", + "intents": { + "Help": { + "score": 0.9895731 + } + }, + "entities": {} + } }, "rawHeaders": [ "Cache-Control", @@ -60,15 +78,15 @@ "Pragma", "no-cache", "Content-Length", - "120", + "103", "Content-Type", "application/json; charset=utf-8", "Apim-Request-Id", - "9faca270-9610-4c1c-9646-fa9010760c89", + "c8558b3d-ce58-4ac1-9b4e-c8bd74658d03", "Request-Id", - "9faca270-9610-4c1c-9646-fa9010760c89", + "c8558b3d-ce58-4ac1-9b4e-c8bd74658d03", "CSP-Billing-Usage", - "CognitiveServices.LUIS.Transaction|1", + "CognitiveServices.LUIS.Transaction=1", "Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload", "X-Content-Type-Options", @@ -76,7 +94,7 @@ "X-Frame-Options", "SAMEORIGIN", "Date", - "Tue, 07 Apr 2020 15:15:26 GMT", + "Thu, 16 Jul 2020 18:23:44 GMT", "Connection", "close" ] diff --git a/templates/typescript/samples/sample-skill/test/mocks/nockFixtures/mainDialog_unhandled_response.json b/templates/typescript/samples/sample-skill/test/mocks/nockFixtures/mainDialog_unhandled_response.json index 660a3804f3..9803541ba7 100644 --- a/templates/typescript/samples/sample-skill/test/mocks/nockFixtures/mainDialog_unhandled_response.json +++ b/templates/typescript/samples/sample-skill/test/mocks/nockFixtures/mainDialog_unhandled_response.json @@ -2,16 +2,25 @@ { "scope": "https://westus.api.cognitive.microsoft.com:443", "method": "POST", - "path": "/luis/v2.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554?verbose=false&staging=false&spellCheck=false&log=true", - "body": "sample dialog", + "path": "/luis/prediction/v3.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554/slots/production/predict?verbose=true&log=true&show-all-intents=false", + "body": { + "query": "sample dialog", + "options": { + "preferExternalEntities": true + } + }, "status": 200, "response": { "query": "sample dialog", - "topScoringIntent": { - "intent": "Sample", - "score": 0.9705775 - }, - "entities": [] + "prediction": { + "topIntent": "Sample", + "intents": { + "Sample": { + "score": 0.9705775 + } + }, + "entities": {} + } }, "rawHeaders": [ "Cache-Control", @@ -19,15 +28,15 @@ "Pragma", "no-cache", "Content-Length", - "131", + "116", "Content-Type", "application/json; charset=utf-8", "Apim-Request-Id", - "60b1ca77-38b9-420e-b72f-cfa30a10194a", + "5f5dd332-b971-41fe-9cd3-5ea9a43b0a3f", "Request-Id", - "60b1ca77-38b9-420e-b72f-cfa30a10194a", + "5f5dd332-b971-41fe-9cd3-5ea9a43b0a3f", "CSP-Billing-Usage", - "CognitiveServices.LUIS.Transaction|1", + "CognitiveServices.LUIS.Transaction=1", "Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload", "X-Content-Type-Options", @@ -35,7 +44,7 @@ "X-Frame-Options", "SAMEORIGIN", "Date", - "Tue, 07 Apr 2020 15:15:27 GMT", + "Thu, 16 Jul 2020 18:23:45 GMT", "Connection", "close" ] @@ -43,16 +52,25 @@ { "scope": "https://westus.api.cognitive.microsoft.com:443", "method": "POST", - "path": "/luis/v2.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554?verbose=false&staging=false&spellCheck=false&log=true", - "body": "sample dialog", + "path": "/luis/prediction/v3.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554/slots/production/predict?verbose=true&log=true&show-all-intents=false", + "body": { + "query": "sample dialog", + "options": { + "preferExternalEntities": true + } + }, "status": 200, "response": { "query": "sample dialog", - "topScoringIntent": { - "intent": "Confirm", - "score": 0.12141446 - }, - "entities": [] + "prediction": { + "topIntent": "Confirm", + "intents": { + "Confirm": { + "score": 0.148891255 + } + }, + "entities": {} + } }, "rawHeaders": [ "Cache-Control", @@ -60,15 +78,15 @@ "Pragma", "no-cache", "Content-Length", - "133", + "120", "Content-Type", "application/json; charset=utf-8", "Apim-Request-Id", - "797f1506-ab96-49cf-8e59-126ca1539b71", + "e5d44eb9-a07a-44b2-87a9-f9d82239dc13", "Request-Id", - "797f1506-ab96-49cf-8e59-126ca1539b71", + "e5d44eb9-a07a-44b2-87a9-f9d82239dc13", "CSP-Billing-Usage", - "CognitiveServices.LUIS.Transaction|1", + "CognitiveServices.LUIS.Transaction=1", "Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload", "X-Content-Type-Options", @@ -76,7 +94,7 @@ "X-Frame-Options", "SAMEORIGIN", "Date", - "Tue, 07 Apr 2020 15:15:27 GMT", + "Thu, 16 Jul 2020 18:23:45 GMT", "Connection", "close" ] @@ -84,16 +102,25 @@ { "scope": "https://westus.api.cognitive.microsoft.com:443", "method": "POST", - "path": "/luis/v2.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554?verbose=false&staging=false&spellCheck=false&log=true", - "body": "Unhandled message", + "path": "/luis/prediction/v3.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554/slots/production/predict?verbose=true&log=true&show-all-intents=false", + "body": { + "query": "Unhandled message", + "options": { + "preferExternalEntities": true + } + }, "status": 200, "response": { "query": "Unhandled message", - "topScoringIntent": { - "intent": "None", - "score": 0.833009 - }, - "entities": [] + "prediction": { + "topIntent": "None", + "intents": { + "None": { + "score": 0.833009 + } + }, + "entities": {} + } }, "rawHeaders": [ "Cache-Control", @@ -101,15 +128,15 @@ "Pragma", "no-cache", "Content-Length", - "132", + "115", "Content-Type", "application/json; charset=utf-8", "Apim-Request-Id", - "3d3e9d15-5edc-48b3-96cf-5d16ff349c73", + "8773612c-2273-4762-9b39-0c6dca4d2397", "Request-Id", - "3d3e9d15-5edc-48b3-96cf-5d16ff349c73", + "8773612c-2273-4762-9b39-0c6dca4d2397", "CSP-Billing-Usage", - "CognitiveServices.LUIS.Transaction|1", + "CognitiveServices.LUIS.Transaction=1", "Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload", "X-Content-Type-Options", @@ -117,7 +144,7 @@ "X-Frame-Options", "SAMEORIGIN", "Date", - "Tue, 07 Apr 2020 15:15:28 GMT", + "Thu, 16 Jul 2020 18:23:46 GMT", "Connection", "close" ] @@ -125,16 +152,25 @@ { "scope": "https://westus.api.cognitive.microsoft.com:443", "method": "POST", - "path": "/luis/v2.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554?verbose=false&staging=false&spellCheck=false&log=true", - "body": "Unhandled message", + "path": "/luis/prediction/v3.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554/slots/production/predict?verbose=true&log=true&show-all-intents=false", + "body": { + "query": "Unhandled message", + "options": { + "preferExternalEntities": true + } + }, "status": 200, "response": { "query": "Unhandled message", - "topScoringIntent": { - "intent": "Confirm", - "score": 0.12141446 - }, - "entities": [] + "prediction": { + "topIntent": "Confirm", + "intents": { + "Confirm": { + "score": 0.148891255 + } + }, + "entities": {} + } }, "rawHeaders": [ "Cache-Control", @@ -142,15 +178,15 @@ "Pragma", "no-cache", "Content-Length", - "137", + "124", "Content-Type", "application/json; charset=utf-8", "Apim-Request-Id", - "bac86884-fc71-44b0-9a02-0545ed9afb64", + "bc3a75d7-1823-480b-b4a2-3acf12f4f74d", "Request-Id", - "bac86884-fc71-44b0-9a02-0545ed9afb64", + "bc3a75d7-1823-480b-b4a2-3acf12f4f74d", "CSP-Billing-Usage", - "CognitiveServices.LUIS.Transaction|1", + "CognitiveServices.LUIS.Transaction=1", "Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload", "X-Content-Type-Options", @@ -158,7 +194,7 @@ "X-Frame-Options", "SAMEORIGIN", "Date", - "Tue, 07 Apr 2020 15:15:29 GMT", + "Thu, 16 Jul 2020 18:23:46 GMT", "Connection", "close" ] diff --git a/templates/typescript/samples/sample-skill/test/mocks/nockFixtures/sampleDialog_response.json b/templates/typescript/samples/sample-skill/test/mocks/nockFixtures/sampleDialog_response.json index 7bc4485f0c..5df5b8c966 100644 --- a/templates/typescript/samples/sample-skill/test/mocks/nockFixtures/sampleDialog_response.json +++ b/templates/typescript/samples/sample-skill/test/mocks/nockFixtures/sampleDialog_response.json @@ -2,16 +2,25 @@ { "scope": "https://westus.api.cognitive.microsoft.com:443", "method": "POST", - "path": "/luis/v2.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554?verbose=false&staging=false&spellCheck=false&log=true", - "body": "sample dialog", + "path": "/luis/prediction/v3.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554/slots/production/predict?verbose=true&log=true&show-all-intents=false", + "body": { + "query": "sample dialog", + "options": { + "preferExternalEntities": true + } + }, "status": 200, "response": { "query": "sample dialog", - "topScoringIntent": { - "intent": "Sample", - "score": 0.9705775 - }, - "entities": [] + "prediction": { + "topIntent": "Sample", + "intents": { + "Sample": { + "score": 0.9705775 + } + }, + "entities": {} + } }, "rawHeaders": [ "Cache-Control", @@ -19,15 +28,15 @@ "Pragma", "no-cache", "Content-Length", - "131", + "116", "Content-Type", "application/json; charset=utf-8", "Apim-Request-Id", - "aa0d5d59-a4a7-4278-a2e2-dfe73fdb9273", + "f2c7cf8f-7c7b-4e78-8cb2-9bf5706a7eba", "Request-Id", - "aa0d5d59-a4a7-4278-a2e2-dfe73fdb9273", + "f2c7cf8f-7c7b-4e78-8cb2-9bf5706a7eba", "CSP-Billing-Usage", - "CognitiveServices.LUIS.Transaction|1", + "CognitiveServices.LUIS.Transaction=1", "Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload", "X-Content-Type-Options", @@ -35,7 +44,7 @@ "X-Frame-Options", "SAMEORIGIN", "Date", - "Tue, 07 Apr 2020 15:15:30 GMT", + "Thu, 16 Jul 2020 18:23:48 GMT", "Connection", "close" ] @@ -43,16 +52,25 @@ { "scope": "https://westus.api.cognitive.microsoft.com:443", "method": "POST", - "path": "/luis/v2.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554?verbose=false&staging=false&spellCheck=false&log=true", - "body": "sample dialog", + "path": "/luis/prediction/v3.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554/slots/production/predict?verbose=true&log=true&show-all-intents=false", + "body": { + "query": "sample dialog", + "options": { + "preferExternalEntities": true + } + }, "status": 200, "response": { "query": "sample dialog", - "topScoringIntent": { - "intent": "Confirm", - "score": 0.12141446 - }, - "entities": [] + "prediction": { + "topIntent": "Confirm", + "intents": { + "Confirm": { + "score": 0.148891255 + } + }, + "entities": {} + } }, "rawHeaders": [ "Cache-Control", @@ -60,15 +78,15 @@ "Pragma", "no-cache", "Content-Length", - "133", + "120", "Content-Type", "application/json; charset=utf-8", "Apim-Request-Id", - "489fec91-4487-49ea-adda-261431361f8c", + "4122a658-7a51-4b8f-87df-32acb24373c1", "Request-Id", - "489fec91-4487-49ea-adda-261431361f8c", + "4122a658-7a51-4b8f-87df-32acb24373c1", "CSP-Billing-Usage", - "CognitiveServices.LUIS.Transaction|1", + "CognitiveServices.LUIS.Transaction=1", "Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload", "X-Content-Type-Options", @@ -76,58 +94,33 @@ "X-Frame-Options", "SAMEORIGIN", "Date", - "Tue, 07 Apr 2020 15:15:31 GMT", + "Thu, 16 Jul 2020 18:23:48 GMT", "Connection", "close" ] }, - { - "scope": "https://dc.services.visualstudio.com:443", - "method": "POST", - "path": "/v2/track", - "body": "1f8b080000000000000aed9d5d8fdd3819c7eff914e608696fc6911d27b1d31b346d818eb66fb4b354422b212776e684c949ce2639333bad2aed0217850b04574815880509092484b842bcec6a25f6abb465eff62b60e74cdbe9ccb4fb329d3db1cf23556d272f3e39c96ffe7efecf63c7f7267bba9d5ca01b934ecee695be257b6d7e246463d2cb9d6e72e1de4496819ccfab32977dd9d4c170fc84062420930dbb53e9bd32d741a9cce6e596bc6a162a689b4a6fd55d2febdc3439b97671737b7bf37b57b7aedfc057376f6edfb8f9c2e94df703dd76e603cca177ca5a35fbdd8fae6f236a3e26a08225ec78d3f6389d1d6b63b3cda765aff37ed1da03de4da26307dcac645f34edccecdc2f6b162e779775afdb5a5641a7769f5f46dd287d8106a1f9a2f737264af6d2de8e4c767afb606e9bffce9eaefbcb76fbc6b0f9f2e121c32d0a3726f3b699ebb62ff5701f8bb6996dd99bb4e8ccfe8d49ded4e6c06eb8abd7e54c2f6f5fd5e4b23afc7fabf3725e9acf184ecb9afee8b6c3532e0e5b6ddb871bde32ad53b3a9d7eff6e6c7e56345aa9455b363bf47fdecbc6bbaebe48ebea5735dee6935b96ff6966fea03b357c559182a95632299c0912c429c164ce13c298aacd011a7ca3e90c3b6ae9579db744dd1079bcf41318fbedc99f65df0b42ddb946dc93674b49d60b88df68acba1b5908404930813be4de30bf64f121092fe7072ff1bf780d6af8bd6233771a02fd692c689c8704c0a8d232515964c094c15177991ca4c09dbb0bdb6da72777b7840cfb6dcce9be13b9220e524e63c3e84f6e82f8439ac5c7efce4dedb936f95874fe36d7339f7ef9bfdef2c74d72fbfeccba8beba28bb5bba5b54fd7869e6411cc640f3d74a73abe7d5c166de977b657f3030474ee8eb9797e51714f73469bdadeb11cbaa055100882b95d5229419cb688e6359c438a2b9c0599a8498132ed23ccd898ec95159bdd4d44569aefca4aed29046348a92f51556118411039e415801c4f503f1f2a058036fd764592f7f34673ebd47c39ed03c59c1788ccda354b84808c52c27028761aab82211cfe851deee98c7d516b2aa6ef7b205e103dece85b78dc9ed5ecf0f252f6b16b542e61bb48ddd7a3a8c76fb98598c8045df3ae167f9a43b53d9a35cd6680b4d75354707cd02ed97fd14f58d9207df76b4b7e6402ce4429dc8855a5ac1b4432ed417cb9e32c885ae3a5a08c1b25b102108805ca82fc29a0609879400082b80b886209e6b6eaa6d16bd763337655984dcd4ca585cdaa0d369644596d298709cc729c5112b52ac6466030059c84c878a51e960661e88739bb853f4cf7cd86cde7fb76987ada08140e41802c317f3f36567f3f22db24cb99892b790425a681d52f2b686e468261e205d7dcae8cb66e2af37f5697978c119a3fc6cd9a263243b90240a49c0622078d5b140b4f649a201c40440742afb7ec5eadd29254d21424ec3b5d35243205432414bc7012268298008200288e701a257992680740590c2e0cf33d00a3ec9b194130cfe7c39cd3ca640b36f53455c0c02780c3551b7d24f30f8f3e53c8741c408f00cc20a20ae1f885f68f0a7a43a614651715ec419ce1256e050b014e73a1142e42149b8706fb81df0e6346f5e4d841f580477e35d27ecef4478207605c4422ef42cb486402be442bdb0eccc100229a855470b305f73001126c2432ed41f613506137806610510d70fc473cd4db93b111e585c2d8baf9a961c6719c9949458e599c4218b521c25598ab34cf244a754169a38989907e2dc26cebb89f040a49f81a15fc3932da4b0f2d13aa4e4737bfb2b4773f180e9ea9346239a0a7f82651712455110c38b71561e0fc0bcb901449849ec58067ea978a71436532e62ced6504fe320e4e0af404f47012204a7de81f8cc39dd7873036dbd31434b95acca7a67e9f95b3d486880aeea1ecd34daad9b7d5416686b18b5a71a24eb837e6a0fd755a791b953f6bc000807c2cf945cfd9c44e96bcaf71f461cc02430f9b9e5ce57942e5fd3bc10a01168fc6a6fa1e739896243988e0c755122182e6446b0715f82e45cea84440e963b81379779f36b2212b0e8b7ffb9626ccd8bf3905cac741a4a054cdd1c75a55369acf4098ce929844e4ea974ba59d98c034600cb558be739cee22cab6ab799cd748dee2ed0d6b4d53394e97ad1dfd5add2455997e6baccce6ed71cf84d27759511982637c248948592d14845380a4566fc7691e3dc06a6948554709a2421899d743ec09bbbbcf9e67c8045bf3b6f8d76655da3329f9abebb36fdb4b14085aedd34408cc04299a33640bac3e6bcb53340140c90bf1afadf3f5c343bcde595b6228efac5d2ea2073395d63be6879572ae9a8f1a1f0369b1106a291ca744a33f3b87262fe8a238ea9e40916226152676144a9a3c60778739637ef8c0fb0e873a7fdf115798064b5d3a077161acd175a493495b96ed1bc69515f3a6a8028b8f5511ba0a2c545bb7e0628042cfdd5d243fb6364f4930fd05ed3bde07fac01ea3ef98bee1c7540216494461891a6899411170a0ba5094ed238b1ff5338ca148d751417599abbe98080376779f3ce0185309bd7df5efbfb83ed293bfc63f3af9dedb3d72c3a475d0f803a6ed753f6b8ec4f90ecbdeb613068d85ffdbcb8343d7d836a5d55b6ee234f147eee9aab75d4f74450b21c611c5a2491cc9294e32ca102172a6598311e6211f3824891f38c48377d0ff0e62c6fdef91e60d1e37efb5253a3bce9a4313d5dd720592eac3696a8d9d971b5e803bc8edbfee81a2fd670d45b04f6c75f19bda3abbc996964fccff0ae987cd1f5cdcce9593e31c8e80843d02ca58a6ace719e45144b3b02296249665849084f432653ceddb43cc09bb3bc79677980459ffb6aef165ab5c4c2f0cc519b9ebb539cd7eb677a6258facf5f217df2d73f7efaf12f9ffcee4f8f1ffcfdc94ffefcbf873f7bfcb7878f1ffce3c92fdefbf4a71f7df6e1fb8e4a29bc65788481a8093a392724c55cd2145321139c8828c305d3e6892b99ea823a6a7c2031e42a6ffe191f60d1e3fefab73f7ff49ff71efdebc19307bf361df4a37ffefbd1471f3c7effe172a3edbe7ff59bcf3efcbda3bd36903b6a03b4a6551f0e03d8fd15540fab3eb064d5188351ae79a49989430bc9188e8b24c33a8f429c5016a62ac984a0a19be60778739637efcc0fb0e8735ffdbceaa39aa78bf3385aec0150c7ed754e40fcd596f0b5d549779d8f80971cc002be870b4e1e23d985e5269380325835d5bb78c0bdfede829800884e2ddf7bc5eadd298bf70a11f2c139ad9b960a020341404b4701228cee001001c435047135267ef958915ae659dd74f3865678a78c636e7eb988f46941282731e7f1d982d09751ed4234ca839841551e8280518008cede2d677fa9a98bd25cf9495da5218d681425eb2bac220819d87c105600710d41fc42e34a08e582c7698475628794c4269ce5566d13a999a6992409d50e8e6302de5ce6cdaf714c9645c82c79d7093fcb275d69f68f4d5e7771101350ba2ef9cfb7eaa9ac55a5159a2dc17434070ac4aedeacbfae114d8c11929ecda7bf0a6b17bc7a1a10581c6be56142085edd8208b5254882fa25ae3c847c00882b80b886209e6b62aa6d16bd763331052c7a298a478cbef992fda2364fb33a405b3649f5467ffc0d8b76125e6b894275b31fa0cd79637e39ccc5068e8a2b64043c12d7a23497efaeb8028b236431e4051552e45848a6b1b4c0e42461388f0a2685e2454163072b9e963778e192abbcf955f10416fd0e2c37ab0aa9a6d601baaa7b34d368d7c48ea82c9631a67d9b83ac0ffa6959ef205d75dad55012105e8772a80fd3410cad310ca077ab140ad3415e4233234104dabbf2f001462d5b10995d77e6ff951f7111432d0100", - "status": 200, - "response": { - "itemsReceived": 115, - "itemsAccepted": 115, - "errors": [] - }, - "rawHeaders": [ - "Content-Type", - "application/json; charset=utf-8", - "x-ms-session-id", - "04B4ED9D-1F06-485E-A968-2C76CD164563", - "Strict-Transport-Security", - "max-age=31536000", - "Access-Control-Allow-Headers", - "Origin, X-Requested-With, Content-Name, Content-Type, Accept, Sdk-Context", - "Access-Control-Allow-Origin", - "*", - "Access-Control-Max-Age", - "3600", - "X-Content-Type-Options", - "nosniff", - "Date", - "Tue, 07 Apr 2020 15:15:31 GMT", - "Connection", - "close", - "Content-Length", - "53" - ] - }, { "scope": "https://westus.api.cognitive.microsoft.com:443", "method": "POST", - "path": "/luis/v2.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554?verbose=false&staging=false&spellCheck=false&log=true", - "body": "sample dialog", + "path": "/luis/prediction/v3.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554/slots/production/predict?verbose=true&log=true&show-all-intents=false", + "body": { + "query": "sample dialog", + "options": { + "preferExternalEntities": true + } + }, "status": 200, "response": { "query": "sample dialog", - "topScoringIntent": { - "intent": "Sample", - "score": 0.9705775 - }, - "entities": [] + "prediction": { + "topIntent": "Sample", + "intents": { + "Sample": { + "score": 0.9705775 + } + }, + "entities": {} + } }, "rawHeaders": [ "Cache-Control", @@ -135,15 +128,15 @@ "Pragma", "no-cache", "Content-Length", - "131", + "116", "Content-Type", "application/json; charset=utf-8", "Apim-Request-Id", - "c820ee0a-3ccf-4a48-ba0e-3f8e5cc0e6e8", + "ff620f7b-20e4-4a82-912b-cfbe4a26e1e0", "Request-Id", - "c820ee0a-3ccf-4a48-ba0e-3f8e5cc0e6e8", + "ff620f7b-20e4-4a82-912b-cfbe4a26e1e0", "CSP-Billing-Usage", - "CognitiveServices.LUIS.Transaction|1", + "CognitiveServices.LUIS.Transaction=1", "Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload", "X-Content-Type-Options", @@ -151,7 +144,7 @@ "X-Frame-Options", "SAMEORIGIN", "Date", - "Tue, 07 Apr 2020 15:15:31 GMT", + "Thu, 16 Jul 2020 18:23:49 GMT", "Connection", "close" ] @@ -159,16 +152,25 @@ { "scope": "https://westus.api.cognitive.microsoft.com:443", "method": "POST", - "path": "/luis/v2.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554?verbose=false&staging=false&spellCheck=false&log=true", - "body": "sample dialog", + "path": "/luis/prediction/v3.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554/slots/production/predict?verbose=true&log=true&show-all-intents=false", + "body": { + "query": "sample dialog", + "options": { + "preferExternalEntities": true + } + }, "status": 200, "response": { "query": "sample dialog", - "topScoringIntent": { - "intent": "Confirm", - "score": 0.12141446 - }, - "entities": [] + "prediction": { + "topIntent": "Confirm", + "intents": { + "Confirm": { + "score": 0.148891255 + } + }, + "entities": {} + } }, "rawHeaders": [ "Cache-Control", @@ -176,15 +178,15 @@ "Pragma", "no-cache", "Content-Length", - "133", + "120", "Content-Type", "application/json; charset=utf-8", "Apim-Request-Id", - "4ddfd754-27d0-427a-a899-95a747de255c", + "672eead0-5591-41fc-a57c-3dcfebaaca83", "Request-Id", - "4ddfd754-27d0-427a-a899-95a747de255c", + "672eead0-5591-41fc-a57c-3dcfebaaca83", "CSP-Billing-Usage", - "CognitiveServices.LUIS.Transaction|1", + "CognitiveServices.LUIS.Transaction=1", "Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload", "X-Content-Type-Options", @@ -192,7 +194,7 @@ "X-Frame-Options", "SAMEORIGIN", "Date", - "Tue, 07 Apr 2020 15:15:32 GMT", + "Thu, 16 Jul 2020 18:23:50 GMT", "Connection", "close" ] @@ -200,16 +202,25 @@ { "scope": "https://westus.api.cognitive.microsoft.com:443", "method": "POST", - "path": "/luis/v2.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554?verbose=false&staging=false&spellCheck=false&log=true", - "body": "custom", + "path": "/luis/prediction/v3.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554/slots/production/predict?verbose=true&log=true&show-all-intents=false", + "body": { + "query": "custom", + "options": { + "preferExternalEntities": true + } + }, "status": 200, "response": { "query": "custom", - "topScoringIntent": { - "intent": "None", - "score": 0.873317 - }, - "entities": [] + "prediction": { + "topIntent": "None", + "intents": { + "None": { + "score": 0.873317 + } + }, + "entities": {} + } }, "rawHeaders": [ "Cache-Control", @@ -217,15 +228,15 @@ "Pragma", "no-cache", "Content-Length", - "121", + "104", "Content-Type", "application/json; charset=utf-8", "Apim-Request-Id", - "2f4a7d98-351f-499d-9ca8-14a5296f4946", + "ece39a3b-7c43-4cfc-af29-647c8e22b677", "Request-Id", - "2f4a7d98-351f-499d-9ca8-14a5296f4946", + "ece39a3b-7c43-4cfc-af29-647c8e22b677", "CSP-Billing-Usage", - "CognitiveServices.LUIS.Transaction|1", + "CognitiveServices.LUIS.Transaction=1", "Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload", "X-Content-Type-Options", @@ -233,7 +244,7 @@ "X-Frame-Options", "SAMEORIGIN", "Date", - "Tue, 07 Apr 2020 15:15:32 GMT", + "Thu, 16 Jul 2020 18:23:50 GMT", "Connection", "close" ] @@ -241,16 +252,25 @@ { "scope": "https://westus.api.cognitive.microsoft.com:443", "method": "POST", - "path": "/luis/v2.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554?verbose=false&staging=false&spellCheck=false&log=true", - "body": "custom", + "path": "/luis/prediction/v3.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554/slots/production/predict?verbose=true&log=true&show-all-intents=false", + "body": { + "query": "custom", + "options": { + "preferExternalEntities": true + } + }, "status": 200, "response": { "query": "custom", - "topScoringIntent": { - "intent": "Confirm", - "score": 0.3304704 - }, - "entities": [] + "prediction": { + "topIntent": "Confirm", + "intents": { + "Confirm": { + "score": 0.4082594 + } + }, + "entities": {} + } }, "rawHeaders": [ "Cache-Control", @@ -258,15 +278,15 @@ "Pragma", "no-cache", "Content-Length", - "125", + "111", "Content-Type", "application/json; charset=utf-8", "Apim-Request-Id", - "5f3c1b8a-23e4-4692-bf7a-82ec8827242e", + "add1b544-d2f6-407a-aec9-8b4a49fb43b8", "Request-Id", - "5f3c1b8a-23e4-4692-bf7a-82ec8827242e", + "add1b544-d2f6-407a-aec9-8b4a49fb43b8", "CSP-Billing-Usage", - "CognitiveServices.LUIS.Transaction|1", + "CognitiveServices.LUIS.Transaction=1", "Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload", "X-Content-Type-Options", @@ -274,7 +294,7 @@ "X-Frame-Options", "SAMEORIGIN", "Date", - "Tue, 07 Apr 2020 15:15:33 GMT", + "Thu, 16 Jul 2020 18:23:50 GMT", "Connection", "close" ] From 081dac08efaf355965e106e5907ad2b4fcaa551f Mon Sep 17 00:00:00 2001 From: matiasroldan6 Date: Thu, 23 Jul 2020 17:25:38 -0300 Subject: [PATCH 11/17] Replicate to template --- .../generators/skill/src/copier.js | 8 + .../templates/sample-skill/_.eslintrc.json | 4 +- .../templates/sample-skill/_package.json | 1 + .../deployment/scripts/deploy.ps1 | 233 ++++++++++++----- .../scripts/deploy_cognitive_models.ps1 | 53 ++-- .../deployment/scripts/luis_functions.ps1 | 229 +++++++---------- ...itivemodels.json => _cognitivemodels.json} | 2 +- .../src/adapters/defaultAdapter.ts | 133 ++++++---- .../sample-skill/src/appsettings.json | 7 +- .../allowedCallersClaimsValidator.ts | 39 +++ .../sample-skill/src/authentication/index.ts | 6 + .../src/bots/defaultActivityHandler.ts | 12 +- .../dialogs/{mainDialog.ts => _mainDialog.ts} | 97 ++++--- .../sample-skill/src/dialogs/sampleAction.ts | 13 +- .../sample-skill/src/dialogs/sampleDialog.ts | 20 +- .../src/dialogs/skillDialogBase.ts | 13 +- .../src/extensions/turnContextEx.ts | 2 +- .../skill/templates/sample-skill/src/index.ts | 52 ++-- .../sample-skill/src/services/botServices.ts | 121 ++++----- .../sample-skill/src/services/botSettings.ts | 4 +- .../test/helpers/skillTestBase.js | 15 +- .../sample-skill/test/interruption.test.js | 8 +- .../interruption_cancel_response.json | 206 +++++++++------ .../interruption_help_response.json | 236 ++++++++++-------- .../mainDialog_help_response.json | 66 +++-- .../mainDialog_unhandled_response.json | 132 ++++++---- .../nockFixtures/sampleDialog_response.json | 232 +++++++++-------- ...r-bot-virtualassistant.skill.test.suite.js | 28 ++- 28 files changed, 1136 insertions(+), 836 deletions(-) rename templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/{cognitivemodels.json => _cognitivemodels.json} (92%) create mode 100644 templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/authentication/allowedCallersClaimsValidator.ts create mode 100644 templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/authentication/index.ts rename templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/dialogs/{mainDialog.ts => _mainDialog.ts} (78%) diff --git a/templates/typescript/generator-bot-virtualassistant/generators/skill/src/copier.js b/templates/typescript/generator-bot-virtualassistant/generators/skill/src/copier.js index de361128ae..5321e1751c 100644 --- a/templates/typescript/generator-bot-virtualassistant/generators/skill/src/copier.js +++ b/templates/typescript/generator-bot-virtualassistant/generators/skill/src/copier.js @@ -80,6 +80,14 @@ class Copier { join(`pipeline`, `_sample-skill.yml`), join(`pipeline`, `${newSkill.skillName}.yml`) ); + templateFiles.set( + join(`src`, `_cognitivemodels.json`), + join(`src`, `cognitivemodels.json`) + ); + templateFiles.set( + join(`src`, `dialogs`, `_mainDialog.ts`), + join(`src`, `dialogs`, `mainDialog.ts`) + ); templateFiles.set( join(`src`, `manifest`, `_manifest-1.0.json`), join(`src`, `manifest`, `manifest-1.0.json`) diff --git a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/_.eslintrc.json b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/_.eslintrc.json index 02aebb9da8..2b593c4e7d 100644 --- a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/_.eslintrc.json +++ b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/_.eslintrc.json @@ -25,9 +25,7 @@ "@typescript-eslint/indent": ["error", 4], "@typescript-eslint/interface-name-prefix": 0, "@typescript-eslint/no-explicit-any": 0, - "@typescript-eslint/no-object-literal-type-assertion": ["error", { - "allowAsParameter": true - }], + "@typescript-eslint/consistent-type-assertions": ["error"], "@typescript-eslint/no-use-before-define": ["error", { "functions": false, "classes": true }], "@typescript-eslint/ban-types": 0 } diff --git a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/_package.json b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/_package.json index 1d43864b3c..17ec954e5c 100644 --- a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/_package.json +++ b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/_package.json @@ -24,6 +24,7 @@ "botbuilder-applicationinsights": "^4.9.2", "botbuilder-azure": "^4.9.2", "botbuilder-dialogs": "^4.9.2", + "botbuilder-lg": "^4.9.2", "bot-solutions": "^1.0.0", "botframework-config": "^4.9.2", "botframework-connector": "^4.9.2", diff --git a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/deployment/scripts/deploy.ps1 b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/deployment/scripts/deploy.ps1 index c6861c8318..437bd4c788 100644 --- a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/deployment/scripts/deploy.ps1 +++ b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/deployment/scripts/deploy.ps1 @@ -19,6 +19,87 @@ Param( [string] $logFile = $(Join-Path $PSScriptRoot .. "deploy_log.txt") ) +function ParseValidationResult +( + [ValidateNotNullOrEmpty()] + [System.Collections.ArrayList] + $ValidationResult +) +{ + # If there is a single ErrorRecord item in the validation result array, then we take that to mean that + # the stderr output stream from running the 'az group deployment validate' command spat out an error. + # + if ($ValidationResult.Count -eq 1 -and $ValidationResult[0] -is [System.Management.Automation.ErrorRecord]) + { + # There are two error formats we could be dealing with: + # 1) We are dealing with a locally-throw exception with a regular exception message; or + # 2) A JSON service error was returned, and the exception message contains the JSON payload. + + # Per GitHub Issue https://github.com/Azure/azure-cli/issues/13037, validation errors are not returned as + # valid JSON. To handle this, parse out the error code and message manually and return an object containing + # the parsed details. + # + $expression = "('code'\s*:\s*['`"]{1}(?[^'`"]*)['`"]{1})|('message'\s*:\s*`"(?[^`"]*)`")" + $regex = New-Object System.Text.RegularExpressions.Regex($expression) + $matches = $regex.Matches($ValidationResult[0].Exception.Message) + + # Here, we parse out only successful match groups where the name matches the capture group names in the expression above. + # + $groupNames = @("code", "message") + $groups = if ($matches) { $matches.Groups | Where-Object { $_.Success -and $groupNames -contains $_.Name } } else { $null } + + # If we don't have any matches, then assume this is a non-service error, and take the exception message as-is. + # + # If we do match on at least one property, then build a Hashtable object that contains the unique properties. + # In JSON representation, this will look like the following: + # + # { + # "code": "ErrorCode", + # "message": "Description of the returned validation error code." + # } + # + # From that, we can concatenate the service error properties into a single message string. + # + if (-not $groups -or $groups.Count -eq 0) + { + $validationError = @{ + "message" = $ValidationResult[0].Exception.Message + } + } + else + { + $serviceError = @{} + foreach ($group in $groups) + { + $serviceError[$group.Name] = $group.Value + } + + $messageComponents = @() + foreach ($groupName in $groupNames) + { + if ($serviceError[$groupName]) + { + $messageComponents += $serviceError[$groupName] + } + } + + $validationError = @{ + "message" = [String]::Join(" : ", $messageComponents) + } + } + + return @{ + "error" = $validationError + } + } + + # If a single ErrorRecord was not returned in the validation results array, then we assume that the validation + # operation was successful, and that the contents of the array are each line of the returned JSON payload. + # In this case, pipe all lines into ConvertFrom-Json to return the parsed PSCustomObject. + # + return $ValidationResult | ConvertFrom-Json +} + # Src folder path $srcDir = $(Join-Path $projDir "src") @@ -93,7 +174,7 @@ if (-not $luisAuthoringKey) { else { $createLuisAuthoring = $true } - } + } } else { $createLuisAuthoring = $false @@ -142,72 +223,94 @@ Write-Host "Done." -ForegroundColor Green # Deploy Azure services (deploys LUIS, QnA Maker, Content Moderator, CosmosDB) if ($parametersFile) { - Write-Host "> Validating Azure deployment ..." -NoNewline - $validation = az deployment group validate ` - --resource-group $resourcegroup ` - --template-file "$(Join-Path $PSScriptRoot '..' 'Resources' 'template.json')" ` - --parameters "@$($parametersFile)" ` - --parameters name=$name microsoftAppId=$appId microsoftAppPassword="`"$($appPassword)`"" luisAuthoringLocation=$armLuisAuthoringRegion useLuisAuthoring=$createLuisAuthoring ` - --output json - - if ($validation) { - $validation >> $logFile - $validation = $validation | ConvertFrom-Json - - if (-not $validation.error) { - Write-Host "Done." -ForegroundColor Green - Write-Host "> Deploying Azure services (this could take a while)..." -ForegroundColor Yellow -NoNewline - $deployment = az deployment group create ` - --name $timestamp ` - --resource-group $resourceGroup ` - --template-file "$(Join-Path $PSScriptRoot '..' 'Resources' 'template.json')" ` - --parameters "@$($parametersFile)" ` - --parameters name=$name microsoftAppId=$appId microsoftAppPassword="`"$($appPassword)`"" luisAuthoringLocation=$armLuisAuthoringRegion useLuisAuthoring=$createLuisAuthoring ` - --output json 2>> $logFile | Out-Null - - Write-Host "Done." -ForegroundColor Green - } - else { - Write-Host "! Template is not valid with provided parameters. Review the log for more information." -ForegroundColor Red - Write-Host "! Error: $($validation.error.message)" -ForegroundColor Red - Write-Host "! Log: $($logFile)" -ForegroundColor Red - Write-Host "+ To delete this resource group, run 'az group delete -g $($resourceGroup) --no-wait'" -ForegroundColor Magenta - Break - } - } + Write-Host "> Validating Azure deployment ..." -NoNewline + + # To explain the syntax here: + # - 'az deployment group validate' is being executed with supplied parameters prefixed with '--' + # - 2>&1 merges the stderr output stream into stdout, ensuring all output from the executed command comes through stdout + # - stdout is piped into Tee-Object to write the contents of stdout to our log file, and capture the piped contents in a variable, $validation + # - The stream is finally piped on into Out-Null so that it does not get rendered to the host + # + az deployment group validate ` + --resource-group $resourcegroup ` + --template-file "$(Join-Path $PSScriptRoot '..' 'resources' 'template.json')" ` + --parameters "@$($parametersFile)" ` + --parameters name=$name microsoftAppId=$appId microsoftAppPassword="`"$($appPassword)`"" luisAuthoringLocation=$armLuisAuthoringRegion useLuisAuthoring=$createLuisAuthoring ` + --output json ` + 2>&1 ` + | Tee-Object -FilePath $logFile -OutVariable validation ` + | Out-Null + + # OutVariable always outputs the contents of the piped output stream as System.Collections.ArrayList, so now let's parse into + # a format that is a little easier to evaluate. + # + $validation = ParseValidationResult -ValidationResult $validation + + if ($validation.error) { + Write-Host "! Template is not valid with provided parameters. Review the log for more information." -ForegroundColor Red + Write-Host "! Error: $($validation.error.message)" -ForegroundColor Red + Write-Host "! Log: $($logFile)" -ForegroundColor Red + Write-Host "+ To delete this resource group, run 'az group delete -g $($resourceGroup) --no-wait'" -ForegroundColor Magenta + break + } + + Write-Host "Done." -ForegroundColor Green + + Write-Host "> Deploying Azure services (this could take a while)..." -ForegroundColor Yellow -NoNewline + + az deployment group create ` + --name $timestamp ` + --resource-group $resourceGroup ` + --template-file "$(Join-Path $PSScriptRoot '..' 'resources' 'template.json')" ` + --parameters "@$($parametersFile)" ` + --parameters name=$name microsoftAppId=$appId microsoftAppPassword="`"$($appPassword)`"" luisAuthoringLocation=$armLuisAuthoringRegion useLuisAuthoring=$createLuisAuthoring ` + --output json 2>> $logFile | Out-Null + + Write-Host "Done." -ForegroundColor Green } else { - Write-Host "> Validating Azure deployment ..." -NoNewline - $validation = az deployment group validate ` - --resource-group $resourcegroup ` - --template-file "$(Join-Path $PSScriptRoot '..' 'Resources' 'template.json')" ` - --parameters name=$name microsoftAppId=$appId microsoftAppPassword="`"$($appPassword)`"" luisAuthoringLocation=$armLuisAuthoringRegion useLuisAuthoring=$createLuisAuthoring ` - --output json - - if ($validation) { - $validation >> $logFile - $validation = $validation | ConvertFrom-Json - - if (-not $validation.error) { - Write-Host "Done." -ForegroundColor Green - Write-Host "> Deploying Azure services (this could take a while)..." -ForegroundColor Yellow -NoNewline - $deployment = az deployment group create ` - --name $timestamp ` - --resource-group $resourceGroup ` - --template-file "$(Join-Path $PSScriptRoot '..' 'Resources' 'template.json')" ` - --parameters name=$name microsoftAppId=$appId microsoftAppPassword="`"$($appPassword)`"" luisAuthoringLocation=$armLuisAuthoringRegion useLuisAuthoring=$createLuisAuthoring ` - --output json 2>> $logFile | Out-Null - - Write-Host "Done." -ForegroundColor Green - } - else { - Write-Host "! Template is not valid with provided parameters. Review the log for more information." -ForegroundColor Red - Write-Host "! Error: $($validation.error.message)" -ForegroundColor Red - Write-Host "! Log: $($logFile)" -ForegroundColor Red - Write-Host "+ To delete this resource group, run 'az group delete -g $($resourceGroup) --no-wait'" -ForegroundColor Magenta - Break - } - } + Write-Host "> Validating Azure deployment ..." -NoNewline + + # To explain the syntax here: + # - 'az deployment group validate' is being executed with supplied parameters prefixed with '--' + # - 2>&1 merges the stderr output stream into stdout, ensuring all output from the executed command comes through stdout + # - stdout is piped into Tee-Object to write the contents of stdout to our log file, and capture the piped contents in a variable, $validation + # - The stream is finally piped on into Out-Null so that it does not get rendered to the host + # + az deployment group validate ` + --resource-group $resourcegroup ` + --template-file "$(Join-Path $PSScriptRoot '..' 'resources' 'template.json')" ` + --parameters name=$name microsoftAppId=$appId microsoftAppPassword="`"$($appPassword)`"" luisAuthoringLocation=$armLuisAuthoringRegion useLuisAuthoring=$createLuisAuthoring ` + --output json ` + 2>&1 ` + | Tee-Object -FilePath $logFile -OutVariable validation ` + | Out-Null + + # OutVariable always outputs the contents of the piped output stream as System.Collections.ArrayList, so now let's parse into + # a format that is a little easier to evaluate. + # + $validation = ParseValidationResult -ValidationResult $validation + + if ($validation.error) { + Write-Host "! Template is not valid with provided parameters. Review the log for more information." -ForegroundColor Red + Write-Host "! Error: $($validation.error.message)" -ForegroundColor Red + Write-Host "! Log: $($logFile)" -ForegroundColor Red + Write-Host "+ To delete this resource group, run 'az group delete -g $($resourceGroup) --no-wait'" -ForegroundColor Magenta + break + } + + Write-Host "Done." -ForegroundColor Green + + Write-Host "> Deploying Azure services (this could take a while)..." -ForegroundColor Yellow -NoNewline + + az deployment group create ` + --name $timestamp ` + --resource-group $resourceGroup ` + --template-file "$(Join-Path $PSScriptRoot '..' 'resources' 'template.json')" ` + --parameters name=$name microsoftAppId=$appId microsoftAppPassword="`"$($appPassword)`"" luisAuthoringLocation=$armLuisAuthoringRegion useLuisAuthoring=$createLuisAuthoring ` + --output json 2>> $logFile | Out-Null + + Write-Host "Done." -ForegroundColor Green } # Get deployment outputs diff --git a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/deployment/scripts/deploy_cognitive_models.ps1 b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/deployment/scripts/deploy_cognitive_models.ps1 index 037f4419a0..0f191d5781 100644 --- a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/deployment/scripts/deploy_cognitive_models.ps1 +++ b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/deployment/scripts/deploy_cognitive_models.ps1 @@ -191,28 +191,27 @@ foreach ($language in $languageArr) # Deploy LUIS model $luisApp = DeployLUIS ` -name $name ` - -lu_file $lu ` - -region $luisAuthoringRegion ` - -authoringKey $luisAuthoringKey ` - -language $language ` - -gov $gov ` + -luFile $lu ` + -endpoint $luisEndpoint ` + -subscriptionKey $luisAuthoringKey ` + -culture $language ` -log $logFile Write-Host "> Setting LUIS subscription key ..." -NoNewline if ($luisApp) { # Setting subscription key - $addKeyResult = luis add appazureaccount ` - --appId $luisApp.id ` - --authoringKey $luisAuthoringKey ` - --region $luisAuthoringRegion ` - --accountName $luisAccountName ` - --azureSubscriptionId $azAccount.id ` - --resourceGroup $resourceGroup ` - --cloud $cloud ` - --armToken "$($azAccessToken.accessToken)" 2>> $logFile - - if (-not $addKeyResult) { + $addKeyResult = bf luis:application:assignazureaccount ` + --accountName $luisAccountName ` + --resourceGroup $resourceGroup ` + --armToken $azAccessToken.accessToken ` + --azureSubscriptionId $azAccount.id ` + --appId $luisApp.id ` + --endpoint $luisEndpoint ` + --subscriptionKey $luisAuthoringKey 2>> $logFile + + if ($addKeyResult -ne "Account successfully assigned.") { $luisKeySet = $false + $addKeyResult >> $logFile Write-Host "! Could not assign subscription key automatically. Review the log for more information. " -ForegroundColor DarkRed Write-Host "! Log: $($logFile)" -ForegroundColor DarkRed Write-Host "+ Please assign your subscription key manually in the LUIS portal." -ForegroundColor Magenta @@ -339,18 +338,18 @@ foreach ($language in $languageArr) # Setting subscription key Write-Host "> Setting LUIS subscription key ..." -NoNewline - $addKeyResult = luis add appazureaccount ` - --appId $dispatchApp.appId ` - --accountName $luisAccountName ` - --authoringKey $luisAuthoringKey ` - --region $luisAuthoringRegion ` - --azureSubscriptionId $azAccount.id ` - --resourceGroup $resourceGroup ` - --cloud $cloud ` - --armToken $azAccessToken.accessToken 2>> $logFile - - if (-not $addKeyResult) { + $addKeyResult = bf luis:application:assignazureaccount ` + --accountName $luisAccountName ` + --resourceGroup $resourceGroup ` + --armToken $azAccessToken.accessToken ` + --azureSubscriptionId $azAccount.id ` + --appId $dispatchApp.appId ` + --endpoint $luisEndpoint ` + --subscriptionKey $luisAuthoringKey 2>> $logFile + + if ($addKeyResult -ne "Account successfully assigned.") { $luisKeySet = $false + $addKeyResult >> $logFile Write-Host "! Could not assign subscription key automatically. Review the log for more information. " -ForegroundColor DarkRed Write-Host "! Log: $($logFile)" -ForegroundColor DarkRed Write-Host "+ Please assign your subscription key manually in the LUIS portal." -ForegroundColor Magenta diff --git a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/deployment/scripts/luis_functions.ps1 b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/deployment/scripts/luis_functions.ps1 index 9b75a9ee76..62739df8be 100644 --- a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/deployment/scripts/luis_functions.ps1 +++ b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/deployment/scripts/luis_functions.ps1 @@ -1,218 +1,159 @@ -function DeployLUIS ($name, $lu_file, $region, $authoringKey, $language, $gov, $log) +function DeployLUIS ($name, $luFile, $endpoint, $subscriptionKey, $culture, $log) { - $id = $lu_file.BaseName - $outFile = Join-Path $lu_file.DirectoryName "$($id).json" - $appName = "$($name)$($langCode)_$($id)" - - if ($gov) - { - $cloud = 'us' - } - else - { - $cloud = 'com' - } + $id = $luFile.BaseName + $outFile = Join-Path $luFile.DirectoryName "$($id).json" + $appName = "$($name)$($culture)_$($id)" - Write-Host "> Parsing $($language) $($id) LU file ..." -NoNewline + Write-Host "> Converting $($language) $($id) LU file ..." -NoNewline bf luis:convert ` - --name $appName ` - --in $lu_file ` - --culture $language ` + --in $luFile ` --out $outFile ` - --force 2>> $log | Out-Null + --name $appName ` + --culture $culture ` + --force Write-Host "Done." -ForegroundColor Green Write-Host "> Deploying $($language) $($id) LUIS app ..." -NoNewline - $luisApp = (luis import application ` - --appName $appName ` - --authoringKey $authoringKey ` - --subscriptionKey $authoringKey ` - --region $region ` + $result = bf luis:application:import ` --in $outFile ` - --cloud $cloud ` - --wait) 2>> $log | ConvertFrom-Json + --name $appName ` + --endpoint $endpoint ` + --subscriptionKey $subscriptionKey ` + --json ` + --save | ConvertFrom-Json - if (-not $luisApp) - { - Write-Host "! Could not deploy LUIS model. Review the log for more information." -ForegroundColor DarkRed - Write-Host "! Log: $($log)" -ForegroundColor DarkRed - Return $null - } - else - { + if ($result.Status -eq "Success") { Write-Host "Done." -ForegroundColor Green + + $luisApp = bf luis:application:show ` + --appId $result.id ` + --endpoint $endpoint ` + --subscriptionKey $subscriptionKey | ConvertFrom-Json + Write-Host "> Training and publishing LUIS app ..." -NoNewline - $(luis train version ` + $(bf luis:train:run ` --appId $luisApp.id ` - --region $region ` - --authoringKey $authoringKey ` + --endpoint $endpoint ` + --subscriptionKey $subscriptionKey ` --versionId $luisApp.activeVersion ` - --cloud $cloud ` --wait - & luis publish version ` + & bf luis:application:publish ` --appId $luisApp.id ` - --region $region ` - --authoringKey $authoringKey ` - --versionId $luisApp.activeVersion ` - --cloud $cloud ` - --wait) 2>> $log | Out-Null + --endpoint $endpoint ` + --subscriptionKey $subscriptionKey ` + --versionId $luisApp.activeVersion) 2>> $log | Out-Null Write-Host "Done." -ForegroundColor Green - Return $luisApp - } + Return $luisApp + } + else { + Write-Host "! Could not deploy LUIS model. Review the log for more information." -ForegroundColor DarkRed + Write-Host "! Log: $($log)" -ForegroundColor DarkRed + Return $null + } } -function UpdateLUIS ($lu_file, $appId, $version, $language, $region, $authoringKey, $subscriptionKey, $gov, $log) +function UpdateLUIS ($luFile, $appId, $endpoint, $subscriptionKey, $culture, $version, $log) { - $id = $lu_file.BaseName - $outFile = Join-Path $lu_file.DirectoryName "$($id).json" + $id = $luFile.BaseName + $outFile = Join-Path $luFile.DirectoryName "$($id).json" $appName = "$($name)$($culture)_$($id)" - - if ($gov) - { - $cloud = 'us' - } - else - { - $cloud = 'com' - } - Write-Host "> Getting hosted $($language) $($id) LUIS model settings..." -NoNewline - $luisApp = (luis get application ` + Write-Host "> Getting hosted $($culture) $($id) LUIS model settings..." -NoNewline + $luisApp = bf luis:application:show ` --appId $appId ` - --region $region ` - --authoringKey $authoringKey ` - --cloud $cloud) 2>> $log | ConvertFrom-Json + --endpoint $endpoint ` + --subscriptionKey $subscriptionKey | ConvertFrom-Json Write-Host "Done." -ForegroundColor Green - Write-Host "> Parsing $($language) $($id) LU file ..." -NoNewline - ($output = bf luis:convert ` - --name $appName ` - --in $lu_file ` - --culture $luisApp.culture ` + + Write-Host "> Converting $($culture) $($id) LU file ..." -NoNewline + bf luis:convert ` + --in $luFile ` --out $outFile ` - --force 2>&1) >> $log + --name $appName ` + --culture $culture ` + --force 2>> $log | Out-Null if (-not (Test-Path $outFile)) { Write-Host "Error." -ForegroundColor Red Write-Host "! File not created. Review the log for more information." -ForegroundColor Red - Write-Host "! Log: $($log)" -ForegroundColor Red - Break - } - - if ($output -match 'error') { - Write-Host "Error." -ForegroundColor Red - Write-Host "! Could not parse the LU file. Review the log for more information." -ForegroundColor Red - Write-Host "! Log: $($log)" -ForegroundColor Red + Write-Host "! Log: $($log)" -ForegroundColor Red Break } else { Write-Host "Done." -ForegroundColor Green } - + + Write-Host "> Getting current versions ..." -NoNewline - $versions = (luis list versions ` + $versions = bf luis:version:list ` --appId $appId ` - --region $region ` - --authoringKey $authoringKey ` - --cloud $cloud) 2>> $log | ConvertFrom-Json + --endpoint $endpoint ` + --subscriptionKey $subscriptionKey 2>> $log | ConvertFrom-Json Write-Host "Done." -ForegroundColor Green + if ($versions | Where { $_.version -eq $version }) { if ($versions | Where { $_.version -eq "backup" }) { Write-Host "> Deleting old backup version ..." -NoNewline - luis delete version ` + bf luis:version:delete ` + --versionId "backup" ` --appId $appId ` - --versionId backup ` - --region $region ` - --authoringKey $authoringKey ` - --cloud $cloud ` - --force ` - --wait 2>> $log | Out-Null + --endpoint $endpoint ` + --subscriptionKey $subscriptionKey 2>> $log | Out-Null Write-Host "Done." -ForegroundColor Green } Write-Host "> Saving current version as backup ..." -NoNewline - luis rename version ` - --appId $appId ` + bf luis:version:rename ` --versionId $version ` - --region $region ` - --newVersionId backup ` - --authoringKey $authoringKey ` - --subscriptionKey $subscriptionKey ` - --cloud $cloud ` - --wait 2>> $log | Out-Null + --newVersionId "backup" ` + --appId $appId ` + --endpoint $endpoint ` + --subscriptionKey $subscriptionKey 2>> $log | Out-Null Write-Host "Done." -ForegroundColor Green } Write-Host "> Importing new version ..." -NoNewline - ($output = luis import version ` + $result = bf luis:version:import ` + --in $outFile ` --appId $appId ` - --authoringKey $authoringKey ` + --endpoint $endpoint ` --subscriptionKey $subscriptionKey ` --versionId $version ` - --region $region ` - --cloud $cloud ` - --in $outFile ` - --wait 2>&1) >> $log - - if ($output) { - Write-Host "Error." -ForegroundColor Red + --json 2>> $log | ConvertFrom-Json - Write-Host "> Looking for backup versions ..." -NoNewline - $versions = (luis list versions ` - --appId $appId ` - --region $region ` - --authoringKey $authoringKey ` - --cloud $cloud) 2>> $log | ConvertFrom-Json - - if ($versions | Where { $_.version -eq 'backup' }) - { - Write-Host "Done." -ForegroundColor Green - - Write-Host "> Setting backup version as active ..." -NoNewline - luis set $appId ` - --versionId 'backup' ` - --authoringKey $authoringKey ` - --subscriptionKey $subscriptionKey ` - --region $region ` - --cloud $cloud ` - --force 2>> $log | Out-Null - Write-Host "Done." - } - else { - Write-Host "! No backup version found. Please review your LUIS application in the LUIS portal to resolve any issues." -ForegroundColor Red - Break - } + if ($result.Status -eq 'Success') { + Write-Host "Done." -ForegroundColor Green } else { - Write-Host "Done." -ForegroundColor Green + Write-Host "Error." -ForegroundColor Red + Write-Host "! Could not import new version. Please review your LUIS application in the LUIS portal to resolve any issues." -ForegroundColor Red + Break } Write-Host "> Training and publishing LUIS app ..." -NoNewline - $(luis train version ` + $(bf luis:train:run ` --appId $luisApp.id ` - --region $region ` - --authoringKey $authoringKey ` + --endpoint $endpoint ` + --subscriptionKey $subscriptionKey ` --versionId $luisApp.activeVersion ` - --cloud $cloud ` --wait - & luis publish version ` + & bf luis:application:publish ` --appId $luisApp.id ` - --region $region ` - --authoringKey $authoringKey ` - --versionId $luisApp.activeVersion ` - --cloud $cloud ` - --wait) 2>> $log | Out-Null + --endpoint $endpoint ` + --subscriptionKey $subscriptionKey ` + --versionId $luisApp.activeVersion) 2>> $log | Out-Null Write-Host "Done." -ForegroundColor Green } -function RunLuisGen($lu_file, $outName, $outFolder, $log) +function RunLuisGen($luFile, $outName, $outFolder, $log) { - $id = $lu_file.BaseName - $luisFolder = $lu_file.DirectoryName + $id = $luFile.BaseName + $luisFolder = $luFile.DirectoryName $luisFile = Join-Path $luisFolder "$($id).json" bf luis:generate:ts ` diff --git a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/cognitivemodels.json b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/_cognitivemodels.json similarity index 92% rename from templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/cognitivemodels.json rename to templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/_cognitivemodels.json index e82c80af6b..9e3713504f 100644 --- a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/cognitivemodels.json +++ b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/_cognitivemodels.json @@ -13,7 +13,7 @@ "subscriptionKey": "" }, { - "id": "skill", + "id": "<%=skillNameCamelCase%>", "name": "", "appId": "", "version": "0.1", diff --git a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/adapters/defaultAdapter.ts b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/adapters/defaultAdapter.ts index 1d1ab55007..765487fd13 100644 --- a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/adapters/defaultAdapter.ts +++ b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/adapters/defaultAdapter.ts @@ -4,11 +4,12 @@ */ import { - ActivityTypes, BotFrameworkAdapter, BotFrameworkAdapterSettings, BotTelemetryClient, + ConversationState, ShowTypingMiddleware, + TelemetryException, TelemetryLoggerMiddleware, TranscriptLoggerMiddleware, TurnContext } from 'botbuilder'; @@ -16,66 +17,51 @@ import { EventDebuggerMiddleware, SetLocaleMiddleware, LocaleTemplateManager, - SetSpeakMiddleware } from 'bot-solutions'; + SetSpeakMiddleware, + ActivityEx } from 'bot-solutions'; import { IBotSettings } from '../services/botSettings'; import { TurnContextEx } from '../extensions/turnContextEx'; import { AzureBlobTranscriptStore, BlobStorageSettings } from 'botbuilder-azure'; import { TelemetryInitializerMiddleware } from 'botbuilder-applicationinsights'; -import { Activity } from 'botframework-schema'; export class DefaultAdapter extends BotFrameworkAdapter { + private readonly conversationState: ConversationState; + private readonly telemetryClient: BotTelemetryClient; + private readonly templateEngine: LocaleTemplateManager; + public constructor( settings: Partial, - adapterSettings: Partial, - templateManager: LocaleTemplateManager, + templateEngine: LocaleTemplateManager, + conversationState: ConversationState, telemetryMiddleware: TelemetryInitializerMiddleware, telemetryClient: BotTelemetryClient, + adapterSettings: Partial ) { super(adapterSettings); - this.onTurnError = async (context: TurnContext, error: Error): Promise => { - await context.sendActivity({ - type: ActivityTypes.Trace, - text: error.message || JSON.stringify(error) - }); - await context.sendActivity({ - type: ActivityTypes.Trace, - text: error.stack - }); - - await context.sendActivity(templateManager.generateActivityForLocale('ErrorMessage', context.activity.locale)); - telemetryClient.trackException({ exception: error }); - - if (TurnContextEx.isSkill(context)){ - // Send and EndOfConversation activity to the skill caller with the error to end the conversation - // and let the caller decide what to do. - const endOfconversation: Partial = { - type: ActivityTypes.EndOfConversation, - code: 'SkillError', - text: error.message - }; - await context.sendActivity(endOfconversation); - } - }; - - this.onTurnError = async (context: TurnContext, error: Error): Promise => { - await context.sendActivity({ - type: ActivityTypes.Trace, - text: error.message || JSON.stringify(error) - }); - await context.sendActivity({ - type: ActivityTypes.Trace, - text: error.stack - }); - await context.sendActivity(templateManager.generateActivityForLocale('ErrorMessage', context.activity.locale)); - telemetryClient.trackException({ exception: error }); - }; - - if (settings.blobStorage === undefined) { - throw new Error('There is no blobStorage value in appsettings file'); + + if (conversationState === undefined) { + throw new Error('conversationState parameter is null'); + } + this.conversationState = conversationState; + + if (templateEngine === undefined) { + throw new Error('templateEngine parameter is null'); } + this.templateEngine = templateEngine; + + if (telemetryClient === undefined) { + throw new Error('telemetryClient parameter is null'); + } + this.telemetryClient = telemetryClient; + + this.onTurnError = this.handleTurnError; this.use(telemetryMiddleware); + + if (settings.blobStorage === undefined) { + throw new Error('There is no blobStorage value in appsettings file'); + } // Uncomment the following line for local development without Azure Storage // this.use(new TranscriptLoggerMiddleware(new MemoryTranscriptStore())); @@ -87,4 +73,61 @@ export class DefaultAdapter extends BotFrameworkAdapter { this.use(new EventDebuggerMiddleware()); this.use(new SetSpeakMiddleware()); } + + private async handleTurnError(turnContext: TurnContext, error: Error): Promise { + // Log any leaked exception from the application. + console.error(`[onTurnError] unhandled error : ${ error }`); + + await this.sendErrorMessage(turnContext, error); + await this.sendEndOfConversationToParent(turnContext, error); + await this.clearConversationStateAsync(turnContext); + } + + private async sendErrorMessage(turnContext: TurnContext, error: Error): Promise { + try { + const telemetryException: TelemetryException = { + exception: error + }; + this.telemetryClient.trackException(telemetryException); + + // Send a message to the user. + await turnContext.sendActivity(this.templateEngine.generateActivityForLocale('ErrorMessage', turnContext.activity.locale)); + + // Send a trace activity, which will be displayed in the Bot Framework Emulator. + // Note: we return the entire exception in the value property to help the developer; + // this should not be done in production. + await turnContext.sendTraceActivity('OnTurnError Trace', error.message, 'https://www.botframework.com/schemas/error', 'TurnError'); + } + catch (err) { + console.error(`Exception caught in sendErrorMessage : ${ err }`); + } + } + + private async sendEndOfConversationToParent(turnContext: TurnContext, error: Error): Promise { + try { + if (TurnContextEx.isSkill(turnContext)) { + // Send and EndOfConversation activity to the skill caller with the error to end the conversation + // and let the caller decide what to do. + const endOfConversation = ActivityEx.createEndOfConversationActivity(); + endOfConversation.code = 'SkillError'; + endOfConversation.text = error.message; + await turnContext.sendActivity(endOfConversation); + } + } + catch (err) { + console.error(`Exception caught in sendEoCToParent : ${ err }`); + } + } + + private async clearConversationStateAsync(turnContext: TurnContext): Promise { + try { + // Delete the conversationState for the current conversation to prevent the + // bot from getting stuck in a error-loop caused by being in a bad state. + // ConversationState should be thought of as similar to "cookie-state" for a Web page. + await this.conversationState.delete(turnContext); + } + catch (err) { + console.error(`Exception caught on attempting to Delete ConversationState : ${ err }`); + } + } } diff --git a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/appsettings.json b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/appsettings.json index 9f1a046da9..74c7a270cb 100644 --- a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/appsettings.json +++ b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/appsettings.json @@ -1,6 +1,7 @@ { "microsoftAppId": "", "microsoftAppPassword": "", + "allowedCallers": [ "*" ], "oauthConnections": [], "skillAuthenticationWhitelist": [], "appInsights": { @@ -8,13 +9,13 @@ }, "blobStorage": { "connectionString": "", - "container": "" + "container": "transcripts" }, "cosmosDb": { "authKey": "", "cosmosDbEndpoint": "", - "containerId": "", - "databaseId": "" + "containerId": "botstate-collection", + "databaseId": "botstate-db" }, "properties": {} } \ No newline at end of file diff --git a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/authentication/allowedCallersClaimsValidator.ts b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/authentication/allowedCallersClaimsValidator.ts new file mode 100644 index 0000000000..7e3da61c8f --- /dev/null +++ b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/authentication/allowedCallersClaimsValidator.ts @@ -0,0 +1,39 @@ +/** + * Copyright(c) Microsoft Corporation.All rights reserved. + * Licensed under the MIT License. + */ + +import { Claim, JwtTokenValidation, SkillValidation } from 'botframework-connector'; + +/** + * Sample claims validator that loads an allowed list from configuration + * and checks that requests are coming from allowed parent bots. + */ +export class AllowedCallersClaimsValidator { + private readonly configKey: string = 'allowedCallers'; + private readonly allowedCallers: string[]; + + public constructor(allowedCallers: string[]) { + // AllowedCallers is the setting in the appsettings.json file + // that consists of the list of parent bot IDs that are allowed to access the skill. + // To add a new parent bot, simply edit the AllowedCallers and add + // the parent bot's Microsoft app ID to the list. + // In this sample, we allow all callers if AllowedCallers contains an "*". + if (allowedCallers === undefined) { + throw new Error('allowedCallers parameter is undefined.'); + } + + this.allowedCallers = allowedCallers; + } + + public validateClaims(claims: Claim[]): void { + // If _allowedCallers contains an "*", we allow all callers. + if (SkillValidation.isSkillClaim(claims) && !this.allowedCallers.includes('*')) { + // Check that the appId claim in the skill request is in the list of callers configured for this bot. + const appId: string = JwtTokenValidation.getAppIdFromClaims(claims); + if (!this.allowedCallers.includes(appId)) { + throw new Error(`Received a request from a bot with an app ID of ${ appId }. To enable requests from this caller, add the app ID to your configuration file.`); + } + } + } +} \ No newline at end of file diff --git a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/authentication/index.ts b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/authentication/index.ts new file mode 100644 index 0000000000..88d0178322 --- /dev/null +++ b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/authentication/index.ts @@ -0,0 +1,6 @@ +/** + * Copyright(c) Microsoft Corporation.All rights reserved. + * Licensed under the MIT License. + */ + +export * from './allowedCallersClaimsValidator'; \ No newline at end of file diff --git a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/bots/defaultActivityHandler.ts b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/bots/defaultActivityHandler.ts index 41383fbdd9..e2f91680c1 100644 --- a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/bots/defaultActivityHandler.ts +++ b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/bots/defaultActivityHandler.ts @@ -8,6 +8,7 @@ import { ActivityHandler, ActivityTypes, BotState, + BotTelemetryClient, Channels, StatePropertyAccessor, TurnContext } from 'botbuilder'; @@ -20,16 +21,17 @@ export class DefaultActivityHandler extends ActivityHandler { private readonly dialog: Dialog; private readonly conversationState: BotState; private readonly userState: BotState; - private dialogStateAccessor: StatePropertyAccessor; - private templateManager: LocaleTemplateManager; + private readonly dialogStateAccessor: StatePropertyAccessor; + private readonly templateEngine: LocaleTemplateManager; - public constructor(conversationState: BotState, userState: BotState, templateManager: LocaleTemplateManager, dialog: T) { + public constructor(conversationState: BotState, userState: BotState, templateManager: LocaleTemplateManager, telemetryClient: BotTelemetryClient, dialog: T) { super(); this.dialog = dialog; + this.dialog.telemetryClient = telemetryClient; this.conversationState = conversationState; this.userState = userState; this.dialogStateAccessor = conversationState.createProperty('DialogState'); - this.templateManager = templateManager; + this.templateEngine = templateManager; super.onMembersAdded(this.membersAdded.bind(this)); } @@ -42,7 +44,7 @@ export class DefaultActivityHandler extends ActivityHandler { } protected async membersAdded(turnContext: TurnContext, next: () => Promise): Promise { - await turnContext.sendActivity(this.templateManager.generateActivityForLocale('IntroMessage', turnContext.activity.locale)); + await turnContext.sendActivity(this.templateEngine.generateActivityForLocale('IntroMessage', turnContext.activity.locale)); await DialogEx.run(this.dialog, turnContext, this.dialogStateAccessor); } diff --git a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/dialogs/mainDialog.ts b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/dialogs/_mainDialog.ts similarity index 78% rename from templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/dialogs/mainDialog.ts rename to templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/dialogs/_mainDialog.ts index a37f59e148..582f9d1ff4 100644 --- a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/dialogs/mainDialog.ts +++ b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/dialogs/_mainDialog.ts @@ -6,9 +6,7 @@ import { Activity, ActivityTypes, BotFrameworkAdapter, - BotTelemetryClient, - RecognizerResult, - StatePropertyAccessor } from 'botbuilder'; + RecognizerResult } from 'botbuilder'; import { LuisRecognizer } from 'botbuilder-ai'; import { DialogContext, @@ -20,7 +18,6 @@ import { ComponentDialog } from 'botbuilder-dialogs'; import { ICognitiveModelSet, LocaleTemplateManager } from 'bot-solutions'; import { TokenStatus } from 'botframework-connector'; -import { SkillState } from '../models/skillState'; import { BotServices } from '../services/botServices'; import { SampleDialog } from './sampleDialog'; import { StateProperties } from '../models'; @@ -37,25 +34,18 @@ export class MainDialog extends ComponentDialog { private readonly services: BotServices; private readonly sampleDialog: SampleDialog; private readonly sampleAction: SampleAction; - private readonly templateManager: LocaleTemplateManager; - private readonly stateAccessor: StatePropertyAccessor; + private readonly templateEngine: LocaleTemplateManager; // Constructor public constructor( services: BotServices, - telemetryClient: BotTelemetryClient, - stateAccessor: StatePropertyAccessor, sampleDialog: SampleDialog, sampleAction: SampleAction, - templateManager: LocaleTemplateManager + templateEngine: LocaleTemplateManager ) { super(MainDialog.name); this.services = services; - this.templateManager = templateManager; - this.telemetryClient = telemetryClient; - - // Create conversationstate properties - this.stateAccessor = stateAccessor; + this.templateEngine = templateEngine; const steps: ((sc: WaterfallStepContext) => Promise)[] = [ this.introStep.bind(this), @@ -76,13 +66,14 @@ export class MainDialog extends ComponentDialog { // Runs when the dialog is started. protected async onBeginDialog(innerDc: DialogContext, options: Object): Promise { - if (innerDc.context.activity.type == ActivityTypes.Message) { + const activity: Activity = innerDc.context.activity; + if (activity.type === ActivityTypes.Message && activity.text !== undefined && activity.text.trim().length > 0) { // Get cognitive models for the current locale. const localizedServices: Partial = this.services.getCognitiveModels(innerDc.context.activity.locale as string); // Run LUIS recognition on Skill model and store result in turn state. - const skillLuis: LuisRecognizer | undefined = localizedServices.luisServices ? localizedServices.luisServices.get('sampleSkill') : undefined; + const skillLuis: LuisRecognizer | undefined = localizedServices.luisServices ? localizedServices.luisServices.get('<%=skillNameCamelCase%>') : undefined; if (skillLuis !== undefined) { const skillResult: RecognizerResult = await skillLuis.recognize(innerDc.context); innerDc.context.turnState.set(this.stateProperties.skillLuisResult, skillResult); @@ -96,11 +87,11 @@ export class MainDialog extends ComponentDialog { } // Check for any interruptions - const interrupted = await this.interruptDialog(innerDc); + const interrupted: DialogTurnResult = await this.interruptDialog(innerDc); - if (interrupted) { - // If dialog was interrupted, return EndOfTurn - return MainDialog.EndOfTurn; + if (Object.keys(interrupted).length > 0) { + // If dialog was interrupted, return interrupted result + return interrupted; } } @@ -109,12 +100,13 @@ export class MainDialog extends ComponentDialog { // Runs on every turn of the conversation. protected async onContinueDialog(innerDc: DialogContext): Promise { - if (innerDc.context.activity.type === ActivityTypes.Message) { - + const activity: Activity = innerDc.context.activity; + if (activity.type === ActivityTypes.Message && activity.text !== undefined && activity.text.trim().length > 0) { // Get cognitive models for the current locale. const localizedServices: Partial = this.services.getCognitiveModels(innerDc.context.activity.locale as string); + // Run LUIS recognition on Skill model and store result in turn state. - const skillLuis: LuisRecognizer | undefined = localizedServices.luisServices ? localizedServices.luisServices.get('sampleSkill') : undefined; + const skillLuis: LuisRecognizer | undefined = localizedServices.luisServices ? localizedServices.luisServices.get('<%=skillNameCamelCase%>') : undefined; if (skillLuis !== undefined) { const skillResult: RecognizerResult = await skillLuis.recognize(innerDc.context); innerDc.context.turnState.set(this.stateProperties.skillLuisResult, skillResult); @@ -128,11 +120,11 @@ export class MainDialog extends ComponentDialog { } // Check for any interruptions - const interrupted = await this.interruptDialog(innerDc); + const interrupted: DialogTurnResult = await this.interruptDialog(innerDc); - if (interrupted) { - // If dialog was interrupted, return EndOfTurn - return MainDialog.EndOfTurn; + if (Object.keys(interrupted).length > 0) { + // If dialog was interrupted, return interrupted result + return interrupted; } } @@ -140,8 +132,8 @@ export class MainDialog extends ComponentDialog { } // Runs on every turn of the conversation to check if the conversation should be interrupted. - protected async interruptDialog(innerDc: DialogContext): Promise { - let interrupted = false; + protected async interruptDialog(innerDc: DialogContext): Promise { + let interrupted: DialogTurnResult = {} as DialogTurnResult; const activity: Activity = innerDc.context.activity; if (activity.type === ActivityTypes.Message && activity.text !== undefined && activity.text.trim().length > 0) { @@ -152,29 +144,34 @@ export class MainDialog extends ComponentDialog { if (generalResult.intents[intent].score > 0.5) { switch(intent) { case 'Cancel': { - - await innerDc.context.sendActivity(this.templateManager.generateActivityForLocale('CancelledMessage', innerDc.context.activity.locale)); + await innerDc.context.sendActivity(this.templateEngine.generateActivityForLocale('CancelledMessage', innerDc.context.activity.locale)); await innerDc.cancelAllDialogs(); - await innerDc.beginDialog(this.initialDialogId); - interrupted = true; + if (TurnContextEx.isSkill(innerDc.context)) { + interrupted = await innerDc.endDialog(); + } + else { + interrupted = await innerDc.beginDialog(this.initialDialogId); + } break; } case 'Help': { - - await innerDc.context.sendActivity(this.templateManager.generateActivityForLocale('HelpCard', innerDc.context.activity.locale)); + await innerDc.context.sendActivity(this.templateEngine.generateActivityForLocale('HelpCard', innerDc.context.activity.locale)); await innerDc.repromptDialog(); - interrupted = true; + interrupted = MainDialog.EndOfTurn; break; } case 'Logout': { - // Log user out of all accounts. await this.logUserOut(innerDc); - await innerDc.context.sendActivity(this.templateManager.generateActivityForLocale('LogoutMessage', innerDc.context.activity.locale)); + await innerDc.context.sendActivity(this.templateEngine.generateActivityForLocale('LogoutMessage', innerDc.context.activity.locale)); await innerDc.cancelAllDialogs(); - await innerDc.beginDialog(this.initialDialogId); - interrupted = true; + if (TurnContextEx.isSkill(innerDc.context)) { + interrupted = await innerDc.endDialog(); + } + else { + interrupted = await innerDc.beginDialog(this.initialDialogId); + } break; } } @@ -189,13 +186,13 @@ export class MainDialog extends ComponentDialog { if (TurnContextEx.isSkill(stepContext.context)) { // If the bot is in skill mode, skip directly to route and do not prompt return await stepContext.next(); - } else { - // If bot is in local mode, prompt with intro or continuation message - const promptOptions: PromptOptions = { - prompt: Object.keys(stepContext.options as Activity).length > 0 ? stepContext.options as Activity : this.templateManager.generateActivityForLocale('FirstPromptMessage', stepContext.context.activity.locale) - }; - return await stepContext.prompt(TextPrompt.name, promptOptions); } + + // If bot is in local mode, prompt with intro or continuation message + const promptOptions: PromptOptions = { + prompt: Object.keys(stepContext.options as Activity).length > 0 ? stepContext.options as Activity : this.templateEngine.generateActivityForLocale('FirstPromptMessage', stepContext.context.activity.locale) + }; + return await stepContext.prompt(TextPrompt.name, promptOptions); } // Handles routing to additional dialogs logic. @@ -210,7 +207,7 @@ export class MainDialog extends ComponentDialog { const localizedServices: Partial = this.services.getCognitiveModels(stepContext.context.activity.locale as string); // Get skill LUIS model from configuration. - const luisService: LuisRecognizer | undefined = localizedServices.luisServices? localizedServices.luisServices.get('sampleSkill') : undefined; + const luisService: LuisRecognizer | undefined = localizedServices.luisServices? localizedServices.luisServices.get('<%=skillNameCamelCase%>') : undefined; if (luisService !== undefined){ const result = stepContext.context.turnState.get(this.stateProperties.skillLuisResult); @@ -223,7 +220,7 @@ export class MainDialog extends ComponentDialog { case 'None': default: { // intent was identified but not yet implemented - await stepContext.context.sendActivity(this.templateManager.generateActivityForLocale('UnsupportedMessage', stepContext.context.activity.locale)); + await stepContext.context.sendActivity(this.templateEngine.generateActivityForLocale('UnsupportedMessage', stepContext.context.activity.locale)); return await stepContext.next(); } } @@ -238,7 +235,7 @@ export class MainDialog extends ComponentDialog { case 'SampleAction': { let actionData: Object = {}; - if (ev.value !== undefined && actionData !== undefined) { + if (ev.value !== undefined) { actionData = ev.value as SampleActionInput; } @@ -274,7 +271,7 @@ export class MainDialog extends ComponentDialog { return await stepContext.endDialog(result); } else { - return await stepContext.replaceDialog(this.id, this.templateManager.generateActivityForLocale('CompletedMessage', stepContext.context.activity.locale)); + return await stepContext.replaceDialog(this.id, this.templateEngine.generateActivityForLocale('CompletedMessage', stepContext.context.activity.locale)); } } diff --git a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/dialogs/sampleAction.ts b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/dialogs/sampleAction.ts index cc5fffae2b..4cb2fac9f4 100644 --- a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/dialogs/sampleAction.ts +++ b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/dialogs/sampleAction.ts @@ -8,10 +8,10 @@ import { WaterfallDialog, TextPrompt } from 'botbuilder-dialogs'; import { SkillDialogBase } from './skillDialogBase'; -import { BotTelemetryClient, StatePropertyAccessor, Activity } from 'botbuilder'; +import { StatePropertyAccessor, Activity } from 'botbuilder'; import { BotServices } from '../services/botServices'; import { LocaleTemplateManager } from 'bot-solutions'; -import { SkillState } from '../models/skillState'; +import { SkillState } from '../models'; import { IBotSettings } from '../services/botSettings'; export class SampleActionInput { @@ -27,16 +27,13 @@ enum DialogIds { } export class SampleAction extends SkillDialogBase { - private readonly nameKey: string = 'name'; - public constructor( settings: Partial, services: BotServices, stateAccessor: StatePropertyAccessor, - telemetryClient: BotTelemetryClient, templateManager: LocaleTemplateManager ) { - super(SampleAction.name, settings, services, stateAccessor, telemetryClient, templateManager); + super(SampleAction.name, settings, services, stateAccessor, templateManager); const sample: ((sc: WaterfallStepContext) => Promise)[] = [ this.promptForName.bind(this), @@ -59,13 +56,13 @@ export class SampleAction extends SkillDialogBase { return await stepContext.next(actionInput.name); } - const prompt: Partial = this.templateManager.generateActivityForLocale('NamePrompt', stepContext.context.activity.locale); + const prompt: Partial = this.templateEngine.generateActivityForLocale('NamePrompt', stepContext.context.activity.locale); return await stepContext.prompt(DialogIds.namePrompt, { prompt: prompt }); } private async greetUser(stepContext: WaterfallStepContext): Promise { const data: Object = { name: stepContext.result as string }; - const response: Partial = this.templateManager.generateActivityForLocale('HaveNameMessage', stepContext.context.activity.locale, data); + const response: Partial = this.templateEngine.generateActivityForLocale('HaveNameMessage', stepContext.context.activity.locale, data); await stepContext.context.sendActivity(response); // Pass the response which we'll return to the user onto the next step diff --git a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/dialogs/sampleDialog.ts b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/dialogs/sampleDialog.ts index bfb6aef306..880e523d9f 100644 --- a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/dialogs/sampleDialog.ts +++ b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/dialogs/sampleDialog.ts @@ -5,14 +5,13 @@ import { Activity, - BotTelemetryClient, StatePropertyAccessor} from 'botbuilder'; import { DialogTurnResult, TextPrompt, WaterfallDialog, WaterfallStepContext } from 'botbuilder-dialogs'; -import { SkillState } from '../models/skillState'; +import { SkillState } from '../models'; import { BotServices } from '../services/botServices'; import { IBotSettings } from '../services/botSettings'; import { SkillDialogBase } from './skillDialogBase'; @@ -23,23 +22,19 @@ enum DialogIds { } export class SampleDialog extends SkillDialogBase { - - private readonly nameKey: string = 'name'; - // Constructor public constructor( settings: Partial, services: BotServices, stateAccessor: StatePropertyAccessor, - telemetryClient: BotTelemetryClient, templateManager: LocaleTemplateManager ) { - super(SampleDialog.name, settings, services, stateAccessor, telemetryClient, templateManager); + super(SampleDialog.name, settings, services, stateAccessor, templateManager); const sample: ((sc: WaterfallStepContext) => Promise)[] = [ // NOTE: Uncomment these lines to include authentication steps to this dialog - // GetAuthToken, - // AfterGetAuthToken, + // this.getAuthToken.bind(this), + // this.afterGetAuthToken.bind(this), this.promptForName.bind(this), this.greetUser.bind(this), this.end.bind(this) @@ -54,16 +49,15 @@ export class SampleDialog extends SkillDialogBase { private async promptForName(stepContext: WaterfallStepContext): Promise { // NOTE: Uncomment the following lines to access LUIS result for this turn. //const luisResult = sc.context.turnState.get(StateProperties.skillLuisResult); - const prompt: Partial = this.templateManager.generateActivityForLocale('NamePrompt', stepContext.context.activity.locale); + const prompt: Partial = this.templateEngine.generateActivityForLocale('NamePrompt', stepContext.context.activity.locale); return await stepContext.prompt(DialogIds.namePrompt, { prompt: prompt }); } private async greetUser(stepContext: WaterfallStepContext): Promise { - const tokens: Map = new Map(); - tokens.set(this.nameKey, stepContext.result as string); + const data: Object = { name: stepContext.result as string }; // eslint-disable-next-line @typescript-eslint/no-explicit-any - const response: any = this.templateManager.generateActivityForLocale('HaveNameMessage', stepContext.context.activity.locale, tokens); + const response: any = this.templateEngine.generateActivityForLocale('HaveNameMessage', stepContext.context.activity.locale, data); await stepContext.context.sendActivity(response); return await stepContext.next(); diff --git a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/dialogs/skillDialogBase.ts b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/dialogs/skillDialogBase.ts index f608d65e5b..f33a4a49fc 100644 --- a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/dialogs/skillDialogBase.ts +++ b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/dialogs/skillDialogBase.ts @@ -6,7 +6,6 @@ import { Activity, ActivityTypes, - BotTelemetryClient, StatePropertyAccessor } from 'botbuilder'; import { ComponentDialog, @@ -20,7 +19,7 @@ import { MultiProviderAuthDialog, LocaleTemplateManager } from 'bot-solutions'; import { TokenResponse } from 'botframework-schema'; -import { SkillState } from '../models/skillState'; +import { SkillState } from '../models'; import { BotServices} from '../services/botServices'; import { IBotSettings } from '../services/botSettings'; @@ -28,22 +27,20 @@ export class SkillDialogBase extends ComponentDialog { protected settings: Partial; protected services: BotServices; protected stateAccessor: StatePropertyAccessor; - protected templateManager: LocaleTemplateManager; + protected templateEngine: LocaleTemplateManager; public constructor( dialogId: string, settings: Partial, services: BotServices, stateAccessor: StatePropertyAccessor, - telemetryClient: BotTelemetryClient, - templateManager: LocaleTemplateManager + templateEngine: LocaleTemplateManager ) { super(dialogId); this.services = services; this.stateAccessor = stateAccessor; - this.telemetryClient = telemetryClient; this.settings = settings; - this.templateManager = templateManager; + this.templateEngine = templateEngine; // NOTE: Uncomment the following if your skill requires authentication // if (!services.authenticationConnections.any()) @@ -124,7 +121,7 @@ export class SkillDialogBase extends ComponentDialog { }); // send error message to bot user - await sc.context.sendActivity(this.templateManager.generateActivityForLocale('ErrorMessage', sc.context.activity.locale)); + await sc.context.sendActivity(this.templateEngine.generateActivityForLocale('ErrorMessage', sc.context.activity.locale)); // clear state // eslint-disable-next-line @typescript-eslint/no-explicit-any diff --git a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/extensions/turnContextEx.ts b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/extensions/turnContextEx.ts index e72ba4cc48..9fd5892cf8 100644 --- a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/extensions/turnContextEx.ts +++ b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/extensions/turnContextEx.ts @@ -10,7 +10,7 @@ export namespace TurnContextEx { export function isSkill(turnContext: TurnContext): boolean { // eslint-disable-next-line @typescript-eslint/no-explicit-any - const botIdentity = turnContext.turnState.get((turnContext.adapter as any).BotIdentityKey); + const botIdentity = turnContext.turnState.get(turnContext.adapter.BotIdentityKey); return botIdentity instanceof ClaimsIdentity && SkillValidation.isSkillClaim(botIdentity.claims) ? true : false; } diff --git a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/index.ts b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/index.ts index 16a2fad493..6a22019a0b 100644 --- a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/index.ts +++ b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/index.ts @@ -4,7 +4,6 @@ */ import { - BotFrameworkAdapter, BotFrameworkAdapterSettings, BotTelemetryClient, ConversationState, @@ -18,7 +17,7 @@ import { CosmosDbPartitionedStorageOptions, CosmosDbPartitionedStorage } from 'b import { Dialog } from 'botbuilder-dialogs'; import { - ICognitiveModelConfiguration, + CognitiveModelConfiguration, LocaleTemplateManager } from 'bot-solutions'; import { join } from 'path'; import * as restify from 'restify'; @@ -29,19 +28,19 @@ import * as cognitiveModelsRaw from './cognitivemodels.json'; import { MainDialog } from './dialogs/mainDialog'; import { SampleDialog } from './dialogs/sampleDialog'; import { SampleAction } from './dialogs/sampleAction'; -import { SkillState } from './models/skillState'; +import { SkillState } from './models'; import { BotServices } from './services/botServices'; import { IBotSettings } from './services/botSettings'; -const cognitiveModels: Map = new Map(); +const cognitiveModels: Map = new Map(); const cognitiveModelDictionary: { [key: string]: Object } = cognitiveModelsRaw.cognitiveModels; const cognitiveModelMap: Map = new Map(Object.entries(cognitiveModelDictionary)); cognitiveModelMap.forEach((value: Object, key: string): void => { - cognitiveModels.set(key, value as ICognitiveModelConfiguration); + cognitiveModels.set(key, value as CognitiveModelConfiguration); }); // Load settings -const botSettings: Partial = { +const settings: Partial = { appInsights: appsettings.appInsights, blobStorage: appsettings.blobStorage, cognitiveModels: cognitiveModels, @@ -50,7 +49,7 @@ const botSettings: Partial = { microsoftAppId: appsettings.microsoftAppId, microsoftAppPassword: appsettings.microsoftAppPassword }; -if (botSettings.appInsights === undefined) { +if (settings.appInsights === undefined) { throw new Error('There is no appInsights value in appsettings file'); } @@ -65,20 +64,20 @@ function getTelemetryClient(settings: Partial): BotTelemetryClient } // Configure telemetry -const telemetryClient: BotTelemetryClient = getTelemetryClient(botSettings); +const telemetryClient: BotTelemetryClient = getTelemetryClient(settings); const telemetryLoggerMiddleware: TelemetryLoggerMiddleware = new TelemetryLoggerMiddleware(telemetryClient); const telemetryInitializerMiddleware: TelemetryInitializerMiddleware = new TelemetryInitializerMiddleware(telemetryLoggerMiddleware); -if (botSettings.cosmosDb === undefined) { +if (settings.cosmosDb === undefined) { throw new Error(); } // Configure storage const cosmosDbStorageOptions: CosmosDbPartitionedStorageOptions = { - authKey: botSettings.cosmosDb.authKey, - containerId: botSettings.cosmosDb.containerId, - databaseId: botSettings.cosmosDb.databaseId, - cosmosDbEndpoint: botSettings.cosmosDb.cosmosDbEndpoint + authKey: settings.cosmosDb.authKey, + containerId: settings.cosmosDb.containerId, + databaseId: settings.cosmosDb.databaseId, + cosmosDbEndpoint: settings.cosmosDb.cosmosDbEndpoint }; const storage: CosmosDbPartitionedStorage = new CosmosDbPartitionedStorage(cosmosDbStorageOptions); const userState: UserState = new UserState(storage); @@ -98,52 +97,47 @@ supportedLocales.forEach((locale: string) => { localizedTemplates.set(locale, localTemplateFile); }); -const localeTemplateManager: LocaleTemplateManager = new LocaleTemplateManager(localizedTemplates, botSettings.defaultLocale || 'en-us'); +const localeTemplateManager: LocaleTemplateManager = new LocaleTemplateManager(localizedTemplates, settings.defaultLocale || 'en-us'); const adapterSettings: Partial = { - appId: botSettings.microsoftAppId, - appPassword: botSettings.microsoftAppPassword + appId: settings.microsoftAppId, + appPassword: settings.microsoftAppPassword }; const defaultAdapter: DefaultAdapter = new DefaultAdapter( - botSettings, - adapterSettings, + settings, localeTemplateManager, + conversationState, telemetryInitializerMiddleware, - telemetryClient); - -const adapter: BotFrameworkAdapter = defaultAdapter; + telemetryClient, + adapterSettings); let bot: DefaultActivityHandler; try { // Configure bot services - const botServices: BotServices = new BotServices(botSettings, telemetryClient); + const botServices: BotServices = new BotServices(settings as IBotSettings, telemetryClient); // Register dialogs const sampleDialog: SampleDialog = new SampleDialog( - botSettings, + settings, botServices, stateAccessor, - telemetryClient, localeTemplateManager ); const sampleAction: SampleAction = new SampleAction( - botSettings, + settings, botServices, stateAccessor, - telemetryClient, localeTemplateManager ); const mainDialog: MainDialog = new MainDialog( botServices, - telemetryClient, - stateAccessor, sampleDialog, sampleAction, localeTemplateManager ); - bot = new DefaultActivityHandler(conversationState, userState, localeTemplateManager, mainDialog); + bot = new DefaultActivityHandler(conversationState, userState, localeTemplateManager, telemetryClient, mainDialog); } catch (err) { throw err; } diff --git a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/services/botServices.ts b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/services/botServices.ts index 9ecafefea2..caf963a890 100644 --- a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/services/botServices.ts +++ b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/services/botServices.ts @@ -4,73 +4,81 @@ */ import { BotTelemetryClient } from 'botbuilder'; -import { LuisApplication, LuisPredictionOptions, LuisRecognizer, QnAMaker, QnAMakerEndpoint } from 'botbuilder-ai'; -import { ICognitiveModelConfiguration, ICognitiveModelSet } from 'bot-solutions'; -import { DispatchService, LuisService, QnaMakerService } from 'botframework-config'; +import { + LuisApplication, + LuisRecognizer, + LuisRecognizerOptionsV3, + QnAMaker, + QnAMakerEndpoint +} from 'botbuilder-ai'; +import { CognitiveModelConfiguration, ICognitiveModelSet } from 'bot-solutions'; +import { LuisService, QnaMakerService } from 'botframework-config'; import { IBotSettings } from './botSettings'; export class BotServices { public cognitiveModelSets: Map> = new Map(); - public constructor(settings: Partial, telemetryClient: BotTelemetryClient) { - const luisPredictionOptions: LuisPredictionOptions = { - telemetryClient: telemetryClient, - logPersonalInformation: true - }; + public constructor(settings: IBotSettings, client: BotTelemetryClient) { + settings.cognitiveModels.forEach((value: CognitiveModelConfiguration, key: string): void => { - if (settings.cognitiveModels !== undefined) { - settings.cognitiveModels.forEach((value: ICognitiveModelConfiguration, key: string): void => { + const language: string = key; + const config: CognitiveModelConfiguration = value; - const language: string = key; - const config: ICognitiveModelConfiguration = value; - const cognitiveModelSet: Partial = { - luisServices: new Map() - }; + const telemetryClient: BotTelemetryClient = client; - if (config.dispatchModel !== undefined) { - const dispatchModel: DispatchService = new DispatchService(config.dispatchModel); + const luisOptions: LuisRecognizerOptionsV3 = { + telemetryClient: telemetryClient, + logPersonalInformation: true, + apiVersion: 'v3' + }; - const dispatchApp: LuisApplication = { - applicationId: dispatchModel.appId, - endpointKey: dispatchModel.subscriptionKey, - endpoint: dispatchModel.getEndpoint() - }; + let set: Partial = { + luisServices: new Map(), + qnaConfiguration: new Map(), + qnaServices: new Map() + }; + if (config.dispatchModel !== undefined) { + const dispatchModel: LuisService = new LuisService(config.dispatchModel); + const dispatchApp: LuisApplication = { + applicationId: dispatchModel.appId, + endpointKey: dispatchModel.subscriptionKey, + endpoint: dispatchModel.getEndpoint() + }; - cognitiveModelSet.dispatchService = new LuisRecognizer(dispatchApp, luisPredictionOptions); - } + set.dispatchService= new LuisRecognizer(dispatchApp, luisOptions); + } + + if (config.languageModels !== undefined) { + config.languageModels.forEach((model: LuisService): void => { + const luisModel: LuisService = new LuisService(model); + const luisApp: LuisApplication = { + applicationId: luisModel.appId, + endpointKey: luisModel.subscriptionKey, + endpoint: luisModel.getEndpoint() + }; - if (config.languageModels !== undefined) { - config.languageModels.forEach((model: LuisService): void => { - const luisService: LuisService = new LuisService(model); - const luisApp: LuisApplication = { - applicationId: luisService.appId, - endpointKey: luisService.subscriptionKey, - endpoint: luisService.getEndpoint() - }; - if (cognitiveModelSet.luisServices !== undefined) { - cognitiveModelSet.luisServices.set(luisService.id, new LuisRecognizer(luisApp, luisPredictionOptions)); - } - }); - } + if (set.luisServices !== undefined) { + set.luisServices.set(model.id, new LuisRecognizer(luisApp, luisOptions)); + } + }); + } - if (config.knowledgeBases !== undefined) { - config.knowledgeBases.forEach((kb: QnaMakerService): void => { - const qnaEndpoint: QnAMakerEndpoint = { - knowledgeBaseId: kb.kbId, - endpointKey: kb.endpointKey, - host: kb.hostname - }; - const qnaMaker: QnAMaker = new QnAMaker(qnaEndpoint, undefined, telemetryClient, true); + if (config.knowledgeBases !== undefined) { + config.knowledgeBases.forEach((kb: QnaMakerService): void => { + const qnaEndpoint: QnAMakerEndpoint = { + knowledgeBaseId: kb.kbId, + endpointKey: kb.endpointKey, + host: kb.hostname + }; - if (cognitiveModelSet.qnaServices !== undefined) { - cognitiveModelSet.qnaServices.set(kb.id, qnaMaker); - } - }); - } - this.cognitiveModelSets.set(language, cognitiveModelSet); - }); - } + if (set.qnaServices !== undefined) { + set.qnaServices.set(kb.id, new QnAMaker(qnaEndpoint, undefined, client, true)); + } + }); + } + this.cognitiveModelSets.set(language, set); + }); } public getCognitiveModels(locale: string): Partial { @@ -79,12 +87,7 @@ export class BotServices { if (cognitiveModels === undefined) { const keyFound: string | undefined = Array.from(this.cognitiveModelSets.keys()) - // eslint-disable-next-line @typescript-eslint/explicit-function-return-type - .find((key: string) => { - if (key.substring(0, 2) === locale.substring(0, 2)) { - return key; - } - }); + .find((key: string) => { key.substring(0, 2) === locale.substring(0, 2); }); if (keyFound !== undefined) { cognitiveModels = this.cognitiveModelSets.get(keyFound); } diff --git a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/services/botSettings.ts b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/services/botSettings.ts index 61c6ccd28c..c07e7a19b7 100644 --- a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/services/botSettings.ts +++ b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/services/botSettings.ts @@ -2,9 +2,9 @@ * Copyright(c) Microsoft Corporation.All rights reserved. * Licensed under the MIT License. */ -import { IBotSettingsBase } from 'bot-solutions'; +import { BotSettingsBase } from 'bot-solutions'; // eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface IBotSettings extends IBotSettingsBase { +export interface IBotSettings extends BotSettingsBase { } diff --git a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/test/helpers/skillTestBase.js b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/test/helpers/skillTestBase.js index 5c8286e3c0..cf7e013547 100644 --- a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/test/helpers/skillTestBase.js +++ b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/test/helpers/skillTestBase.js @@ -11,6 +11,7 @@ const { UserState } = require("botbuilder"); const { join } = require("path"); +const { TemplatesParser } = require("botbuilder-lg"); const { ApplicationInsightsTelemetryClient } = require("botbuilder-applicationinsights"); @@ -102,25 +103,21 @@ const initialize = async function() { botSettings, botServices, stateAccessor, - telemetryClient, templateManager ); const sampleAction = new SampleAction( botSettings, botServices, stateAccessor, - telemetryClient, templateManager ); const mainDialog = new MainDialog( botServices, - telemetryClient, - stateAccessor, sampleDialog, sampleAction, templateManager ); - this.bot = new DefaultActivityHandler(conversationState, userState, templateManager, mainDialog); + this.bot = new DefaultActivityHandler(conversationState, userState, templateManager, telemetryClient, mainDialog); }; /** @@ -166,8 +163,12 @@ const getTelemetryClient = function(settings) { return new NullTelemetryClient(); }; -const getTemplates = function(locale, name) { - return templateManager.lgPerLocale.get(locale).expandTemplate(name); +const getTemplates = function(locale, name, data) { + const path = locale === 'en-us' + ? join(__dirname, '..', '..', 'lib', 'responses', 'AllResponses.lg') + : join(__dirname, '..', '..', 'lib', 'responses', `AllResponses.${locale}.lg`) + + return TemplatesParser.parseFile(path).expandTemplate(name, data); }; module.exports = { diff --git a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/test/interruption.test.js b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/test/interruption.test.js index 4783274a52..8c313c32ca 100644 --- a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/test/interruption.test.js +++ b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/test/interruption.test.js @@ -16,9 +16,9 @@ describe("interruption", function() { it("send 'help' during the sample dialog", function(done) { const testAdapter = skillTestBase.getTestAdapter(); const flow = testAdapter - .send("sample dialog") + .send("run sample dialog") .assertReplyOneOf(skillTestBase.getTemplates('en-us','FirstPromptText')) - .send("sample dialog") + .send("run sample dialog") .assertReplyOneOf(skillTestBase.getTemplates('en-us','NamePromptText')) .send("help") .assertReply(function (activity) { @@ -33,9 +33,9 @@ describe("interruption", function() { it("send 'cancel' during the sample dialog", function(done) { const testAdapter = skillTestBase.getTestAdapter(); const flow = testAdapter - .send("sample dialog") + .send("run sample dialog") .assertReplyOneOf(skillTestBase.getTemplates('en-us','FirstPromptText')) - .send("sample dialog") + .send("run sample dialog") .assertReplyOneOf(skillTestBase.getTemplates('en-us','NamePromptText')) .send("cancel") .assertReplyOneOf(skillTestBase.getTemplates('en-us','CancelledText')); diff --git a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/test/mocks/nockFixtures/interruption_cancel_response.json b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/test/mocks/nockFixtures/interruption_cancel_response.json index 8c1cc0a1e9..8670090f20 100644 --- a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/test/mocks/nockFixtures/interruption_cancel_response.json +++ b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/test/mocks/nockFixtures/interruption_cancel_response.json @@ -2,16 +2,25 @@ { "scope": "https://westus.api.cognitive.microsoft.com:443", "method": "POST", - "path": "/luis/v2.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554?verbose=false&staging=false&spellCheck=false&log=true", - "body": "sample dialog", + "path": "/luis/prediction/v3.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554/slots/production/predict?verbose=true&log=true&show-all-intents=false", + "body": { + "query": "run sample dialog", + "options": { + "preferExternalEntities": true + } + }, "status": 200, "response": { - "query": "sample dialog", - "topScoringIntent": { - "intent": "Sample", - "score": 0.9705775 - }, - "entities": [] + "query": "run sample dialog", + "prediction": { + "topIntent": "Sample", + "intents": { + "Sample": { + "score": 0.9705775 + } + }, + "entities": {} + } }, "rawHeaders": [ "Cache-Control", @@ -19,15 +28,15 @@ "Pragma", "no-cache", "Content-Length", - "131", + "116", "Content-Type", "application/json; charset=utf-8", "Apim-Request-Id", - "a894c379-cfec-4b0f-8c4e-42806ff34da0", + "d9155560-6898-4d9b-9ff4-98a34b38cae1", "Request-Id", - "a894c379-cfec-4b0f-8c4e-42806ff34da0", + "d9155560-6898-4d9b-9ff4-98a34b38cae1", "CSP-Billing-Usage", - "CognitiveServices.LUIS.Transaction|1", + "CognitiveServices.LUIS.Transaction=1", "Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload", "X-Content-Type-Options", @@ -35,7 +44,7 @@ "X-Frame-Options", "SAMEORIGIN", "Date", - "Tue, 07 Apr 2020 15:15:21 GMT", + "Thu, 16 Jul 2020 18:21:31 GMT", "Connection", "close" ] @@ -43,16 +52,25 @@ { "scope": "https://westus.api.cognitive.microsoft.com:443", "method": "POST", - "path": "/luis/v2.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554?verbose=false&staging=false&spellCheck=false&log=true", - "body": "sample dialog", + "path": "/luis/prediction/v3.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554/slots/production/predict?verbose=true&log=true&show-all-intents=false", + "body": { + "query": "run sample dialog", + "options": { + "preferExternalEntities": true + } + }, "status": 200, "response": { - "query": "sample dialog", - "topScoringIntent": { - "intent": "Confirm", - "score": 0.12141446 - }, - "entities": [] + "query": "run sample dialog", + "prediction": { + "topIntent": "Confirm", + "intents": { + "Confirm": { + "score": 0.148891255 + } + }, + "entities": {} + } }, "rawHeaders": [ "Cache-Control", @@ -60,15 +78,15 @@ "Pragma", "no-cache", "Content-Length", - "133", + "120", "Content-Type", "application/json; charset=utf-8", "Apim-Request-Id", - "3f40e459-6baa-4812-a2ec-0f1504a2785c", + "390e15ac-6a40-4b10-a909-16d19051e30e", "Request-Id", - "3f40e459-6baa-4812-a2ec-0f1504a2785c", + "390e15ac-6a40-4b10-a909-16d19051e30e", "CSP-Billing-Usage", - "CognitiveServices.LUIS.Transaction|1", + "CognitiveServices.LUIS.Transaction=1", "Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload", "X-Content-Type-Options", @@ -76,7 +94,7 @@ "X-Frame-Options", "SAMEORIGIN", "Date", - "Tue, 07 Apr 2020 15:15:21 GMT", + "Thu, 16 Jul 2020 18:21:32 GMT", "Connection", "close" ] @@ -84,16 +102,25 @@ { "scope": "https://westus.api.cognitive.microsoft.com:443", "method": "POST", - "path": "/luis/v2.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554?verbose=false&staging=false&spellCheck=false&log=true", - "body": "sample dialog", + "path": "/luis/prediction/v3.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554/slots/production/predict?verbose=true&log=true&show-all-intents=false", + "body": { + "query": "run sample dialog", + "options": { + "preferExternalEntities": true + } + }, "status": 200, "response": { - "query": "sample dialog", - "topScoringIntent": { - "intent": "Sample", - "score": 0.9705775 - }, - "entities": [] + "query": "run sample dialog", + "prediction": { + "topIntent": "Sample", + "intents": { + "Sample": { + "score": 0.9705775 + } + }, + "entities": {} + } }, "rawHeaders": [ "Cache-Control", @@ -101,15 +128,15 @@ "Pragma", "no-cache", "Content-Length", - "131", + "116", "Content-Type", "application/json; charset=utf-8", "Apim-Request-Id", - "8621a3e9-54df-41bc-8970-ae5da208d7e6", + "539dd476-9f3d-421c-ae44-70f9e0674b2b", "Request-Id", - "8621a3e9-54df-41bc-8970-ae5da208d7e6", + "539dd476-9f3d-421c-ae44-70f9e0674b2b", "CSP-Billing-Usage", - "CognitiveServices.LUIS.Transaction|1", + "CognitiveServices.LUIS.Transaction=1", "Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload", "X-Content-Type-Options", @@ -117,7 +144,7 @@ "X-Frame-Options", "SAMEORIGIN", "Date", - "Tue, 07 Apr 2020 15:15:22 GMT", + "Thu, 16 Jul 2020 18:21:33 GMT", "Connection", "close" ] @@ -125,16 +152,25 @@ { "scope": "https://westus.api.cognitive.microsoft.com:443", "method": "POST", - "path": "/luis/v2.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554?verbose=false&staging=false&spellCheck=false&log=true", - "body": "sample dialog", + "path": "/luis/prediction/v3.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554/slots/production/predict?verbose=true&log=true&show-all-intents=false", + "body": { + "query": "run sample dialog", + "options": { + "preferExternalEntities": true + } + }, "status": 200, "response": { - "query": "sample dialog", - "topScoringIntent": { - "intent": "Confirm", - "score": 0.12141446 - }, - "entities": [] + "query": "run sample dialog", + "prediction": { + "topIntent": "Confirm", + "intents": { + "Confirm": { + "score": 0.148891255 + } + }, + "entities": {} + } }, "rawHeaders": [ "Cache-Control", @@ -142,15 +178,15 @@ "Pragma", "no-cache", "Content-Length", - "133", + "120", "Content-Type", "application/json; charset=utf-8", "Apim-Request-Id", - "dda572b9-f94a-4168-a471-3f54f07fff7c", + "26a36063-fab8-4228-9e40-8a72978a038f", "Request-Id", - "dda572b9-f94a-4168-a471-3f54f07fff7c", + "26a36063-fab8-4228-9e40-8a72978a038f", "CSP-Billing-Usage", - "CognitiveServices.LUIS.Transaction|1", + "CognitiveServices.LUIS.Transaction=1", "Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload", "X-Content-Type-Options", @@ -158,7 +194,7 @@ "X-Frame-Options", "SAMEORIGIN", "Date", - "Tue, 07 Apr 2020 15:15:23 GMT", + "Thu, 16 Jul 2020 18:21:34 GMT", "Connection", "close" ] @@ -166,16 +202,25 @@ { "scope": "https://westus.api.cognitive.microsoft.com:443", "method": "POST", - "path": "/luis/v2.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554?verbose=false&staging=false&spellCheck=false&log=true", - "body": "cancel", + "path": "/luis/prediction/v3.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554/slots/production/predict?verbose=true&log=true&show-all-intents=false", + "body": { + "query": "cancel", + "options": { + "preferExternalEntities": true + } + }, "status": 200, "response": { "query": "cancel", - "topScoringIntent": { - "intent": "None", - "score": 0.873317 - }, - "entities": [] + "prediction": { + "topIntent": "None", + "intents": { + "None": { + "score": 0.873317 + } + }, + "entities": {} + } }, "rawHeaders": [ "Cache-Control", @@ -183,15 +228,15 @@ "Pragma", "no-cache", "Content-Length", - "121", + "104", "Content-Type", "application/json; charset=utf-8", "Apim-Request-Id", - "7f6ce299-a76d-4648-92c2-733ee9c1b5f6", + "1a93915c-061f-47c8-8b95-2d039a224427", "Request-Id", - "7f6ce299-a76d-4648-92c2-733ee9c1b5f6", + "1a93915c-061f-47c8-8b95-2d039a224427", "CSP-Billing-Usage", - "CognitiveServices.LUIS.Transaction|1", + "CognitiveServices.LUIS.Transaction=1", "Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload", "X-Content-Type-Options", @@ -199,7 +244,7 @@ "X-Frame-Options", "SAMEORIGIN", "Date", - "Tue, 07 Apr 2020 15:15:24 GMT", + "Thu, 16 Jul 2020 18:21:34 GMT", "Connection", "close" ] @@ -207,16 +252,25 @@ { "scope": "https://westus.api.cognitive.microsoft.com:443", "method": "POST", - "path": "/luis/v2.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554?verbose=false&staging=false&spellCheck=false&log=true", - "body": "cancel", + "path": "/luis/prediction/v3.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554/slots/production/predict?verbose=true&log=true&show-all-intents=false", + "body": { + "query": "cancel", + "options": { + "preferExternalEntities": true + } + }, "status": 200, "response": { "query": "cancel", - "topScoringIntent": { - "intent": "Cancel", - "score": 0.9978573 - }, - "entities": [] + "prediction": { + "topIntent": "Cancel", + "intents": { + "Cancel": { + "score": 0.9978573 + } + }, + "entities": {} + } }, "rawHeaders": [ "Cache-Control", @@ -224,15 +278,15 @@ "Pragma", "no-cache", "Content-Length", - "124", + "109", "Content-Type", "application/json; charset=utf-8", "Apim-Request-Id", - "9ebf28b2-785b-442e-bd5a-c26f9c5f88e9", + "e468b79a-3e1e-4b11-b16f-fae3e919163e", "Request-Id", - "9ebf28b2-785b-442e-bd5a-c26f9c5f88e9", + "e468b79a-3e1e-4b11-b16f-fae3e919163e", "CSP-Billing-Usage", - "CognitiveServices.LUIS.Transaction|1", + "CognitiveServices.LUIS.Transaction=1", "Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload", "X-Content-Type-Options", @@ -240,7 +294,7 @@ "X-Frame-Options", "SAMEORIGIN", "Date", - "Tue, 07 Apr 2020 15:15:24 GMT", + "Thu, 16 Jul 2020 18:21:36 GMT", "Connection", "close" ] diff --git a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/test/mocks/nockFixtures/interruption_help_response.json b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/test/mocks/nockFixtures/interruption_help_response.json index edb3beb316..63c695e8ab 100644 --- a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/test/mocks/nockFixtures/interruption_help_response.json +++ b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/test/mocks/nockFixtures/interruption_help_response.json @@ -1,47 +1,26 @@ [ - { - "scope": "https://dc.services.visualstudio.com:443", - "method": "GET", - "path": "/api/profiles/f7c2ee78-8679-4a3e-b384-0cd10c67e554/appId", - "body": "", - "status": 200, - "response": "6b757982-4de3-4003-b373-49821deabe2a", - "rawHeaders": [ - "Content-Type", - "text/plain", - "x-ms-session-id", - "0BEF36A2-4A13-4D0C-9C48-C387F85C03BD", - "Strict-Transport-Security", - "max-age=31536000", - "Access-Control-Allow-Headers", - "Origin, X-Requested-With, Content-Name, Content-Type, Accept, Sdk-Context", - "Access-Control-Allow-Origin", - "*", - "Access-Control-Max-Age", - "3600", - "X-Content-Type-Options", - "nosniff", - "Date", - "Tue, 07 Apr 2020 15:15:16 GMT", - "Connection", - "close", - "Content-Length", - "36" - ] - }, { "scope": "https://westus.api.cognitive.microsoft.com:443", "method": "POST", - "path": "/luis/v2.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554?verbose=false&staging=false&spellCheck=false&log=true", - "body": "sample dialog", + "path": "/luis/prediction/v3.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554/slots/production/predict?verbose=true&log=true&show-all-intents=false", + "body": { + "query": "run sample dialog", + "options": { + "preferExternalEntities": true + } + }, "status": 200, "response": { - "query": "sample dialog", - "topScoringIntent": { - "intent": "Sample", - "score": 0.9705775 - }, - "entities": [] + "query": "run sample dialog", + "prediction": { + "topIntent": "Sample", + "intents": { + "Sample": { + "score": 0.9750285 + } + }, + "entities": {} + } }, "rawHeaders": [ "Cache-Control", @@ -49,15 +28,15 @@ "Pragma", "no-cache", "Content-Length", - "131", + "120", "Content-Type", "application/json; charset=utf-8", "Apim-Request-Id", - "97aefb89-2819-4b04-a981-c880e2010f46", + "a3e0b6ac-5171-47f7-a1fd-ddb69f01f8a0", "Request-Id", - "97aefb89-2819-4b04-a981-c880e2010f46", + "a3e0b6ac-5171-47f7-a1fd-ddb69f01f8a0", "CSP-Billing-Usage", - "CognitiveServices.LUIS.Transaction|1", + "CognitiveServices.LUIS.Transaction=1", "Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload", "X-Content-Type-Options", @@ -65,7 +44,7 @@ "X-Frame-Options", "SAMEORIGIN", "Date", - "Tue, 07 Apr 2020 15:15:17 GMT", + "Thu, 16 Jul 2020 18:21:27 GMT", "Connection", "close" ] @@ -73,16 +52,25 @@ { "scope": "https://westus.api.cognitive.microsoft.com:443", "method": "POST", - "path": "/luis/v2.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554?verbose=false&staging=false&spellCheck=false&log=true", - "body": "sample dialog", + "path": "/luis/prediction/v3.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554/slots/production/predict?verbose=true&log=true&show-all-intents=false", + "body": { + "query": "run sample dialog", + "options": { + "preferExternalEntities": true + } + }, "status": 200, "response": { - "query": "sample dialog", - "topScoringIntent": { - "intent": "Confirm", - "score": 0.12141446 - }, - "entities": [] + "query": "run sample dialog", + "prediction": { + "topIntent": "Confirm", + "intents": { + "Confirm": { + "score": 0.061984323 + } + }, + "entities": {} + } }, "rawHeaders": [ "Cache-Control", @@ -90,15 +78,15 @@ "Pragma", "no-cache", "Content-Length", - "133", + "124", "Content-Type", "application/json; charset=utf-8", "Apim-Request-Id", - "6a76c7a8-259a-4c3c-80e7-33e16b5a2d07", + "8796a5af-9627-4304-b3fb-55bdbcb72587", "Request-Id", - "6a76c7a8-259a-4c3c-80e7-33e16b5a2d07", + "8796a5af-9627-4304-b3fb-55bdbcb72587", "CSP-Billing-Usage", - "CognitiveServices.LUIS.Transaction|1", + "CognitiveServices.LUIS.Transaction=1", "Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload", "X-Content-Type-Options", @@ -106,7 +94,7 @@ "X-Frame-Options", "SAMEORIGIN", "Date", - "Tue, 07 Apr 2020 15:15:17 GMT", + "Thu, 16 Jul 2020 18:21:28 GMT", "Connection", "close" ] @@ -114,16 +102,25 @@ { "scope": "https://westus.api.cognitive.microsoft.com:443", "method": "POST", - "path": "/luis/v2.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554?verbose=false&staging=false&spellCheck=false&log=true", - "body": "sample dialog", + "path": "/luis/prediction/v3.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554/slots/production/predict?verbose=true&log=true&show-all-intents=false", + "body": { + "query": "run sample dialog", + "options": { + "preferExternalEntities": true + } + }, "status": 200, "response": { - "query": "sample dialog", - "topScoringIntent": { - "intent": "Sample", - "score": 0.9705775 - }, - "entities": [] + "query": "run sample dialog", + "prediction": { + "topIntent": "Sample", + "intents": { + "Sample": { + "score": 0.9750285 + } + }, + "entities": {} + } }, "rawHeaders": [ "Cache-Control", @@ -131,15 +128,15 @@ "Pragma", "no-cache", "Content-Length", - "131", + "120", "Content-Type", "application/json; charset=utf-8", "Apim-Request-Id", - "05dccbd7-55f9-4860-a88c-95d60e30b320", + "25ff97a1-5b45-4f5c-a99b-23c8bd3c3435", "Request-Id", - "05dccbd7-55f9-4860-a88c-95d60e30b320", + "25ff97a1-5b45-4f5c-a99b-23c8bd3c3435", "CSP-Billing-Usage", - "CognitiveServices.LUIS.Transaction|1", + "CognitiveServices.LUIS.Transaction=1", "Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload", "X-Content-Type-Options", @@ -147,7 +144,7 @@ "X-Frame-Options", "SAMEORIGIN", "Date", - "Tue, 07 Apr 2020 15:15:18 GMT", + "Thu, 16 Jul 2020 18:21:29 GMT", "Connection", "close" ] @@ -155,16 +152,25 @@ { "scope": "https://westus.api.cognitive.microsoft.com:443", "method": "POST", - "path": "/luis/v2.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554?verbose=false&staging=false&spellCheck=false&log=true", - "body": "sample dialog", + "path": "/luis/prediction/v3.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554/slots/production/predict?verbose=true&log=true&show-all-intents=false", + "body": { + "query": "run sample dialog", + "options": { + "preferExternalEntities": true + } + }, "status": 200, "response": { - "query": "sample dialog", - "topScoringIntent": { - "intent": "Confirm", - "score": 0.12141446 - }, - "entities": [] + "query": "run sample dialog", + "prediction": { + "topIntent": "Confirm", + "intents": { + "Confirm": { + "score": 0.061984323 + } + }, + "entities": {} + } }, "rawHeaders": [ "Cache-Control", @@ -172,15 +178,15 @@ "Pragma", "no-cache", "Content-Length", - "133", + "124", "Content-Type", "application/json; charset=utf-8", "Apim-Request-Id", - "f110c39d-efc5-4447-9f42-70941fcc885e", + "099f4182-7bfb-43d1-9f50-002c87541729", "Request-Id", - "f110c39d-efc5-4447-9f42-70941fcc885e", + "099f4182-7bfb-43d1-9f50-002c87541729", "CSP-Billing-Usage", - "CognitiveServices.LUIS.Transaction|1", + "CognitiveServices.LUIS.Transaction=1", "Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload", "X-Content-Type-Options", @@ -188,7 +194,7 @@ "X-Frame-Options", "SAMEORIGIN", "Date", - "Tue, 07 Apr 2020 15:15:18 GMT", + "Thu, 16 Jul 2020 18:21:30 GMT", "Connection", "close" ] @@ -196,16 +202,25 @@ { "scope": "https://westus.api.cognitive.microsoft.com:443", "method": "POST", - "path": "/luis/v2.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554?verbose=false&staging=false&spellCheck=false&log=true", - "body": "help", + "path": "/luis/prediction/v3.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554/slots/production/predict?verbose=true&log=true&show-all-intents=false", + "body": { + "query": "help", + "options": { + "preferExternalEntities": true + } + }, "status": 200, "response": { "query": "help", - "topScoringIntent": { - "intent": "None", - "score": 0.873317 - }, - "entities": [] + "prediction": { + "topIntent": "None", + "intents": { + "None": { + "score": 0.873317 + } + }, + "entities": {} + } }, "rawHeaders": [ "Cache-Control", @@ -213,15 +228,15 @@ "Pragma", "no-cache", "Content-Length", - "119", + "102", "Content-Type", "application/json; charset=utf-8", "Apim-Request-Id", - "c24f8385-f433-472f-897c-daa568b6e49b", + "b4b7e80b-92ba-49ce-afac-5b36a7af61d0", "Request-Id", - "c24f8385-f433-472f-897c-daa568b6e49b", + "b4b7e80b-92ba-49ce-afac-5b36a7af61d0", "CSP-Billing-Usage", - "CognitiveServices.LUIS.Transaction|1", + "CognitiveServices.LUIS.Transaction=1", "Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload", "X-Content-Type-Options", @@ -229,7 +244,7 @@ "X-Frame-Options", "SAMEORIGIN", "Date", - "Tue, 07 Apr 2020 15:15:20 GMT", + "Thu, 16 Jul 2020 18:21:30 GMT", "Connection", "close" ] @@ -237,16 +252,25 @@ { "scope": "https://westus.api.cognitive.microsoft.com:443", "method": "POST", - "path": "/luis/v2.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554?verbose=false&staging=false&spellCheck=false&log=true", - "body": "help", + "path": "/luis/prediction/v3.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554/slots/production/predict?verbose=true&log=true&show-all-intents=false", + "body": { + "query": "help", + "options": { + "preferExternalEntities": true + } + }, "status": 200, "response": { "query": "help", - "topScoringIntent": { - "intent": "Help", - "score": 0.9882712 - }, - "entities": [] + "prediction": { + "topIntent": "Help", + "intents": { + "Help": { + "score": 0.9895731 + } + }, + "entities": {} + } }, "rawHeaders": [ "Cache-Control", @@ -254,15 +278,15 @@ "Pragma", "no-cache", "Content-Length", - "120", + "103", "Content-Type", "application/json; charset=utf-8", "Apim-Request-Id", - "8ffdfce3-b4d1-41b0-8ea6-8defc97e25b2", + "7f86c6d4-1d48-4bbd-83c6-769ccfd83a1b", "Request-Id", - "8ffdfce3-b4d1-41b0-8ea6-8defc97e25b2", + "7f86c6d4-1d48-4bbd-83c6-769ccfd83a1b", "CSP-Billing-Usage", - "CognitiveServices.LUIS.Transaction|1", + "CognitiveServices.LUIS.Transaction=1", "Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload", "X-Content-Type-Options", @@ -270,7 +294,7 @@ "X-Frame-Options", "SAMEORIGIN", "Date", - "Tue, 07 Apr 2020 15:15:20 GMT", + "Thu, 16 Jul 2020 18:21:31 GMT", "Connection", "close" ] diff --git a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/test/mocks/nockFixtures/mainDialog_help_response.json b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/test/mocks/nockFixtures/mainDialog_help_response.json index 803fb31a7e..383e37d2bd 100644 --- a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/test/mocks/nockFixtures/mainDialog_help_response.json +++ b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/test/mocks/nockFixtures/mainDialog_help_response.json @@ -2,16 +2,25 @@ { "scope": "https://westus.api.cognitive.microsoft.com:443", "method": "POST", - "path": "/luis/v2.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554?verbose=false&staging=false&spellCheck=false&log=true", - "body": "help", + "path": "/luis/prediction/v3.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554/slots/production/predict?verbose=true&log=true&show-all-intents=false", + "body": { + "query": "help", + "options": { + "preferExternalEntities": true + } + }, "status": 200, "response": { "query": "help", - "topScoringIntent": { - "intent": "None", - "score": 0.873317 - }, - "entities": [] + "prediction": { + "topIntent": "None", + "intents": { + "None": { + "score": 0.873317 + } + }, + "entities": {} + } }, "rawHeaders": [ "Cache-Control", @@ -19,15 +28,15 @@ "Pragma", "no-cache", "Content-Length", - "119", + "102", "Content-Type", "application/json; charset=utf-8", "Apim-Request-Id", - "c65270f7-f705-4921-a3c2-876984f7eeaa", + "767f65bd-23ba-4fc4-9564-66d610c17a81", "Request-Id", - "c65270f7-f705-4921-a3c2-876984f7eeaa", + "767f65bd-23ba-4fc4-9564-66d610c17a81", "CSP-Billing-Usage", - "CognitiveServices.LUIS.Transaction|1", + "CognitiveServices.LUIS.Transaction=1", "Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload", "X-Content-Type-Options", @@ -35,7 +44,7 @@ "X-Frame-Options", "SAMEORIGIN", "Date", - "Tue, 07 Apr 2020 15:15:26 GMT", + "Thu, 16 Jul 2020 18:23:43 GMT", "Connection", "close" ] @@ -43,16 +52,25 @@ { "scope": "https://westus.api.cognitive.microsoft.com:443", "method": "POST", - "path": "/luis/v2.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554?verbose=false&staging=false&spellCheck=false&log=true", - "body": "help", + "path": "/luis/prediction/v3.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554/slots/production/predict?verbose=true&log=true&show-all-intents=false", + "body": { + "query": "help", + "options": { + "preferExternalEntities": true + } + }, "status": 200, "response": { "query": "help", - "topScoringIntent": { - "intent": "Help", - "score": 0.9882712 - }, - "entities": [] + "prediction": { + "topIntent": "Help", + "intents": { + "Help": { + "score": 0.9895731 + } + }, + "entities": {} + } }, "rawHeaders": [ "Cache-Control", @@ -60,15 +78,15 @@ "Pragma", "no-cache", "Content-Length", - "120", + "103", "Content-Type", "application/json; charset=utf-8", "Apim-Request-Id", - "9faca270-9610-4c1c-9646-fa9010760c89", + "c8558b3d-ce58-4ac1-9b4e-c8bd74658d03", "Request-Id", - "9faca270-9610-4c1c-9646-fa9010760c89", + "c8558b3d-ce58-4ac1-9b4e-c8bd74658d03", "CSP-Billing-Usage", - "CognitiveServices.LUIS.Transaction|1", + "CognitiveServices.LUIS.Transaction=1", "Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload", "X-Content-Type-Options", @@ -76,7 +94,7 @@ "X-Frame-Options", "SAMEORIGIN", "Date", - "Tue, 07 Apr 2020 15:15:26 GMT", + "Thu, 16 Jul 2020 18:23:44 GMT", "Connection", "close" ] diff --git a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/test/mocks/nockFixtures/mainDialog_unhandled_response.json b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/test/mocks/nockFixtures/mainDialog_unhandled_response.json index 660a3804f3..9803541ba7 100644 --- a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/test/mocks/nockFixtures/mainDialog_unhandled_response.json +++ b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/test/mocks/nockFixtures/mainDialog_unhandled_response.json @@ -2,16 +2,25 @@ { "scope": "https://westus.api.cognitive.microsoft.com:443", "method": "POST", - "path": "/luis/v2.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554?verbose=false&staging=false&spellCheck=false&log=true", - "body": "sample dialog", + "path": "/luis/prediction/v3.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554/slots/production/predict?verbose=true&log=true&show-all-intents=false", + "body": { + "query": "sample dialog", + "options": { + "preferExternalEntities": true + } + }, "status": 200, "response": { "query": "sample dialog", - "topScoringIntent": { - "intent": "Sample", - "score": 0.9705775 - }, - "entities": [] + "prediction": { + "topIntent": "Sample", + "intents": { + "Sample": { + "score": 0.9705775 + } + }, + "entities": {} + } }, "rawHeaders": [ "Cache-Control", @@ -19,15 +28,15 @@ "Pragma", "no-cache", "Content-Length", - "131", + "116", "Content-Type", "application/json; charset=utf-8", "Apim-Request-Id", - "60b1ca77-38b9-420e-b72f-cfa30a10194a", + "5f5dd332-b971-41fe-9cd3-5ea9a43b0a3f", "Request-Id", - "60b1ca77-38b9-420e-b72f-cfa30a10194a", + "5f5dd332-b971-41fe-9cd3-5ea9a43b0a3f", "CSP-Billing-Usage", - "CognitiveServices.LUIS.Transaction|1", + "CognitiveServices.LUIS.Transaction=1", "Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload", "X-Content-Type-Options", @@ -35,7 +44,7 @@ "X-Frame-Options", "SAMEORIGIN", "Date", - "Tue, 07 Apr 2020 15:15:27 GMT", + "Thu, 16 Jul 2020 18:23:45 GMT", "Connection", "close" ] @@ -43,16 +52,25 @@ { "scope": "https://westus.api.cognitive.microsoft.com:443", "method": "POST", - "path": "/luis/v2.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554?verbose=false&staging=false&spellCheck=false&log=true", - "body": "sample dialog", + "path": "/luis/prediction/v3.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554/slots/production/predict?verbose=true&log=true&show-all-intents=false", + "body": { + "query": "sample dialog", + "options": { + "preferExternalEntities": true + } + }, "status": 200, "response": { "query": "sample dialog", - "topScoringIntent": { - "intent": "Confirm", - "score": 0.12141446 - }, - "entities": [] + "prediction": { + "topIntent": "Confirm", + "intents": { + "Confirm": { + "score": 0.148891255 + } + }, + "entities": {} + } }, "rawHeaders": [ "Cache-Control", @@ -60,15 +78,15 @@ "Pragma", "no-cache", "Content-Length", - "133", + "120", "Content-Type", "application/json; charset=utf-8", "Apim-Request-Id", - "797f1506-ab96-49cf-8e59-126ca1539b71", + "e5d44eb9-a07a-44b2-87a9-f9d82239dc13", "Request-Id", - "797f1506-ab96-49cf-8e59-126ca1539b71", + "e5d44eb9-a07a-44b2-87a9-f9d82239dc13", "CSP-Billing-Usage", - "CognitiveServices.LUIS.Transaction|1", + "CognitiveServices.LUIS.Transaction=1", "Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload", "X-Content-Type-Options", @@ -76,7 +94,7 @@ "X-Frame-Options", "SAMEORIGIN", "Date", - "Tue, 07 Apr 2020 15:15:27 GMT", + "Thu, 16 Jul 2020 18:23:45 GMT", "Connection", "close" ] @@ -84,16 +102,25 @@ { "scope": "https://westus.api.cognitive.microsoft.com:443", "method": "POST", - "path": "/luis/v2.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554?verbose=false&staging=false&spellCheck=false&log=true", - "body": "Unhandled message", + "path": "/luis/prediction/v3.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554/slots/production/predict?verbose=true&log=true&show-all-intents=false", + "body": { + "query": "Unhandled message", + "options": { + "preferExternalEntities": true + } + }, "status": 200, "response": { "query": "Unhandled message", - "topScoringIntent": { - "intent": "None", - "score": 0.833009 - }, - "entities": [] + "prediction": { + "topIntent": "None", + "intents": { + "None": { + "score": 0.833009 + } + }, + "entities": {} + } }, "rawHeaders": [ "Cache-Control", @@ -101,15 +128,15 @@ "Pragma", "no-cache", "Content-Length", - "132", + "115", "Content-Type", "application/json; charset=utf-8", "Apim-Request-Id", - "3d3e9d15-5edc-48b3-96cf-5d16ff349c73", + "8773612c-2273-4762-9b39-0c6dca4d2397", "Request-Id", - "3d3e9d15-5edc-48b3-96cf-5d16ff349c73", + "8773612c-2273-4762-9b39-0c6dca4d2397", "CSP-Billing-Usage", - "CognitiveServices.LUIS.Transaction|1", + "CognitiveServices.LUIS.Transaction=1", "Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload", "X-Content-Type-Options", @@ -117,7 +144,7 @@ "X-Frame-Options", "SAMEORIGIN", "Date", - "Tue, 07 Apr 2020 15:15:28 GMT", + "Thu, 16 Jul 2020 18:23:46 GMT", "Connection", "close" ] @@ -125,16 +152,25 @@ { "scope": "https://westus.api.cognitive.microsoft.com:443", "method": "POST", - "path": "/luis/v2.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554?verbose=false&staging=false&spellCheck=false&log=true", - "body": "Unhandled message", + "path": "/luis/prediction/v3.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554/slots/production/predict?verbose=true&log=true&show-all-intents=false", + "body": { + "query": "Unhandled message", + "options": { + "preferExternalEntities": true + } + }, "status": 200, "response": { "query": "Unhandled message", - "topScoringIntent": { - "intent": "Confirm", - "score": 0.12141446 - }, - "entities": [] + "prediction": { + "topIntent": "Confirm", + "intents": { + "Confirm": { + "score": 0.148891255 + } + }, + "entities": {} + } }, "rawHeaders": [ "Cache-Control", @@ -142,15 +178,15 @@ "Pragma", "no-cache", "Content-Length", - "137", + "124", "Content-Type", "application/json; charset=utf-8", "Apim-Request-Id", - "bac86884-fc71-44b0-9a02-0545ed9afb64", + "bc3a75d7-1823-480b-b4a2-3acf12f4f74d", "Request-Id", - "bac86884-fc71-44b0-9a02-0545ed9afb64", + "bc3a75d7-1823-480b-b4a2-3acf12f4f74d", "CSP-Billing-Usage", - "CognitiveServices.LUIS.Transaction|1", + "CognitiveServices.LUIS.Transaction=1", "Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload", "X-Content-Type-Options", @@ -158,7 +194,7 @@ "X-Frame-Options", "SAMEORIGIN", "Date", - "Tue, 07 Apr 2020 15:15:29 GMT", + "Thu, 16 Jul 2020 18:23:46 GMT", "Connection", "close" ] diff --git a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/test/mocks/nockFixtures/sampleDialog_response.json b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/test/mocks/nockFixtures/sampleDialog_response.json index 7bc4485f0c..5df5b8c966 100644 --- a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/test/mocks/nockFixtures/sampleDialog_response.json +++ b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/test/mocks/nockFixtures/sampleDialog_response.json @@ -2,16 +2,25 @@ { "scope": "https://westus.api.cognitive.microsoft.com:443", "method": "POST", - "path": "/luis/v2.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554?verbose=false&staging=false&spellCheck=false&log=true", - "body": "sample dialog", + "path": "/luis/prediction/v3.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554/slots/production/predict?verbose=true&log=true&show-all-intents=false", + "body": { + "query": "sample dialog", + "options": { + "preferExternalEntities": true + } + }, "status": 200, "response": { "query": "sample dialog", - "topScoringIntent": { - "intent": "Sample", - "score": 0.9705775 - }, - "entities": [] + "prediction": { + "topIntent": "Sample", + "intents": { + "Sample": { + "score": 0.9705775 + } + }, + "entities": {} + } }, "rawHeaders": [ "Cache-Control", @@ -19,15 +28,15 @@ "Pragma", "no-cache", "Content-Length", - "131", + "116", "Content-Type", "application/json; charset=utf-8", "Apim-Request-Id", - "aa0d5d59-a4a7-4278-a2e2-dfe73fdb9273", + "f2c7cf8f-7c7b-4e78-8cb2-9bf5706a7eba", "Request-Id", - "aa0d5d59-a4a7-4278-a2e2-dfe73fdb9273", + "f2c7cf8f-7c7b-4e78-8cb2-9bf5706a7eba", "CSP-Billing-Usage", - "CognitiveServices.LUIS.Transaction|1", + "CognitiveServices.LUIS.Transaction=1", "Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload", "X-Content-Type-Options", @@ -35,7 +44,7 @@ "X-Frame-Options", "SAMEORIGIN", "Date", - "Tue, 07 Apr 2020 15:15:30 GMT", + "Thu, 16 Jul 2020 18:23:48 GMT", "Connection", "close" ] @@ -43,16 +52,25 @@ { "scope": "https://westus.api.cognitive.microsoft.com:443", "method": "POST", - "path": "/luis/v2.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554?verbose=false&staging=false&spellCheck=false&log=true", - "body": "sample dialog", + "path": "/luis/prediction/v3.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554/slots/production/predict?verbose=true&log=true&show-all-intents=false", + "body": { + "query": "sample dialog", + "options": { + "preferExternalEntities": true + } + }, "status": 200, "response": { "query": "sample dialog", - "topScoringIntent": { - "intent": "Confirm", - "score": 0.12141446 - }, - "entities": [] + "prediction": { + "topIntent": "Confirm", + "intents": { + "Confirm": { + "score": 0.148891255 + } + }, + "entities": {} + } }, "rawHeaders": [ "Cache-Control", @@ -60,15 +78,15 @@ "Pragma", "no-cache", "Content-Length", - "133", + "120", "Content-Type", "application/json; charset=utf-8", "Apim-Request-Id", - "489fec91-4487-49ea-adda-261431361f8c", + "4122a658-7a51-4b8f-87df-32acb24373c1", "Request-Id", - "489fec91-4487-49ea-adda-261431361f8c", + "4122a658-7a51-4b8f-87df-32acb24373c1", "CSP-Billing-Usage", - "CognitiveServices.LUIS.Transaction|1", + "CognitiveServices.LUIS.Transaction=1", "Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload", "X-Content-Type-Options", @@ -76,58 +94,33 @@ "X-Frame-Options", "SAMEORIGIN", "Date", - "Tue, 07 Apr 2020 15:15:31 GMT", + "Thu, 16 Jul 2020 18:23:48 GMT", "Connection", "close" ] }, - { - "scope": "https://dc.services.visualstudio.com:443", - "method": "POST", - "path": "/v2/track", - "body": "1f8b080000000000000aed9d5d8fdd3819c7eff914e608696fc6911d27b1d31b346d818eb66fb4b354422b212776e684c949ce2639333bad2aed0217850b04574815880509092484b842bcec6a25f6abb465eff62b60e74cdbe9ccb4fb329d3db1cf23556d272f3e39c96ffe7efecf63c7f7267bba9d5ca01b934ecee695be257b6d7e246463d2cb9d6e72e1de4496819ccfab32977dd9d4c170fc84062420930dbb53e9bd32d741a9cce6e596bc6a162a689b4a6fd55d2febdc3439b97671737b7bf37b57b7aedfc057376f6edfb8f9c2e94df703dd76e603cca177ca5a35fbdd8fae6f236a3e26a08225ec78d3f6389d1d6b63b3cda765aff37ed1da03de4da26307dcac645f34edccecdc2f6b162e779775afdb5a5641a7769f5f46dd287d8106a1f9a2f737264af6d2de8e4c767afb606e9bffce9eaefbcb76fbc6b0f9f2e121c32d0a3726f3b699ebb62ff5701f8bb6996dd99bb4e8ccfe8d49ded4e6c06eb8abd7e54c2f6f5fd5e4b23afc7fabf3725e9acf184ecb9afee8b6c3532e0e5b6ddb871bde32ad53b3a9d7eff6e6c7e56345aa9455b363bf47fdecbc6bbaebe48ebea5735dee6935b96ff6966fea03b357c559182a95632299c0912c429c164ce13c298aacd011a7ca3e90c3b6ae9579db744dd1079bcf41318fbedc99f65df0b42ddb946dc93674b49d60b88df68acba1b5908404930813be4de30bf64f121092fe7072ff1bf780d6af8bd6233771a02fd692c689c8704c0a8d232515964c094c15177991ca4c09dbb0bdb6da72777b7840cfb6dcce9be13b9220e524e63c3e84f6e82f8439ac5c7efce4dedb936f95874fe36d7339f7ef9bfdef2c74d72fbfeccba8beba28bb5bba5b54fd7869e6411cc640f3d74a73abe7d5c166de977b657f3030474ee8eb9797e51714f73469bdadeb11cbaa055100882b95d5229419cb688e6359c438a2b9c0599a8498132ed23ccd898ec95159bdd4d44569aefca4aed29046348a92f51556118411039e415801c4f503f1f2a058036fd764592f7f34673ebd47c39ed03c59c1788ccda354b84808c52c27028761aab82211cfe851deee98c7d516b2aa6ef7b205e103dece85b78dc9ed5ecf0f252f6b16b542e61bb48ddd7a3a8c76fb98598c8045df3ae167f9a43b53d9a35cd6680b4d75354707cd02ed97fd14f58d9207df76b4b7e6402ce4429dc8855a5ac1b4432ed417cb9e32c885ae3a5a08c1b25b102108805ca82fc29a0609879400082b80b886209e6b6eaa6d16bd763337655984dcd4ca585cdaa0d369644596d298709cc729c5112b52ac6466030059c84c878a51e960661e88739bb853f4cf7cd86cde7fb76987ada08140e41802c317f3f36567f3f22db24cb99892b790425a681d52f2b686e468261e205d7dcae8cb66e2af37f5697978c119a3fc6cd9a263243b90240a49c0622078d5b140b4f649a201c40440742afb7ec5eadd29254d21424ec3b5d35243205432414bc7012268298008200288e701a257992680740590c2e0cf33d00a3ec9b194130cfe7c39cd3ca640b36f53455c0c02780c3551b7d24f30f8f3e53c8741c408f00cc20a20ae1f885f68f0a7a43a614651715ec419ce1256e050b014e73a1142e42149b8706fb81df0e6346f5e4d841f580477e35d27ecef4478207605c4422ef42cb486402be442bdb0eccc100229a855470b305f73001126c2432ed41f613506137806610510d70fc473cd4db93b111e585c2d8baf9a961c6719c9949458e599c4218b521c25598ab34cf244a754169a38989907e2dc26cebb89f040a49f81a15fc3932da4b0f2d13aa4e4737bfb2b4773f180e9ea9346239a0a7f82651712455110c38b71561e0fc0bcb901449849ec58067ea978a71436532e62ced6504fe320e4e0af404f47012204a7de81f8cc39dd7873036dbd31434b95acca7a67e9f95b3d486880aeea1ecd34daad9b7d5416686b18b5a71a24eb837e6a0fd755a791b953f6bc000807c2cf945cfd9c44e96bcaf71f461cc02430f9b9e5ce57942e5fd3bc10a01168fc6a6fa1e739896243988e0c755122182e6446b0715f82e45cea84440e963b81379779f36b2212b0e8b7ffb9626ccd8bf3905cac741a4a054cdd1c75a55369acf4098ce929844e4ea974ba59d98c034600cb558be739cee22cab6ab799cd748dee2ed0d6b4d53394e97ad1dfd5add2455997e6baccce6ed71cf84d27759511982637c248948592d14845380a4566fc7691e3dc06a6948554709a2421899d743ec09bbbbcf9e67c8045bf3b6f8d76655da3329f9abebb36fdb4b14085aedd34408cc04299a33640bac3e6bcb53340140c90bf1afadf3f5c343bcde595b6228efac5d2ea2073395d63be6879572ae9a8f1a1f0369b1106a291ca744a33f3b87262fe8a238ea9e40916226152676144a9a3c60778739637ef8c0fb0e873a7fdf115798064b5d3a077161acd175a493495b96ed1bc69515f3a6a8028b8f5511ba0a2c545bb7e0628042cfdd5d243fb6364f4930fd05ed3bde07fac01ea3ef98bee1c7540216494461891a6899411170a0ba5094ed238b1ff5338ca148d751417599abbe98080376779f3ce0185309bd7df5efbfb83ed293bfc63f3af9dedb3d72c3a475d0f803a6ed753f6b8ec4f90ecbdeb613068d85ffdbcb8343d7d836a5d55b6ee234f147eee9aab75d4f74450b21c611c5a2491cc9294e32ca102172a6598311e6211f3824891f38c48377d0ff0e62c6fdef91e60d1e37efb5253a3bce9a4313d5dd720592eac3696a8d9d971b5e803bc8edbfee81a2fd670d45b04f6c75f19bda3abbc996964fccff0ae987cd1f5cdcce9593e31c8e80843d02ca58a6ace719e45144b3b02296249665849084f432653ceddb43cc09bb3bc79677980459ffb6aef165ab5c4c2f0cc519b9ebb539cd7eb677a6258facf5f217df2d73f7efaf12f9ffcee4f8f1ffcfdc94ffefcbf873f7bfcb7878f1ffce3c92fdefbf4a71f7df6e1fb8e4a29bc65788481a8093a392724c55cd2145321139c8828c305d3e6892b99ea823a6a7c2031e42a6ffe191f60d1e3fefab73f7ff49ff71efdebc19307bf361df4a37ffefbd1471f3c7effe172a3edbe7ff59bcf3efcbda3bd36903b6a03b4a6551f0e03d8fd15540fab3eb064d5188351ae79a49989430bc9188e8b24c33a8f429c5016a62ac984a0a19be60778739637efcc0fb0e8735ffdbceaa39aa78bf3385aec0150c7ed754e40fcd596f0b5d549779d8f80971cc002be870b4e1e23d985e5269380325835d5bb78c0bdfede829800884e2ddf7bc5eadd298bf70a11f2c139ad9b960a020341404b4701228cee001001c435047135267ef958915ae659dd74f3865678a78c636e7eb988f46941282731e7f1d982d09751ed4234ca839841551e8280518008cede2d677fa9a98bd25cf9495da5218d681425eb2bac220819d87c105600710d41fc42e34a08e582c7698475628794c4269ce5566d13a999a6992409d50e8e6302de5ce6cdaf714c9645c82c79d7093fcb275d69f68f4d5e7771101350ba2ef9cfb7eaa9ac55a5159a2dc17434070ac4aedeacbfae114d8c11929ecda7bf0a6b17bc7a1a10581c6be56142085edd8208b5254882fa25ae3c847c00882b80b886209e6b62aa6d16bd763331052c7a298a478cbef992fda2364fb33a405b3649f5467ffc0d8b76125e6b894275b31fa0cd79637e39ccc5068e8a2b64043c12d7a23497efaeb8028b236431e4051552e45848a6b1b4c0e42461388f0a2685e2454163072b9e963778e192abbcf955f10416fd0e2c37ab0aa9a6d601baaa7b34d368d7c48ea82c9631a67d9b83ac0ffa6959ef205d75dad55012105e8772a80fd3410cad310ca077ab140ad3415e4233234104dabbf2f001462d5b10995d77e6ff951f7111432d0100", - "status": 200, - "response": { - "itemsReceived": 115, - "itemsAccepted": 115, - "errors": [] - }, - "rawHeaders": [ - "Content-Type", - "application/json; charset=utf-8", - "x-ms-session-id", - "04B4ED9D-1F06-485E-A968-2C76CD164563", - "Strict-Transport-Security", - "max-age=31536000", - "Access-Control-Allow-Headers", - "Origin, X-Requested-With, Content-Name, Content-Type, Accept, Sdk-Context", - "Access-Control-Allow-Origin", - "*", - "Access-Control-Max-Age", - "3600", - "X-Content-Type-Options", - "nosniff", - "Date", - "Tue, 07 Apr 2020 15:15:31 GMT", - "Connection", - "close", - "Content-Length", - "53" - ] - }, { "scope": "https://westus.api.cognitive.microsoft.com:443", "method": "POST", - "path": "/luis/v2.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554?verbose=false&staging=false&spellCheck=false&log=true", - "body": "sample dialog", + "path": "/luis/prediction/v3.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554/slots/production/predict?verbose=true&log=true&show-all-intents=false", + "body": { + "query": "sample dialog", + "options": { + "preferExternalEntities": true + } + }, "status": 200, "response": { "query": "sample dialog", - "topScoringIntent": { - "intent": "Sample", - "score": 0.9705775 - }, - "entities": [] + "prediction": { + "topIntent": "Sample", + "intents": { + "Sample": { + "score": 0.9705775 + } + }, + "entities": {} + } }, "rawHeaders": [ "Cache-Control", @@ -135,15 +128,15 @@ "Pragma", "no-cache", "Content-Length", - "131", + "116", "Content-Type", "application/json; charset=utf-8", "Apim-Request-Id", - "c820ee0a-3ccf-4a48-ba0e-3f8e5cc0e6e8", + "ff620f7b-20e4-4a82-912b-cfbe4a26e1e0", "Request-Id", - "c820ee0a-3ccf-4a48-ba0e-3f8e5cc0e6e8", + "ff620f7b-20e4-4a82-912b-cfbe4a26e1e0", "CSP-Billing-Usage", - "CognitiveServices.LUIS.Transaction|1", + "CognitiveServices.LUIS.Transaction=1", "Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload", "X-Content-Type-Options", @@ -151,7 +144,7 @@ "X-Frame-Options", "SAMEORIGIN", "Date", - "Tue, 07 Apr 2020 15:15:31 GMT", + "Thu, 16 Jul 2020 18:23:49 GMT", "Connection", "close" ] @@ -159,16 +152,25 @@ { "scope": "https://westus.api.cognitive.microsoft.com:443", "method": "POST", - "path": "/luis/v2.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554?verbose=false&staging=false&spellCheck=false&log=true", - "body": "sample dialog", + "path": "/luis/prediction/v3.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554/slots/production/predict?verbose=true&log=true&show-all-intents=false", + "body": { + "query": "sample dialog", + "options": { + "preferExternalEntities": true + } + }, "status": 200, "response": { "query": "sample dialog", - "topScoringIntent": { - "intent": "Confirm", - "score": 0.12141446 - }, - "entities": [] + "prediction": { + "topIntent": "Confirm", + "intents": { + "Confirm": { + "score": 0.148891255 + } + }, + "entities": {} + } }, "rawHeaders": [ "Cache-Control", @@ -176,15 +178,15 @@ "Pragma", "no-cache", "Content-Length", - "133", + "120", "Content-Type", "application/json; charset=utf-8", "Apim-Request-Id", - "4ddfd754-27d0-427a-a899-95a747de255c", + "672eead0-5591-41fc-a57c-3dcfebaaca83", "Request-Id", - "4ddfd754-27d0-427a-a899-95a747de255c", + "672eead0-5591-41fc-a57c-3dcfebaaca83", "CSP-Billing-Usage", - "CognitiveServices.LUIS.Transaction|1", + "CognitiveServices.LUIS.Transaction=1", "Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload", "X-Content-Type-Options", @@ -192,7 +194,7 @@ "X-Frame-Options", "SAMEORIGIN", "Date", - "Tue, 07 Apr 2020 15:15:32 GMT", + "Thu, 16 Jul 2020 18:23:50 GMT", "Connection", "close" ] @@ -200,16 +202,25 @@ { "scope": "https://westus.api.cognitive.microsoft.com:443", "method": "POST", - "path": "/luis/v2.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554?verbose=false&staging=false&spellCheck=false&log=true", - "body": "custom", + "path": "/luis/prediction/v3.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554/slots/production/predict?verbose=true&log=true&show-all-intents=false", + "body": { + "query": "custom", + "options": { + "preferExternalEntities": true + } + }, "status": 200, "response": { "query": "custom", - "topScoringIntent": { - "intent": "None", - "score": 0.873317 - }, - "entities": [] + "prediction": { + "topIntent": "None", + "intents": { + "None": { + "score": 0.873317 + } + }, + "entities": {} + } }, "rawHeaders": [ "Cache-Control", @@ -217,15 +228,15 @@ "Pragma", "no-cache", "Content-Length", - "121", + "104", "Content-Type", "application/json; charset=utf-8", "Apim-Request-Id", - "2f4a7d98-351f-499d-9ca8-14a5296f4946", + "ece39a3b-7c43-4cfc-af29-647c8e22b677", "Request-Id", - "2f4a7d98-351f-499d-9ca8-14a5296f4946", + "ece39a3b-7c43-4cfc-af29-647c8e22b677", "CSP-Billing-Usage", - "CognitiveServices.LUIS.Transaction|1", + "CognitiveServices.LUIS.Transaction=1", "Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload", "X-Content-Type-Options", @@ -233,7 +244,7 @@ "X-Frame-Options", "SAMEORIGIN", "Date", - "Tue, 07 Apr 2020 15:15:32 GMT", + "Thu, 16 Jul 2020 18:23:50 GMT", "Connection", "close" ] @@ -241,16 +252,25 @@ { "scope": "https://westus.api.cognitive.microsoft.com:443", "method": "POST", - "path": "/luis/v2.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554?verbose=false&staging=false&spellCheck=false&log=true", - "body": "custom", + "path": "/luis/prediction/v3.0/apps/f7c2ee78-8679-4a3e-b384-0cd10c67e554/slots/production/predict?verbose=true&log=true&show-all-intents=false", + "body": { + "query": "custom", + "options": { + "preferExternalEntities": true + } + }, "status": 200, "response": { "query": "custom", - "topScoringIntent": { - "intent": "Confirm", - "score": 0.3304704 - }, - "entities": [] + "prediction": { + "topIntent": "Confirm", + "intents": { + "Confirm": { + "score": 0.4082594 + } + }, + "entities": {} + } }, "rawHeaders": [ "Cache-Control", @@ -258,15 +278,15 @@ "Pragma", "no-cache", "Content-Length", - "125", + "111", "Content-Type", "application/json; charset=utf-8", "Apim-Request-Id", - "5f3c1b8a-23e4-4692-bf7a-82ec8827242e", + "add1b544-d2f6-407a-aec9-8b4a49fb43b8", "Request-Id", - "5f3c1b8a-23e4-4692-bf7a-82ec8827242e", + "add1b544-d2f6-407a-aec9-8b4a49fb43b8", "CSP-Billing-Usage", - "CognitiveServices.LUIS.Transaction|1", + "CognitiveServices.LUIS.Transaction=1", "Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload", "X-Content-Type-Options", @@ -274,7 +294,7 @@ "X-Frame-Options", "SAMEORIGIN", "Date", - "Tue, 07 Apr 2020 15:15:33 GMT", + "Thu, 16 Jul 2020 18:23:50 GMT", "Connection", "close" ] diff --git a/templates/typescript/generator-bot-virtualassistant/test/generator-bot-virtualassistant.skill.test.suite.js b/templates/typescript/generator-bot-virtualassistant/test/generator-bot-virtualassistant.skill.test.suite.js index 4115532d2b..aecc4ea4e6 100644 --- a/templates/typescript/generator-bot-virtualassistant/test/generator-bot-virtualassistant.skill.test.suite.js +++ b/templates/typescript/generator-bot-virtualassistant/test/generator-bot-virtualassistant.skill.test.suite.js @@ -27,6 +27,8 @@ describe(`The generator-bot-virtualassistant skill tests`, function() { var manifest1_1; const manifestPath1_0 = join(`src`, `manifest`, `manifest-1.0.json`); const manifestPath1_1 = join(`src`, `manifest`, `manifest-1.1.json`); + const mainDialogPath = join(`src`, `dialogs`, `mainDialog.ts`); + const cognitiveModelsPath = join(`src`, `cognitiveModels.json`); const testCognitiveModelsPath = join(`test`, `mocks`, `resources`, `cognitiveModels.json`); const templatesFiles = [ @@ -34,8 +36,10 @@ describe(`The generator-bot-virtualassistant skill tests`, function() { `.eslintrc.json`, `.gitignore`, `.nycrc`, + mainDialogPath, manifestPath1_0, manifestPath1_1, + cognitiveModelsPath, testCognitiveModelsPath ]; @@ -91,7 +95,7 @@ describe(`The generator-bot-virtualassistant skill tests`, function() { ]) .on('ready', generator => { generator.spawnCommandSync = sinon.spy(); - });; + }); packageJSON = require(join(skillGenerationPath, skillName, `package.json`)); manifest1_0 = require(join(skillGenerationPath, skillName, manifestPath1_0)); @@ -199,8 +203,28 @@ describe(`The generator-bot-virtualassistant skill tests`, function() { done(); }); }); - + + describe(`and have in the mainDialog file`, function() { + it(`an line with the following structure`, function(done) { + assert.fileContent( + join(skillGenerationPath, skillName, mainDialogPath), + `const skillLuis: LuisRecognizer | undefined = localizedServices.luisServices ? localizedServices.luisServices.get('${skillNameCamelCase}') : undefined;` + ); + done(); + }); + }); + describe(`and have in the cognitiveModels file`, function() { + it(`an id property with the given name`, function(done) { + assert.fileContent( + join(skillGenerationPath, skillName, cognitiveModelsPath), + `"id": "${skillNameCamelCase}",` + ); + done(); + }); + }); + + describe(`and have in the test cognitiveModels file`, function() { it(`an id property with the given name`, function(done) { assert.fileContent( join(skillGenerationPath, skillName, testCognitiveModelsPath), From 5f5930cc372ae6d9a453cb73a4e839f548ec4b2e Mon Sep 17 00:00:00 2001 From: matiasroldan6 Date: Wed, 5 Aug 2020 15:09:31 -0300 Subject: [PATCH 12/17] Fix authentication support --- .../samples/sample-skill/src/dialogs/skillDialogBase.ts | 6 +++--- templates/typescript/samples/sample-skill/src/index.ts | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/templates/typescript/samples/sample-skill/src/dialogs/skillDialogBase.ts b/templates/typescript/samples/sample-skill/src/dialogs/skillDialogBase.ts index f33a4a49fc..9aa9a7c454 100644 --- a/templates/typescript/samples/sample-skill/src/dialogs/skillDialogBase.ts +++ b/templates/typescript/samples/sample-skill/src/dialogs/skillDialogBase.ts @@ -43,12 +43,12 @@ export class SkillDialogBase extends ComponentDialog { this.templateEngine = templateEngine; // NOTE: Uncomment the following if your skill requires authentication - // if (!services.authenticationConnections.any()) + // if (!settings.oauthConnections || settings.oauthConnections.length < 0) // { - // throw new Error("You must configure an authentication connection in your bot file before using this component."); + // throw new Error('You must configure an authentication connection in your bot file before using this component.'); // } // - // this.addDialog(new MultiProviderAuthDialog(services)); + // this.addDialog(new MultiProviderAuthDialog(settings.oauthConnections,'en')); } protected async getAuthToken(sc: WaterfallStepContext): Promise { diff --git a/templates/typescript/samples/sample-skill/src/index.ts b/templates/typescript/samples/sample-skill/src/index.ts index 6a22019a0b..f15f21c66b 100644 --- a/templates/typescript/samples/sample-skill/src/index.ts +++ b/templates/typescript/samples/sample-skill/src/index.ts @@ -47,7 +47,8 @@ const settings: Partial = { cosmosDb: appsettings.cosmosDb, defaultLocale: cognitiveModelsRaw.defaultLocale, microsoftAppId: appsettings.microsoftAppId, - microsoftAppPassword: appsettings.microsoftAppPassword + microsoftAppPassword: appsettings.microsoftAppPassword, + oauthConnections: appsettings.oauthConnections }; if (settings.appInsights === undefined) { throw new Error('There is no appInsights value in appsettings file'); From 31f31376bf77399f242ee76ee826646ea7b8f38d Mon Sep 17 00:00:00 2001 From: matiasroldan6 Date: Wed, 5 Aug 2020 16:16:53 -0300 Subject: [PATCH 13/17] Correct locale. Replicate changes in generator template --- .../templates/sample-skill/src/dialogs/skillDialogBase.ts | 6 +++--- .../generators/skill/templates/sample-skill/src/index.ts | 3 ++- .../samples/sample-skill/src/dialogs/skillDialogBase.ts | 4 ++-- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/dialogs/skillDialogBase.ts b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/dialogs/skillDialogBase.ts index f33a4a49fc..23d1b43127 100644 --- a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/dialogs/skillDialogBase.ts +++ b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/dialogs/skillDialogBase.ts @@ -43,12 +43,12 @@ export class SkillDialogBase extends ComponentDialog { this.templateEngine = templateEngine; // NOTE: Uncomment the following if your skill requires authentication - // if (!services.authenticationConnections.any()) + // if (!settings.oauthConnections || settings.oauthConnections.length === 0) // { - // throw new Error("You must configure an authentication connection in your bot file before using this component."); + // throw new Error('You must configure an authentication connection in your bot file before using this component.'); // } // - // this.addDialog(new MultiProviderAuthDialog(services)); + // this.addDialog(new MultiProviderAuthDialog(settings.oauthConnections, this.settings.defaultLocale as string)); } protected async getAuthToken(sc: WaterfallStepContext): Promise { diff --git a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/index.ts b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/index.ts index 6a22019a0b..f15f21c66b 100644 --- a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/index.ts +++ b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/index.ts @@ -47,7 +47,8 @@ const settings: Partial = { cosmosDb: appsettings.cosmosDb, defaultLocale: cognitiveModelsRaw.defaultLocale, microsoftAppId: appsettings.microsoftAppId, - microsoftAppPassword: appsettings.microsoftAppPassword + microsoftAppPassword: appsettings.microsoftAppPassword, + oauthConnections: appsettings.oauthConnections }; if (settings.appInsights === undefined) { throw new Error('There is no appInsights value in appsettings file'); diff --git a/templates/typescript/samples/sample-skill/src/dialogs/skillDialogBase.ts b/templates/typescript/samples/sample-skill/src/dialogs/skillDialogBase.ts index 9aa9a7c454..23d1b43127 100644 --- a/templates/typescript/samples/sample-skill/src/dialogs/skillDialogBase.ts +++ b/templates/typescript/samples/sample-skill/src/dialogs/skillDialogBase.ts @@ -43,12 +43,12 @@ export class SkillDialogBase extends ComponentDialog { this.templateEngine = templateEngine; // NOTE: Uncomment the following if your skill requires authentication - // if (!settings.oauthConnections || settings.oauthConnections.length < 0) + // if (!settings.oauthConnections || settings.oauthConnections.length === 0) // { // throw new Error('You must configure an authentication connection in your bot file before using this component.'); // } // - // this.addDialog(new MultiProviderAuthDialog(settings.oauthConnections,'en')); + // this.addDialog(new MultiProviderAuthDialog(settings.oauthConnections, this.settings.defaultLocale as string)); } protected async getAuthToken(sc: WaterfallStepContext): Promise { From 71ef82354e554bc1f3494df5b2921ebb397a76cb Mon Sep 17 00:00:00 2001 From: Luis Sergio <37625424+LCarbonellRod@users.noreply.github.com> Date: Wed, 12 Aug 2020 10:09:57 -0300 Subject: [PATCH 14/17] Fix undefined state issue --- .../templates/sample-skill/src/dialogs/skillDialogBase.ts | 4 ++-- .../generators/skill/templates/sample-skill/src/index.ts | 2 +- .../samples/sample-skill/src/dialogs/skillDialogBase.ts | 4 ++-- templates/typescript/samples/sample-skill/src/index.ts | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/dialogs/skillDialogBase.ts b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/dialogs/skillDialogBase.ts index 23d1b43127..306303eae7 100644 --- a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/dialogs/skillDialogBase.ts +++ b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/dialogs/skillDialogBase.ts @@ -72,7 +72,7 @@ export class SkillDialogBase extends ComponentDialog { if (providerTokenResponse !== undefined) { // eslint-disable-next-line @typescript-eslint/no-explicit-any - const state: any = await this.stateAccessor.get(sc.context); + const state: SkillState = await this.stateAccessor.get(sc.context, new SkillState()); state.token = providerTokenResponse.tokenResponse.token; } @@ -125,7 +125,7 @@ export class SkillDialogBase extends ComponentDialog { // clear state // eslint-disable-next-line @typescript-eslint/no-explicit-any - const state: any = await this.stateAccessor.get(sc.context); + const state: SkillState = await this.stateAccessor.get(sc.context, new SkillState()); state.clear(); } } diff --git a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/index.ts b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/index.ts index f15f21c66b..fb366193b6 100644 --- a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/index.ts +++ b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/index.ts @@ -83,7 +83,7 @@ const cosmosDbStorageOptions: CosmosDbPartitionedStorageOptions = { const storage: CosmosDbPartitionedStorage = new CosmosDbPartitionedStorage(cosmosDbStorageOptions); const userState: UserState = new UserState(storage); const conversationState: ConversationState = new ConversationState(storage); -const stateAccessor: StatePropertyAccessor = userState.createProperty(SkillState.name); +const stateAccessor: StatePropertyAccessor = conversationState.createProperty(SkillState.name); // Configure localized responses const localizedTemplates: Map = new Map(); diff --git a/templates/typescript/samples/sample-skill/src/dialogs/skillDialogBase.ts b/templates/typescript/samples/sample-skill/src/dialogs/skillDialogBase.ts index 23d1b43127..306303eae7 100644 --- a/templates/typescript/samples/sample-skill/src/dialogs/skillDialogBase.ts +++ b/templates/typescript/samples/sample-skill/src/dialogs/skillDialogBase.ts @@ -72,7 +72,7 @@ export class SkillDialogBase extends ComponentDialog { if (providerTokenResponse !== undefined) { // eslint-disable-next-line @typescript-eslint/no-explicit-any - const state: any = await this.stateAccessor.get(sc.context); + const state: SkillState = await this.stateAccessor.get(sc.context, new SkillState()); state.token = providerTokenResponse.tokenResponse.token; } @@ -125,7 +125,7 @@ export class SkillDialogBase extends ComponentDialog { // clear state // eslint-disable-next-line @typescript-eslint/no-explicit-any - const state: any = await this.stateAccessor.get(sc.context); + const state: SkillState = await this.stateAccessor.get(sc.context, new SkillState()); state.clear(); } } diff --git a/templates/typescript/samples/sample-skill/src/index.ts b/templates/typescript/samples/sample-skill/src/index.ts index f15f21c66b..fb366193b6 100644 --- a/templates/typescript/samples/sample-skill/src/index.ts +++ b/templates/typescript/samples/sample-skill/src/index.ts @@ -83,7 +83,7 @@ const cosmosDbStorageOptions: CosmosDbPartitionedStorageOptions = { const storage: CosmosDbPartitionedStorage = new CosmosDbPartitionedStorage(cosmosDbStorageOptions); const userState: UserState = new UserState(storage); const conversationState: ConversationState = new ConversationState(storage); -const stateAccessor: StatePropertyAccessor = userState.createProperty(SkillState.name); +const stateAccessor: StatePropertyAccessor = conversationState.createProperty(SkillState.name); // Configure localized responses const localizedTemplates: Map = new Map(); From a525f2deb65b8579b48f40bea4b4cfdf9a8638ac Mon Sep 17 00:00:00 2001 From: Martin Battaglino Date: Wed, 16 Sep 2020 16:08:00 -0300 Subject: [PATCH 15/17] Add authentication configuration in the Skill --- .../authentication/allowedCallersClaimsValidator.ts | 4 +++- .../skill/templates/sample-skill/src/index.ts | 12 +++++++++++- .../authentication/allowedCallersClaimsValidator.ts | 4 +++- .../typescript/samples/sample-skill/src/index.ts | 12 +++++++++++- 4 files changed, 28 insertions(+), 4 deletions(-) diff --git a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/authentication/allowedCallersClaimsValidator.ts b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/authentication/allowedCallersClaimsValidator.ts index 7e3da61c8f..5e354bf4e0 100644 --- a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/authentication/allowedCallersClaimsValidator.ts +++ b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/authentication/allowedCallersClaimsValidator.ts @@ -26,7 +26,7 @@ export class AllowedCallersClaimsValidator { this.allowedCallers = allowedCallers; } - public validateClaims(claims: Claim[]): void { + public validateClaims(claims: Claim[]): Promise { // If _allowedCallers contains an "*", we allow all callers. if (SkillValidation.isSkillClaim(claims) && !this.allowedCallers.includes('*')) { // Check that the appId claim in the skill request is in the list of callers configured for this bot. @@ -35,5 +35,7 @@ export class AllowedCallersClaimsValidator { throw new Error(`Received a request from a bot with an app ID of ${ appId }. To enable requests from this caller, add the app ID to your configuration file.`); } } + + return Promise.resolve(); } } \ No newline at end of file diff --git a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/index.ts b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/index.ts index fb366193b6..b2dd8552ee 100644 --- a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/index.ts +++ b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/index.ts @@ -31,6 +31,8 @@ import { SampleAction } from './dialogs/sampleAction'; import { SkillState } from './models'; import { BotServices } from './services/botServices'; import { IBotSettings } from './services/botSettings'; +import { AuthenticationConfiguration, Claim } from 'botframework-connector'; +import { AllowedCallersClaimsValidator } from './authentication'; const cognitiveModels: Map = new Map(); const cognitiveModelDictionary: { [key: string]: Object } = cognitiveModelsRaw.cognitiveModels; @@ -100,9 +102,17 @@ supportedLocales.forEach((locale: string) => { const localeTemplateManager: LocaleTemplateManager = new LocaleTemplateManager(localizedTemplates, settings.defaultLocale || 'en-us'); +// Register AuthConfiguration to enable custom claim validation. +const allowedCallersClaimsValidator: AllowedCallersClaimsValidator = new AllowedCallersClaimsValidator(appsettings.allowedCallers); +const authenticationConfiguration: AuthenticationConfiguration = new AuthenticationConfiguration( + undefined, + (claims: Claim[]) => allowedCallersClaimsValidator.validateClaims(claims) +); + const adapterSettings: Partial = { appId: settings.microsoftAppId, - appPassword: settings.microsoftAppPassword + appPassword: settings.microsoftAppPassword, + authConfig: authenticationConfiguration }; const defaultAdapter: DefaultAdapter = new DefaultAdapter( diff --git a/templates/typescript/samples/sample-skill/src/authentication/allowedCallersClaimsValidator.ts b/templates/typescript/samples/sample-skill/src/authentication/allowedCallersClaimsValidator.ts index 7e3da61c8f..5e354bf4e0 100644 --- a/templates/typescript/samples/sample-skill/src/authentication/allowedCallersClaimsValidator.ts +++ b/templates/typescript/samples/sample-skill/src/authentication/allowedCallersClaimsValidator.ts @@ -26,7 +26,7 @@ export class AllowedCallersClaimsValidator { this.allowedCallers = allowedCallers; } - public validateClaims(claims: Claim[]): void { + public validateClaims(claims: Claim[]): Promise { // If _allowedCallers contains an "*", we allow all callers. if (SkillValidation.isSkillClaim(claims) && !this.allowedCallers.includes('*')) { // Check that the appId claim in the skill request is in the list of callers configured for this bot. @@ -35,5 +35,7 @@ export class AllowedCallersClaimsValidator { throw new Error(`Received a request from a bot with an app ID of ${ appId }. To enable requests from this caller, add the app ID to your configuration file.`); } } + + return Promise.resolve(); } } \ No newline at end of file diff --git a/templates/typescript/samples/sample-skill/src/index.ts b/templates/typescript/samples/sample-skill/src/index.ts index fb366193b6..b2dd8552ee 100644 --- a/templates/typescript/samples/sample-skill/src/index.ts +++ b/templates/typescript/samples/sample-skill/src/index.ts @@ -31,6 +31,8 @@ import { SampleAction } from './dialogs/sampleAction'; import { SkillState } from './models'; import { BotServices } from './services/botServices'; import { IBotSettings } from './services/botSettings'; +import { AuthenticationConfiguration, Claim } from 'botframework-connector'; +import { AllowedCallersClaimsValidator } from './authentication'; const cognitiveModels: Map = new Map(); const cognitiveModelDictionary: { [key: string]: Object } = cognitiveModelsRaw.cognitiveModels; @@ -100,9 +102,17 @@ supportedLocales.forEach((locale: string) => { const localeTemplateManager: LocaleTemplateManager = new LocaleTemplateManager(localizedTemplates, settings.defaultLocale || 'en-us'); +// Register AuthConfiguration to enable custom claim validation. +const allowedCallersClaimsValidator: AllowedCallersClaimsValidator = new AllowedCallersClaimsValidator(appsettings.allowedCallers); +const authenticationConfiguration: AuthenticationConfiguration = new AuthenticationConfiguration( + undefined, + (claims: Claim[]) => allowedCallersClaimsValidator.validateClaims(claims) +); + const adapterSettings: Partial = { appId: settings.microsoftAppId, - appPassword: settings.microsoftAppPassword + appPassword: settings.microsoftAppPassword, + authConfig: authenticationConfiguration }; const defaultAdapter: DefaultAdapter = new DefaultAdapter( From 7fb3e3801d5c55b5a9b2e5d7f8589cde4561866c Mon Sep 17 00:00:00 2001 From: Martin Battaglino Date: Wed, 16 Sep 2020 16:41:00 -0300 Subject: [PATCH 16/17] Add async in validateClaims method --- .../src/authentication/allowedCallersClaimsValidator.ts | 2 +- .../src/authentication/allowedCallersClaimsValidator.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/authentication/allowedCallersClaimsValidator.ts b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/authentication/allowedCallersClaimsValidator.ts index 5e354bf4e0..4ee2bc4b6c 100644 --- a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/authentication/allowedCallersClaimsValidator.ts +++ b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/authentication/allowedCallersClaimsValidator.ts @@ -26,7 +26,7 @@ export class AllowedCallersClaimsValidator { this.allowedCallers = allowedCallers; } - public validateClaims(claims: Claim[]): Promise { + public async validateClaims(claims: Claim[]): Promise { // If _allowedCallers contains an "*", we allow all callers. if (SkillValidation.isSkillClaim(claims) && !this.allowedCallers.includes('*')) { // Check that the appId claim in the skill request is in the list of callers configured for this bot. diff --git a/templates/typescript/samples/sample-skill/src/authentication/allowedCallersClaimsValidator.ts b/templates/typescript/samples/sample-skill/src/authentication/allowedCallersClaimsValidator.ts index 5e354bf4e0..4ee2bc4b6c 100644 --- a/templates/typescript/samples/sample-skill/src/authentication/allowedCallersClaimsValidator.ts +++ b/templates/typescript/samples/sample-skill/src/authentication/allowedCallersClaimsValidator.ts @@ -26,7 +26,7 @@ export class AllowedCallersClaimsValidator { this.allowedCallers = allowedCallers; } - public validateClaims(claims: Claim[]): Promise { + public async validateClaims(claims: Claim[]): Promise { // If _allowedCallers contains an "*", we allow all callers. if (SkillValidation.isSkillClaim(claims) && !this.allowedCallers.includes('*')) { // Check that the appId claim in the skill request is in the list of callers configured for this bot. From a48ebebcc750468397641cf81f0985d34f9247f5 Mon Sep 17 00:00:00 2001 From: MatR Date: Thu, 10 Dec 2020 16:24:36 -0300 Subject: [PATCH 17/17] Replace DialogEx using JS SDK DialogHelper --- .../sample-skill/src/bots/defaultActivityHandler.ts | 13 +++++++------ .../sample-skill/src/bots/defaultActivityHandler.ts | 13 +++++++------ 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/bots/defaultActivityHandler.ts b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/bots/defaultActivityHandler.ts index e2f91680c1..82bfc3ec48 100644 --- a/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/bots/defaultActivityHandler.ts +++ b/templates/typescript/generator-bot-virtualassistant/generators/skill/templates/sample-skill/src/bots/defaultActivityHandler.ts @@ -14,8 +14,9 @@ import { TurnContext } from 'botbuilder'; import { Dialog, - DialogState } from 'botbuilder-dialogs'; -import { LocaleTemplateManager, DialogEx } from 'bot-solutions'; + DialogState, + runDialog } from 'botbuilder-dialogs'; +import { LocaleTemplateManager } from 'bot-solutions'; export class DefaultActivityHandler extends ActivityHandler { private readonly dialog: Dialog; @@ -45,7 +46,7 @@ export class DefaultActivityHandler extends ActivityHandler { protected async membersAdded(turnContext: TurnContext, next: () => Promise): Promise { await turnContext.sendActivity(this.templateEngine.generateActivityForLocale('IntroMessage', turnContext.activity.locale)); - await DialogEx.run(this.dialog, turnContext, this.dialogStateAccessor); + await runDialog(this.dialog, turnContext, this.dialogStateAccessor); } protected onMessageActivity(turnContext: TurnContext): Promise { @@ -56,14 +57,14 @@ export class DefaultActivityHandler extends ActivityHandler { (activity.text === undefined || activity.text.trim().length === 0)) { return Promise.resolve(); } - return DialogEx.run(this.dialog, turnContext, this.dialogStateAccessor); + return runDialog(this.dialog, turnContext, this.dialogStateAccessor); } protected onEventActivity(turnContext: TurnContext): Promise { - return DialogEx.run(this.dialog, turnContext, this.dialogStateAccessor); + return runDialog(this.dialog, turnContext, this.dialogStateAccessor); } protected onEndOfConversationActivity(turnContext: TurnContext): Promise { - return DialogEx.run(this.dialog, turnContext, this.dialogStateAccessor); + return runDialog(this.dialog, turnContext, this.dialogStateAccessor); } } diff --git a/templates/typescript/samples/sample-skill/src/bots/defaultActivityHandler.ts b/templates/typescript/samples/sample-skill/src/bots/defaultActivityHandler.ts index e2f91680c1..82bfc3ec48 100644 --- a/templates/typescript/samples/sample-skill/src/bots/defaultActivityHandler.ts +++ b/templates/typescript/samples/sample-skill/src/bots/defaultActivityHandler.ts @@ -14,8 +14,9 @@ import { TurnContext } from 'botbuilder'; import { Dialog, - DialogState } from 'botbuilder-dialogs'; -import { LocaleTemplateManager, DialogEx } from 'bot-solutions'; + DialogState, + runDialog } from 'botbuilder-dialogs'; +import { LocaleTemplateManager } from 'bot-solutions'; export class DefaultActivityHandler extends ActivityHandler { private readonly dialog: Dialog; @@ -45,7 +46,7 @@ export class DefaultActivityHandler extends ActivityHandler { protected async membersAdded(turnContext: TurnContext, next: () => Promise): Promise { await turnContext.sendActivity(this.templateEngine.generateActivityForLocale('IntroMessage', turnContext.activity.locale)); - await DialogEx.run(this.dialog, turnContext, this.dialogStateAccessor); + await runDialog(this.dialog, turnContext, this.dialogStateAccessor); } protected onMessageActivity(turnContext: TurnContext): Promise { @@ -56,14 +57,14 @@ export class DefaultActivityHandler extends ActivityHandler { (activity.text === undefined || activity.text.trim().length === 0)) { return Promise.resolve(); } - return DialogEx.run(this.dialog, turnContext, this.dialogStateAccessor); + return runDialog(this.dialog, turnContext, this.dialogStateAccessor); } protected onEventActivity(turnContext: TurnContext): Promise { - return DialogEx.run(this.dialog, turnContext, this.dialogStateAccessor); + return runDialog(this.dialog, turnContext, this.dialogStateAccessor); } protected onEndOfConversationActivity(turnContext: TurnContext): Promise { - return DialogEx.run(this.dialog, turnContext, this.dialogStateAccessor); + return runDialog(this.dialog, turnContext, this.dialogStateAccessor); } }