port: component registration -> bot components (#3471)
* feat: BotComponent instead of ComponentRegistration * fix: serviceCollection sync * feat: dialogs to bot component, shim registration * fix: dialogs adaptive testing component registration * fix: adaptive teams tests * fix: dialogs declarative tests * fix: orchestrator bot component * fix: remove unused p-reduce dep * fix: orchestrator rename * fix: corebot initial turn state * fix: turn state undefined * fix: component load error * fix: use no-op configuration for configure services calls * fix: shim luis/qna component registrations * port: collect bot component load exceptions and report once * fix: orchestrator exports * fix: noOpConfiguration docstring
This commit is contained in:
Родитель
1bc772d54d
Коммит
85ff1febb9
|
@ -32,6 +32,7 @@
|
|||
"botbuilder-dialogs": "4.1.6",
|
||||
"botbuilder-dialogs-adaptive": "4.1.6",
|
||||
"botbuilder-dialogs-declarative": "4.1.6",
|
||||
"botbuilder-runtime-core": "4.1.6",
|
||||
"orchestrator-core": "rc",
|
||||
"uuid": "^8.3.2"
|
||||
},
|
||||
|
|
|
@ -6,5 +6,5 @@
|
|||
* Licensed under the MIT License.
|
||||
*/
|
||||
|
||||
export { OrchestratorRecognizer, LabelType } from './orchestratorRecognizer';
|
||||
export { OrchestratorComponentRegistration } from './orchestratorComponentRegistration';
|
||||
export { LabelType, OrchestratorRecognizer } from './orchestratorRecognizer';
|
||||
export { OrchestratorBotComponent } from './orchestratorBotComponent';
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
import { BotComponent } from 'botbuilder-core';
|
||||
import { ComponentDeclarativeTypes } from 'botbuilder-dialogs-declarative';
|
||||
import { OrchestratorRecognizer } from './orchestratorRecognizer';
|
||||
import { ServiceCollection, Configuration } from 'botbuilder-runtime-core';
|
||||
|
||||
export class OrchestratorBotComponent extends BotComponent {
|
||||
configureServices(services: ServiceCollection, _configuration: Configuration): void {
|
||||
services.composeFactory<ComponentDeclarativeTypes[]>('declarativeTypes', (declarativeTypes) =>
|
||||
declarativeTypes.concat({
|
||||
getDeclarativeTypes() {
|
||||
return [
|
||||
{
|
||||
kind: OrchestratorRecognizer.$kind,
|
||||
type: OrchestratorRecognizer,
|
||||
},
|
||||
];
|
||||
},
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
/**
|
||||
* @module botbuilder-ai-orchestrator
|
||||
*/
|
||||
/**
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License.
|
||||
*/
|
||||
|
||||
import { ComponentDeclarativeTypes, DeclarativeType } from 'botbuilder-dialogs-declarative';
|
||||
import { OrchestratorRecognizer } from './orchestratorRecognizer';
|
||||
|
||||
export class OrchestratorComponentRegistration implements ComponentDeclarativeTypes {
|
||||
public getDeclarativeTypes(_resourceExplorer: unknown): DeclarativeType[] {
|
||||
return [
|
||||
{
|
||||
kind: OrchestratorRecognizer.$kind,
|
||||
type: OrchestratorRecognizer,
|
||||
},
|
||||
];
|
||||
}
|
||||
}
|
|
@ -33,6 +33,8 @@
|
|||
"adaptive-expressions": "4.1.6",
|
||||
"botbuilder-core": "4.1.6",
|
||||
"botbuilder-dialogs": "4.1.6",
|
||||
"botbuilder-dialogs-declarative": "4.1.6",
|
||||
"botbuilder-runtime-core": "4.1.6",
|
||||
"lodash": "^4.17.21",
|
||||
"node-fetch": "^2.6.0",
|
||||
"url-parse": "^1.5.1"
|
||||
|
@ -59,4 +61,4 @@
|
|||
"schemas",
|
||||
"src"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -14,12 +14,22 @@ export * from './instanceData';
|
|||
export * from './intentData';
|
||||
export * from './listElement';
|
||||
export * from './luisAdaptiveRecognizer';
|
||||
export * from './luisBotComponent';
|
||||
export * from './luisComponentRegistration';
|
||||
export * from './luisRecognizer';
|
||||
export * from './luisTelemetryConstants';
|
||||
export * from './numberWithUnits';
|
||||
export * from './ordinalV2';
|
||||
export * from './qnaCardBuilder';
|
||||
export * from './qnaMakerBotComponent';
|
||||
export * from './qnaMakerComponentRegistration';
|
||||
export * from './qnaMakerRecognizer';
|
||||
|
||||
// BindToActivity, GenerateAnswerUtils, HttpRequestUtils and TrainUtils are internal.
|
||||
export { ActiveLearningUtils } from './qnamaker-utils';
|
||||
|
||||
export { QnAMakerDialog, QnAMakerDialogOptions, QnAMakerDialogResponseOptions } from './qnaMakerDialog';
|
||||
|
||||
export {
|
||||
QNAMAKER_TRACE_TYPE,
|
||||
QNAMAKER_TRACE_NAME,
|
||||
|
@ -29,6 +39,7 @@ export {
|
|||
QnAMakerClientKey,
|
||||
QnAMaker,
|
||||
} from './qnaMaker';
|
||||
|
||||
export {
|
||||
FeedbackRecord,
|
||||
FeedbackRecords,
|
||||
|
@ -43,9 +54,3 @@ export {
|
|||
QnAResponseContext,
|
||||
RankerTypes,
|
||||
} from './qnamaker-interfaces';
|
||||
export { QnAMakerDialog, QnAMakerDialogOptions, QnAMakerDialogResponseOptions } from './qnaMakerDialog';
|
||||
export * from './qnaMakerComponentRegistration';
|
||||
export * from './qnaMakerRecognizer';
|
||||
|
||||
// BindToActivity, GenerateAnswerUtils, HttpRequestUtils and TrainUtils are internal.
|
||||
export { ActiveLearningUtils } from './qnamaker-utils';
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
import { BotComponent } from 'botbuilder-core';
|
||||
import { ComponentDeclarativeTypes } from 'botbuilder-dialogs-declarative';
|
||||
import { Configuration, ServiceCollection } from 'botbuilder-runtime-core';
|
||||
import { LuisAdaptiveRecognizer } from './luisAdaptiveRecognizer';
|
||||
|
||||
export class LuisBotComponent extends BotComponent {
|
||||
configureServices(services: ServiceCollection, _configuration: Configuration): void {
|
||||
services.composeFactory<ComponentDeclarativeTypes[]>('declarativeTypes', (declarativeTypes) =>
|
||||
declarativeTypes.concat({
|
||||
getDeclarativeTypes() {
|
||||
return [
|
||||
{
|
||||
kind: LuisAdaptiveRecognizer.$kind,
|
||||
type: LuisAdaptiveRecognizer,
|
||||
},
|
||||
];
|
||||
},
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
|
@ -6,25 +6,32 @@
|
|||
* Licensed under the MIT License.
|
||||
*/
|
||||
|
||||
import { ComponentDeclarativeTypes } from 'botbuilder-dialogs-declarative';
|
||||
import { ComponentRegistration } from 'botbuilder-core';
|
||||
import { LuisAdaptiveRecognizer } from './luisAdaptiveRecognizer';
|
||||
import { LuisBotComponent } from './luisBotComponent';
|
||||
import { ServiceCollection, noOpConfiguration } from 'botbuilder-runtime-core';
|
||||
|
||||
/**
|
||||
* Define component assets for Luis.
|
||||
*/
|
||||
export class LuisComponentRegistration extends ComponentRegistration {
|
||||
private readonly services = new ServiceCollection({
|
||||
declarativeTypes: [],
|
||||
});
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
new LuisBotComponent().configureServices(this.services, noOpConfiguration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get declarative types for LUIS component registration.
|
||||
*
|
||||
* @param {any} _resourceExplorer resource explorer
|
||||
* @returns {ComponentRegistration[]} component registrations
|
||||
* @param _resourceExplorer resource explorer
|
||||
* @returns component registrations
|
||||
*/
|
||||
public getDeclarativeTypes(_resourceExplorer: unknown): ComponentRegistration[] {
|
||||
return [
|
||||
{
|
||||
kind: LuisAdaptiveRecognizer.$kind,
|
||||
type: LuisAdaptiveRecognizer,
|
||||
},
|
||||
];
|
||||
public getDeclarativeTypes(_resourceExplorer: unknown): ComponentDeclarativeTypes[] {
|
||||
return this.services.mustMakeInstance<ComponentDeclarativeTypes[]>('declarativeTypes');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
import { BotComponent } from 'botbuilder-core';
|
||||
import { ComponentDeclarativeTypes } from 'botbuilder-dialogs-declarative';
|
||||
import { Configuration, ServiceCollection } from 'botbuilder-runtime-core';
|
||||
import { QnAMakerDialog } from './qnaMakerDialog';
|
||||
import { QnAMakerRecognizer } from './qnaMakerRecognizer';
|
||||
|
||||
export class QnAMakerBotComponent extends BotComponent {
|
||||
configureServices(services: ServiceCollection, _configuration: Configuration): void {
|
||||
services.composeFactory<ComponentDeclarativeTypes[]>('declarativeTypes', (declarativeTypes) =>
|
||||
declarativeTypes.concat({
|
||||
getDeclarativeTypes() {
|
||||
return [
|
||||
{
|
||||
kind: QnAMakerRecognizer.$kind,
|
||||
type: QnAMakerRecognizer,
|
||||
},
|
||||
{
|
||||
kind: QnAMakerDialog.$kind,
|
||||
type: QnAMakerDialog,
|
||||
},
|
||||
];
|
||||
},
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
|
@ -6,24 +6,32 @@
|
|||
* Licensed under the MIT License.
|
||||
*/
|
||||
|
||||
import { ComponentDeclarativeTypes } from 'botbuilder-dialogs-declarative';
|
||||
import { ComponentRegistration } from 'botbuilder-core';
|
||||
import { QnAMakerDialog } from './qnaMakerDialog';
|
||||
import { QnAMakerRecognizer } from './qnaMakerRecognizer';
|
||||
import { QnAMakerBotComponent } from './qnaMakerBotComponent';
|
||||
import { ServiceCollection, noOpConfiguration } from 'botbuilder-runtime-core';
|
||||
|
||||
/**
|
||||
* Define component assets for QnAMaker.
|
||||
*/
|
||||
export class QnAMakerComponentRegistration extends ComponentRegistration {
|
||||
public getDeclarativeTypes(_resourceExplorer: unknown): unknown[] {
|
||||
return [
|
||||
{
|
||||
kind: QnAMakerRecognizer.$kind,
|
||||
type: QnAMakerRecognizer,
|
||||
},
|
||||
{
|
||||
kind: QnAMakerDialog.$kind,
|
||||
type: QnAMakerDialog,
|
||||
},
|
||||
];
|
||||
private readonly services = new ServiceCollection({
|
||||
declarativeTypes: [],
|
||||
});
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
new QnAMakerBotComponent().configureServices(this.services, noOpConfiguration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get declarative types for QnAMaker component registration.
|
||||
*
|
||||
* @param _resourceExplorer resource explorer
|
||||
* @returns component registrations
|
||||
*/
|
||||
public getDeclarativeTypes(_resourceExplorer: unknown): ComponentDeclarativeTypes[] {
|
||||
return this.services.mustMakeInstance<ComponentDeclarativeTypes[]>('declarativeTypes');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
import { Assertion, assert } from 'botbuilder-stdlib';
|
||||
import { Configuration, ServiceCollection } from 'botbuilder-runtime-core';
|
||||
import { Test, tests } from 'botbuilder-stdlib';
|
||||
|
||||
/**
|
||||
* Definition of a BotComponent that allows registration of services, custom actions, memory scopes and adapters.
|
||||
|
@ -15,6 +15,7 @@ export abstract class BotComponent {
|
|||
abstract configureServices(services: ServiceCollection, configuration: Configuration): void;
|
||||
}
|
||||
|
||||
export const isBotComponent: Test<BotComponent> = (val): val is BotComponent => {
|
||||
return tests.unsafe.isObjectAs<BotComponent>(val) && tests.isFunc(val.configureServices);
|
||||
export const assertBotComponent: Assertion<BotComponent> = (val, path) => {
|
||||
assert.unsafe.castObjectAs<BotComponent>(val, path);
|
||||
assert.func(val.configureServices, path.concat('configureServices'));
|
||||
};
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
"botbuilder-dialogs": "4.1.6",
|
||||
"botbuilder-dialogs-adaptive": "4.1.6",
|
||||
"botbuilder-dialogs-declarative": "4.1.6",
|
||||
"botbuilder-runtime-core": "4.1.6",
|
||||
"botbuilder-stdlib": "4.1.6",
|
||||
"lodash": "^4.17.19"
|
||||
},
|
||||
|
|
|
@ -14,7 +14,6 @@ export * from './getTeamChannels';
|
|||
export * from './getTeamDetails';
|
||||
export * from './getTeamMember';
|
||||
export * from './sendAppBasedLinkQueryResponse';
|
||||
export * from './sendMessageToTeamsChannel';
|
||||
export * from './sendMEActionResponse';
|
||||
export * from './sendMEAttachmentsResponse';
|
||||
export * from './sendMEAuthResponse';
|
||||
|
@ -22,6 +21,9 @@ export * from './sendMEBotMessagePreviewResponse';
|
|||
export * from './sendMEConfigQuerySettingUrlResponse';
|
||||
export * from './sendMEMessageResponse';
|
||||
export * from './sendMESelectItemResponse';
|
||||
export * from './sendMessageToTeamsChannel';
|
||||
export * from './sendTabAuthResponse';
|
||||
export * from './sendTabCardResponse';
|
||||
export * from './sendTaskModuleCardResponse';
|
||||
export * from './sendTaskModuleMessageResponse';
|
||||
export * from './sendTaskModuleUrlResponse';
|
||||
|
|
|
@ -0,0 +1,126 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
import { BotComponent } from 'botbuilder';
|
||||
import { ComponentDeclarativeTypes } from 'botbuilder-dialogs-declarative';
|
||||
import { Configuration, ServiceCollection } from 'botbuilder-runtime-core';
|
||||
|
||||
import {
|
||||
GetMeetingParticipant,
|
||||
GetMember,
|
||||
GetPagedMembers,
|
||||
GetPagedTeamMembers,
|
||||
GetTeamChannels,
|
||||
GetTeamDetails,
|
||||
GetTeamMember,
|
||||
SendAppBasedLinkQueryResponse,
|
||||
SendMEActionResponse,
|
||||
SendMEAttachmentsResponse,
|
||||
SendMEAuthResponse,
|
||||
SendMEBotMessagePreviewResponse,
|
||||
SendMEConfigQuerySettingUrlResponse,
|
||||
SendMEMessageResponse,
|
||||
SendMESelectItemResponse,
|
||||
SendMessageToTeamsChannel,
|
||||
SendTabAuthResponse,
|
||||
SendTabCardResponse,
|
||||
SendTaskModuleCardResponse,
|
||||
SendTaskModuleMessageResponse,
|
||||
SendTaskModuleUrlResponse,
|
||||
} from './actions';
|
||||
|
||||
import {
|
||||
OnTeamsAppBasedLinkQuery,
|
||||
OnTeamsCardAction,
|
||||
OnTeamsChannelCreated,
|
||||
OnTeamsChannelDeleted,
|
||||
OnTeamsChannelRenamed,
|
||||
OnTeamsChannelRestored,
|
||||
OnTeamsFileConsent,
|
||||
OnTeamsMEBotMessagePreviewEdit,
|
||||
OnTeamsMEBotMessagePreviewSend,
|
||||
OnTeamsMECardButtonClicked,
|
||||
OnTeamsMEConfigQuerySettingUrl,
|
||||
OnTeamsMEConfigSetting,
|
||||
OnTeamsMEConfigurationSetting,
|
||||
OnTeamsMEFetchTask,
|
||||
OnTeamsMEQuery,
|
||||
OnTeamsMESelectItem,
|
||||
OnTeamsMESubmitAction,
|
||||
OnTeamsO365ConnectorCardAction,
|
||||
OnTeamsTabFetch,
|
||||
OnTeamsTabSubmit,
|
||||
OnTeamsTaskModuleFetch,
|
||||
OnTeamsTaskModuleSubmit,
|
||||
OnTeamsTeamArchived,
|
||||
OnTeamsTeamDeleted,
|
||||
OnTeamsTeamHardDeleted,
|
||||
OnTeamsTeamRenamed,
|
||||
OnTeamsTeamRestored,
|
||||
OnTeamsTeamUnarchived,
|
||||
} from './conditions';
|
||||
|
||||
export class AdaptiveTeamsBotComponent extends BotComponent {
|
||||
configureServices(services: ServiceCollection, _configuration: Configuration): void {
|
||||
services.composeFactory<ComponentDeclarativeTypes[]>('declarativeTypes', (declarativeTypes) =>
|
||||
declarativeTypes.concat({
|
||||
getDeclarativeTypes() {
|
||||
return [
|
||||
// Actions
|
||||
{ kind: GetMeetingParticipant.$kind, type: GetMeetingParticipant },
|
||||
{ kind: GetMember.$kind, type: GetMember },
|
||||
{ kind: GetPagedMembers.$kind, type: GetPagedMembers },
|
||||
{ kind: GetPagedTeamMembers.$kind, type: GetPagedTeamMembers },
|
||||
{ kind: GetTeamChannels.$kind, type: GetTeamChannels },
|
||||
{ kind: GetTeamDetails.$kind, type: GetTeamDetails },
|
||||
{ kind: GetTeamMember.$kind, type: GetTeamMember },
|
||||
{ kind: SendAppBasedLinkQueryResponse.$kind, type: SendAppBasedLinkQueryResponse },
|
||||
{ kind: SendMEActionResponse.$kind, type: SendMEActionResponse },
|
||||
{ kind: SendMEAttachmentsResponse.$kind, type: SendMEAttachmentsResponse },
|
||||
{ kind: SendMEAuthResponse.$kind, type: SendMEAuthResponse },
|
||||
{ kind: SendMEBotMessagePreviewResponse.$kind, type: SendMEBotMessagePreviewResponse },
|
||||
{ kind: SendMEConfigQuerySettingUrlResponse.$kind, type: SendMEConfigQuerySettingUrlResponse },
|
||||
{ kind: SendMEMessageResponse.$kind, type: SendMEMessageResponse },
|
||||
{ kind: SendMESelectItemResponse.$kind, type: SendMESelectItemResponse },
|
||||
{ kind: SendMessageToTeamsChannel.$kind, type: SendMessageToTeamsChannel },
|
||||
{ kind: SendTabAuthResponse.$kind, type: SendTabAuthResponse },
|
||||
{ kind: SendTabCardResponse.$kind, type: SendTabCardResponse },
|
||||
{ kind: SendTaskModuleCardResponse.$kind, type: SendTaskModuleCardResponse },
|
||||
{ kind: SendTaskModuleMessageResponse.$kind, type: SendTaskModuleMessageResponse },
|
||||
{ kind: SendTaskModuleUrlResponse.$kind, type: SendTaskModuleUrlResponse },
|
||||
|
||||
// Conditions
|
||||
{ kind: OnTeamsAppBasedLinkQuery.$kind, type: OnTeamsAppBasedLinkQuery },
|
||||
{ kind: OnTeamsCardAction.$kind, type: OnTeamsCardAction },
|
||||
{ kind: OnTeamsChannelCreated.$kind, type: OnTeamsChannelCreated },
|
||||
{ kind: OnTeamsChannelDeleted.$kind, type: OnTeamsChannelDeleted },
|
||||
{ kind: OnTeamsChannelRenamed.$kind, type: OnTeamsChannelRenamed },
|
||||
{ kind: OnTeamsChannelRestored.$kind, type: OnTeamsChannelRestored },
|
||||
{ kind: OnTeamsFileConsent.$kind, type: OnTeamsFileConsent },
|
||||
{ kind: OnTeamsMEBotMessagePreviewEdit.$kind, type: OnTeamsMEBotMessagePreviewEdit },
|
||||
{ kind: OnTeamsMEBotMessagePreviewSend.$kind, type: OnTeamsMEBotMessagePreviewSend },
|
||||
{ kind: OnTeamsMECardButtonClicked.$kind, type: OnTeamsMECardButtonClicked },
|
||||
{ kind: OnTeamsMEConfigSetting.$kind, type: OnTeamsMEConfigSetting },
|
||||
{ kind: OnTeamsMEConfigQuerySettingUrl.$kind, type: OnTeamsMEConfigQuerySettingUrl },
|
||||
{ kind: OnTeamsMEFetchTask.$kind, type: OnTeamsMEFetchTask },
|
||||
{ kind: OnTeamsMEQuery.$kind, type: OnTeamsMEQuery },
|
||||
{ kind: OnTeamsMESelectItem.$kind, type: OnTeamsMESelectItem },
|
||||
{ kind: OnTeamsMEConfigurationSetting.$kind, type: OnTeamsMEConfigurationSetting },
|
||||
{ kind: OnTeamsMESubmitAction.$kind, type: OnTeamsMESubmitAction },
|
||||
{ kind: OnTeamsO365ConnectorCardAction.$kind, type: OnTeamsO365ConnectorCardAction },
|
||||
{ kind: OnTeamsTabFetch.$kind, type: OnTeamsTabFetch },
|
||||
{ kind: OnTeamsTabSubmit.$kind, type: OnTeamsTabSubmit },
|
||||
{ kind: OnTeamsTaskModuleFetch.$kind, type: OnTeamsTaskModuleFetch },
|
||||
{ kind: OnTeamsTaskModuleSubmit.$kind, type: OnTeamsTaskModuleSubmit },
|
||||
{ kind: OnTeamsTeamArchived.$kind, type: OnTeamsTeamArchived },
|
||||
{ kind: OnTeamsTeamDeleted.$kind, type: OnTeamsTeamDeleted },
|
||||
{ kind: OnTeamsTeamHardDeleted.$kind, type: OnTeamsTeamHardDeleted },
|
||||
{ kind: OnTeamsTeamRenamed.$kind, type: OnTeamsTeamRenamed },
|
||||
{ kind: OnTeamsTeamRestored.$kind, type: OnTeamsTeamRestored },
|
||||
{ kind: OnTeamsTeamUnarchived.$kind, type: OnTeamsTeamUnarchived },
|
||||
];
|
||||
},
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
|
@ -6,6 +6,7 @@
|
|||
* Licensed under the MIT License.
|
||||
*/
|
||||
|
||||
export * from './onTeamsAppBasedLinkQuery';
|
||||
export * from './onTeamsAppBasedLinkQuery';
|
||||
export * from './onTeamsCardAction';
|
||||
export * from './onTeamsChannelCreated';
|
||||
|
@ -17,6 +18,7 @@ export * from './onTeamsMEBotMessagePreviewEdit';
|
|||
export * from './onTeamsMEBotMessagePreviewSend';
|
||||
export * from './onTeamsMECardButtonClicked';
|
||||
export * from './onTeamsMEConfigQuerySettingUrl';
|
||||
export * from './onTeamsMEConfigSetting';
|
||||
export * from './onTeamsMEConfigurationSetting';
|
||||
export * from './onTeamsMEFetchTask';
|
||||
export * from './onTeamsMEQuery';
|
||||
|
@ -28,9 +30,9 @@ export * from './onTeamsTabSubmit';
|
|||
export * from './onTeamsTaskModuleFetch';
|
||||
export * from './onTeamsTaskModuleSubmit';
|
||||
export * from './onTeamsTeamArchived';
|
||||
export * from './onTeamsTeamArchived';
|
||||
export * from './onTeamsTeamDeleted';
|
||||
export * from './onTeamsTeamHardDeleted';
|
||||
export * from './onTeamsTeamRenamed';
|
||||
export * from './onTeamsTeamRestored';
|
||||
export * from './onTeamsTeamArchived';
|
||||
export * from './onTeamsTeamUnarchived';
|
||||
|
|
|
@ -7,5 +7,5 @@
|
|||
*/
|
||||
|
||||
export * from './actions';
|
||||
export * from './adaptiveTeamsBotComponent';
|
||||
export * from './conditions';
|
||||
export * from './teamsComponentRegistration';
|
||||
|
|
|
@ -1,188 +0,0 @@
|
|||
/**
|
||||
* @module botbuilder-dialogs-adaptive-teams
|
||||
*/
|
||||
/**
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License.
|
||||
*/
|
||||
|
||||
import { OnTeamsAppBasedLinkQuery } from './conditions/onTeamsAppBasedLinkQuery';
|
||||
import {
|
||||
ComponentDeclarativeTypes,
|
||||
CustomDeserializer,
|
||||
DeclarativeType,
|
||||
ResourceExplorer,
|
||||
} from 'botbuilder-dialogs-declarative';
|
||||
import { OnActivityConfiguration } from 'botbuilder-dialogs-adaptive';
|
||||
import {
|
||||
OnTeamsCardAction,
|
||||
OnTeamsChannelCreated,
|
||||
OnTeamsChannelDeleted,
|
||||
OnTeamsChannelRenamed,
|
||||
OnTeamsChannelRestored,
|
||||
OnTeamsFileConsent,
|
||||
OnTeamsMEBotMessagePreviewEdit,
|
||||
OnTeamsMEBotMessagePreviewSend,
|
||||
OnTeamsMECardButtonClicked,
|
||||
OnTeamsMEConfigQuerySettingUrl,
|
||||
OnTeamsMEConfigurationSetting,
|
||||
OnTeamsMEFetchTask,
|
||||
OnTeamsMEQuery,
|
||||
OnTeamsMESelectItem,
|
||||
OnTeamsMESubmitAction,
|
||||
OnTeamsO365ConnectorCardAction,
|
||||
OnTeamsTabFetch,
|
||||
OnTeamsTabSubmit,
|
||||
OnTeamsTaskModuleFetch,
|
||||
OnTeamsTaskModuleSubmit,
|
||||
OnTeamsTeamArchived,
|
||||
OnTeamsTeamDeleted,
|
||||
OnTeamsTeamHardDeleted,
|
||||
OnTeamsTeamRenamed,
|
||||
OnTeamsTeamRestored,
|
||||
OnTeamsTeamUnarchived,
|
||||
} from './conditions';
|
||||
import {
|
||||
GetMeetingParticipant,
|
||||
GetMeetingParticipantConfiguration,
|
||||
GetMember,
|
||||
GetMemberConfiguration,
|
||||
GetPagedMembers,
|
||||
GetPagedMembersConfiguration,
|
||||
GetPagedTeamMembers,
|
||||
GetPagedTeamMembersConfiguration,
|
||||
GetTeamChannels,
|
||||
GetTeamChannelsConfiguration,
|
||||
GetTeamDetails,
|
||||
GetTeamDetailsConfiguration,
|
||||
GetTeamMember,
|
||||
GetTeamMemberConfiguration,
|
||||
SendAppBasedLinkQueryResponse,
|
||||
SendAppBasedLinkQueryResponseConfiguration,
|
||||
SendMessageToTeamsChannel,
|
||||
SendMEActionResponse,
|
||||
SendMEActionResponseConfiguration,
|
||||
SendMEAttachmentsResponse,
|
||||
SendMEAttachmentsResponseConfiguration,
|
||||
SendMEAuthResponse,
|
||||
SendMEBotMessagePreviewResponse,
|
||||
SendMEBotMessagePreviewResponseConfiguration,
|
||||
SendMEConfigQuerySettingUrlResponse,
|
||||
SendMEConfigQuerySettingUrlResponseConfiguration,
|
||||
SendMEMessageResponse,
|
||||
SendMEMessageResponseConfiguration,
|
||||
SendMESelectItemResponse,
|
||||
SendMESelectItemResponseConfiguration,
|
||||
SendTaskModuleCardResponse,
|
||||
SendTaskModuleCardResponseConfiguration,
|
||||
SendTaskModuleMessageResponse,
|
||||
SendTaskModuleMessageResponseConfiguration,
|
||||
SendTaskModuleUrlResponse,
|
||||
SendTaskModuleUrlResponseConfiguration,
|
||||
} from './actions';
|
||||
import { ComponentRegistration } from 'botbuilder';
|
||||
import { Dialog } from 'botbuilder-dialogs';
|
||||
import { BaseAuthResponseDialogConfiguration } from './actions/baseAuthResponseDialog';
|
||||
import { SendTabAuthResponse } from './actions/sendTabAuthResponse';
|
||||
import { SendTabCardResponse } from './actions/sendTabCardResponse';
|
||||
import { OnTeamsMEConfigSetting } from './conditions/onTeamsMEConfigSetting';
|
||||
|
||||
type ActionType<T> = {
|
||||
$kind: string;
|
||||
new (dialogId?: string | undefined): T;
|
||||
};
|
||||
|
||||
type ConditionType<T> = {
|
||||
$kind: string;
|
||||
new (actions?: Dialog<Record<string, unknown>>[] | undefined, condition?: string | undefined): T;
|
||||
};
|
||||
|
||||
type Type<T> = {
|
||||
$kind: string;
|
||||
new (...args: unknown[]): T;
|
||||
};
|
||||
|
||||
/* eslint-disable prettier/prettier */
|
||||
/* eslint-reason It's extremely difficult to read with limited line widths.*/
|
||||
export class TeamsComponentRegistration extends ComponentRegistration implements ComponentDeclarativeTypes {
|
||||
private _declarativeTypes: DeclarativeType<unknown, unknown>[] = [];
|
||||
|
||||
/**
|
||||
* Initializes a new instance of `TeamsComponentRegistration`.
|
||||
*/
|
||||
public constructor() {
|
||||
super();
|
||||
|
||||
// Actions
|
||||
this._addDeclarativeType<GetMeetingParticipant, GetMeetingParticipantConfiguration>(GetMeetingParticipant);
|
||||
this._addDeclarativeType<GetMember, GetMemberConfiguration>(GetMember);
|
||||
this._addDeclarativeType<GetPagedMembers, GetPagedMembersConfiguration>(GetPagedMembers);
|
||||
this._addDeclarativeType<GetPagedTeamMembers, GetPagedTeamMembersConfiguration>(GetPagedTeamMembers);
|
||||
this._addDeclarativeType<GetTeamChannels, GetTeamChannelsConfiguration>(GetTeamChannels);
|
||||
this._addDeclarativeType<GetTeamDetails, GetTeamDetailsConfiguration>(GetTeamDetails);
|
||||
this._addDeclarativeType<GetTeamMember, GetTeamMemberConfiguration>(GetTeamMember);
|
||||
this._addDeclarativeType<SendAppBasedLinkQueryResponse, SendAppBasedLinkQueryResponseConfiguration>(SendAppBasedLinkQueryResponse);
|
||||
this._addDeclarativeType<SendMessageToTeamsChannel, SendMessageToTeamsChannel>(SendMessageToTeamsChannel);
|
||||
this._addDeclarativeType<SendMEActionResponse, SendMEActionResponseConfiguration>(SendMEActionResponse);
|
||||
this._addDeclarativeType<SendMEAttachmentsResponse,SendMEAttachmentsResponseConfiguration>(SendMEAttachmentsResponse);
|
||||
this._addDeclarativeType<SendMEAuthResponse, BaseAuthResponseDialogConfiguration>(SendMEAuthResponse);
|
||||
this._addDeclarativeType<SendMEBotMessagePreviewResponse,SendMEBotMessagePreviewResponseConfiguration>(SendMEBotMessagePreviewResponse);
|
||||
this._addDeclarativeType<SendMEConfigQuerySettingUrlResponse,SendMEConfigQuerySettingUrlResponseConfiguration>(SendMEConfigQuerySettingUrlResponse);
|
||||
this._addDeclarativeType<SendMEMessageResponse,SendMEMessageResponseConfiguration>(SendMEMessageResponse);
|
||||
this._addDeclarativeType<SendMESelectItemResponse,SendMESelectItemResponseConfiguration>(SendMESelectItemResponse);
|
||||
this._addDeclarativeType<SendTaskModuleCardResponse, SendTaskModuleCardResponseConfiguration>(SendTaskModuleCardResponse);
|
||||
this._addDeclarativeType<SendTaskModuleMessageResponse, SendTaskModuleMessageResponseConfiguration>(SendTaskModuleMessageResponse);
|
||||
this._addDeclarativeType<SendTaskModuleUrlResponse, SendTaskModuleUrlResponseConfiguration>(SendTaskModuleUrlResponse);
|
||||
this._addDeclarativeType<SendTabAuthResponse, BaseAuthResponseDialogConfiguration>(SendTabAuthResponse);
|
||||
this._addDeclarativeType<SendTabCardResponse, BaseAuthResponseDialogConfiguration>(SendTabCardResponse);
|
||||
|
||||
// Conditions
|
||||
this._addDeclarativeType<OnTeamsAppBasedLinkQuery, OnActivityConfiguration>(OnTeamsAppBasedLinkQuery);
|
||||
this._addDeclarativeType<OnTeamsCardAction, OnActivityConfiguration>(OnTeamsCardAction);
|
||||
this._addDeclarativeType<OnTeamsChannelCreated, OnActivityConfiguration>(OnTeamsChannelCreated);
|
||||
this._addDeclarativeType<OnTeamsChannelDeleted, OnActivityConfiguration>(OnTeamsChannelDeleted);
|
||||
this._addDeclarativeType<OnTeamsChannelRenamed, OnActivityConfiguration>(OnTeamsChannelRenamed);
|
||||
this._addDeclarativeType<OnTeamsChannelRestored, OnActivityConfiguration>(OnTeamsChannelRestored);
|
||||
this._addDeclarativeType<OnTeamsFileConsent, OnActivityConfiguration>(OnTeamsFileConsent);
|
||||
this._addDeclarativeType<OnTeamsMEBotMessagePreviewEdit, OnActivityConfiguration>(OnTeamsMEBotMessagePreviewEdit);
|
||||
this._addDeclarativeType<OnTeamsMEBotMessagePreviewSend, OnActivityConfiguration>(OnTeamsMEBotMessagePreviewSend);
|
||||
this._addDeclarativeType<OnTeamsMECardButtonClicked, OnActivityConfiguration>(OnTeamsMECardButtonClicked);
|
||||
this._addDeclarativeType<OnTeamsMEConfigSetting, OnActivityConfiguration>(OnTeamsMEConfigSetting);
|
||||
this._addDeclarativeType<OnTeamsMEConfigQuerySettingUrl, OnActivityConfiguration>(OnTeamsMEConfigQuerySettingUrl);
|
||||
this._addDeclarativeType<OnTeamsMEFetchTask, OnActivityConfiguration>(OnTeamsMEFetchTask);
|
||||
this._addDeclarativeType<OnTeamsMEQuery, OnActivityConfiguration>(OnTeamsMEQuery);
|
||||
this._addDeclarativeType<OnTeamsMESelectItem, OnActivityConfiguration>(OnTeamsMESelectItem);
|
||||
this._addDeclarativeType<OnTeamsMEConfigurationSetting, OnActivityConfiguration>(OnTeamsMEConfigurationSetting);
|
||||
this._addDeclarativeType<OnTeamsMESubmitAction, OnActivityConfiguration>(OnTeamsMESubmitAction);
|
||||
this._addDeclarativeType<OnTeamsO365ConnectorCardAction, OnActivityConfiguration>(OnTeamsO365ConnectorCardAction);
|
||||
this._addDeclarativeType<OnTeamsTabFetch, OnActivityConfiguration>(OnTeamsTabFetch);
|
||||
this._addDeclarativeType<OnTeamsTabSubmit, OnActivityConfiguration>(OnTeamsTabSubmit);
|
||||
this._addDeclarativeType<OnTeamsTaskModuleFetch, OnActivityConfiguration>(OnTeamsTaskModuleFetch);
|
||||
this._addDeclarativeType<OnTeamsTaskModuleSubmit, OnActivityConfiguration>(OnTeamsTaskModuleSubmit);
|
||||
this._addDeclarativeType<OnTeamsTeamArchived, OnActivityConfiguration>(OnTeamsTeamArchived);
|
||||
this._addDeclarativeType<OnTeamsTeamDeleted, OnActivityConfiguration>(OnTeamsTeamDeleted);
|
||||
this._addDeclarativeType<OnTeamsTeamHardDeleted, OnActivityConfiguration>(OnTeamsTeamHardDeleted);
|
||||
this._addDeclarativeType<OnTeamsTeamRenamed, OnActivityConfiguration>(OnTeamsTeamRenamed);
|
||||
this._addDeclarativeType<OnTeamsTeamRestored, OnActivityConfiguration>(OnTeamsTeamRestored);
|
||||
this._addDeclarativeType<OnTeamsTeamUnarchived, OnActivityConfiguration>(OnTeamsTeamUnarchived);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets adaptive testing `DeclarativeType` resources.
|
||||
*
|
||||
* @param {ResourceExplorer} _resourceExplorer `ResourceExplorer` with expected path to get all resources.
|
||||
* @returns {DeclarativeType[]} Adaptive testing `DeclarativeType` resources.
|
||||
*/
|
||||
public getDeclarativeTypes(_resourceExplorer: ResourceExplorer): DeclarativeType[] {
|
||||
return this._declarativeTypes;
|
||||
}
|
||||
|
||||
private _addDeclarativeType<T, C>(type: ActionType<T> | ConditionType<T>, loader?: CustomDeserializer<T, C>): void {
|
||||
const declarativeType: DeclarativeType<T, C> = {
|
||||
kind: type.$kind,
|
||||
type: <Type<T>>type,
|
||||
loader,
|
||||
};
|
||||
this._declarativeTypes.push(declarativeType);
|
||||
}
|
||||
}
|
|
@ -1,8 +1,18 @@
|
|||
// Licensed under the MIT License.
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
|
||||
import nock = require('nock');
|
||||
import path = require('path');
|
||||
import { AdaptiveBotComponent } from 'botbuilder-dialogs-adaptive';
|
||||
import { AdaptiveTeamsBotComponent } from '../src/adaptiveTeamsBotComponent';
|
||||
import { AdaptiveTestBotComponent, TestUtils } from 'botbuilder-dialogs-adaptive-testing';
|
||||
import { ConnectorClient, MicrosoftAppCredentials } from 'botframework-connector';
|
||||
import { ComponentDeclarativeTypes, ResourceExplorer } from 'botbuilder-dialogs-declarative';
|
||||
import { ServiceCollection, noOpConfiguration } from 'botbuilder-runtime-core';
|
||||
import { jwt } from 'botbuilder-test-utils';
|
||||
import { ok } from 'assert';
|
||||
|
||||
import {
|
||||
ComponentRegistration,
|
||||
ConversationState,
|
||||
TestAdapter,
|
||||
useBotState,
|
||||
|
@ -13,15 +23,6 @@ import {
|
|||
ChannelAccount,
|
||||
ConversationAccount,
|
||||
} from 'botbuilder';
|
||||
import { ResourceExplorer } from 'botbuilder-dialogs-declarative';
|
||||
import { TeamsComponentRegistration } from '../lib';
|
||||
import { AdaptiveTestComponentRegistration, TestUtils } from 'botbuilder-dialogs-adaptive-testing';
|
||||
import { AdaptiveComponentRegistration } from 'botbuilder-dialogs-adaptive';
|
||||
import { ConnectorClient, MicrosoftAppCredentials } from 'botframework-connector';
|
||||
import { ok } from 'assert';
|
||||
import path = require('path');
|
||||
import nock = require('nock');
|
||||
import { jwt } from 'botbuilder-test-utils';
|
||||
|
||||
const getTeamsTestAdapter = (convo?: Partial<ConversationReference>): TestAdapter => {
|
||||
const adapter = new TestAdapter(convo as ConversationReference);
|
||||
|
@ -118,11 +119,24 @@ const generateTeamMembers = (amount: number): Record<string, unknown>[] => {
|
|||
describe('Actions', function () {
|
||||
jwt.mocha();
|
||||
|
||||
ComponentRegistration.add(new AdaptiveTestComponentRegistration());
|
||||
ComponentRegistration.add(new AdaptiveComponentRegistration());
|
||||
ComponentRegistration.add(new TeamsComponentRegistration());
|
||||
let resourceExplorer: ResourceExplorer;
|
||||
beforeEach(function () {
|
||||
const services = new ServiceCollection({
|
||||
declarativeTypes: [],
|
||||
});
|
||||
|
||||
const resourceExplorer = new ResourceExplorer().addFolder(path.join(__dirname, 'actionTests'), true, false);
|
||||
new AdaptiveBotComponent().configureServices(services, noOpConfiguration);
|
||||
new AdaptiveTeamsBotComponent().configureServices(services, noOpConfiguration);
|
||||
new AdaptiveTestBotComponent().configureServices(services, noOpConfiguration);
|
||||
|
||||
const declarativeTypes = services.mustMakeInstance<ComponentDeclarativeTypes[]>('declarativeTypes');
|
||||
|
||||
resourceExplorer = new ResourceExplorer({ declarativeTypes }).addFolder(
|
||||
path.join(__dirname, 'actionTests'),
|
||||
true,
|
||||
false
|
||||
);
|
||||
});
|
||||
|
||||
/**
|
||||
* Note: With mocha, `this.test?.title` refers to the test's name, so runTestScript
|
||||
|
|
|
@ -1,20 +1,32 @@
|
|||
// Licensed under the MIT License.
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
|
||||
import 'mocha';
|
||||
import { ComponentRegistration } from 'botbuilder';
|
||||
import { ResourceExplorer } from 'botbuilder-dialogs-declarative';
|
||||
import { TeamsComponentRegistration } from '../lib';
|
||||
import path = require('path');
|
||||
import { AdaptiveTestComponentRegistration, TestUtils } from 'botbuilder-dialogs-adaptive-testing';
|
||||
import { AdaptiveComponentRegistration } from 'botbuilder-dialogs-adaptive';
|
||||
import { AdaptiveBotComponent } from 'botbuilder-dialogs-adaptive';
|
||||
import { AdaptiveTeamsBotComponent } from '../src';
|
||||
import { AdaptiveTestBotComponent, TestUtils } from 'botbuilder-dialogs-adaptive-testing';
|
||||
import { ComponentDeclarativeTypes, ResourceExplorer } from 'botbuilder-dialogs-declarative';
|
||||
import { ServiceCollection, noOpConfiguration } from 'botbuilder-runtime-core';
|
||||
|
||||
describe('Conditional Tests', function () {
|
||||
ComponentRegistration.add(new AdaptiveTestComponentRegistration());
|
||||
ComponentRegistration.add(new AdaptiveComponentRegistration());
|
||||
ComponentRegistration.add(new TeamsComponentRegistration());
|
||||
let resourceExplorer: ResourceExplorer;
|
||||
beforeEach(function () {
|
||||
const services = new ServiceCollection({
|
||||
declarativeTypes: [],
|
||||
});
|
||||
|
||||
const resourceExplorer = new ResourceExplorer().addFolder(path.join(__dirname, 'conditionalTests'), true, false);
|
||||
new AdaptiveBotComponent().configureServices(services, noOpConfiguration);
|
||||
new AdaptiveTeamsBotComponent().configureServices(services, noOpConfiguration);
|
||||
new AdaptiveTestBotComponent().configureServices(services, noOpConfiguration);
|
||||
|
||||
const declarativeTypes = services.mustMakeInstance<ComponentDeclarativeTypes[]>('declarativeTypes');
|
||||
|
||||
resourceExplorer = new ResourceExplorer({ declarativeTypes }).addFolder(
|
||||
path.join(__dirname, 'conditionalTests'),
|
||||
true,
|
||||
false
|
||||
);
|
||||
});
|
||||
|
||||
it('OnTeamsActivityTypes', async () => {
|
||||
await TestUtils.runTestScript(resourceExplorer, 'ConditionalsTests_OnTeamsActivityTypes');
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
"botbuilder-dialogs": "4.1.6",
|
||||
"botbuilder-dialogs-adaptive": "4.1.6",
|
||||
"botbuilder-dialogs-declarative": "4.1.6",
|
||||
"botbuilder-runtime-core": "4.1.6",
|
||||
"murmurhash-js": "^1.0.0",
|
||||
"nock": "^11.9.1",
|
||||
"url-parse": "^1.5.1"
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
import { BotComponent } from 'botbuilder-core';
|
||||
import { ComponentDeclarativeTypes } from 'botbuilder-dialogs-declarative';
|
||||
import { ServiceCollection, Configuration } from 'botbuilder-runtime-core';
|
||||
|
||||
import { AssertCondition } from './actions';
|
||||
|
||||
import {
|
||||
AssertNoActivity,
|
||||
AssertReply,
|
||||
AssertReplyActivity,
|
||||
AssertReplyOneOf,
|
||||
CustomEvent,
|
||||
MemoryAssertions,
|
||||
SetProperties,
|
||||
UserActivity,
|
||||
UserConversationUpdate,
|
||||
UserDelay,
|
||||
UserSays,
|
||||
UserTyping,
|
||||
} from './testActions';
|
||||
|
||||
import { HttpRequestSequenceMock } from './httpRequestMocks/httpRequestSequenceMock';
|
||||
import { SettingStringMock } from './settingMocks/settingStringMock';
|
||||
import { TestScript } from './testScript';
|
||||
import { UserTokenBasicMock } from './userTokenMocks';
|
||||
|
||||
export class AdaptiveTestBotComponent extends BotComponent {
|
||||
configureServices(services: ServiceCollection, _configuration: Configuration): void {
|
||||
services.composeFactory<ComponentDeclarativeTypes[]>('declarativeTypes', (declarativeTypes) =>
|
||||
declarativeTypes.concat({
|
||||
getDeclarativeTypes() {
|
||||
return [
|
||||
{ kind: AssertCondition.$kind, type: AssertCondition },
|
||||
{ kind: AssertNoActivity.$kind, type: AssertNoActivity },
|
||||
{ kind: AssertReply.$kind, type: AssertReply },
|
||||
{ kind: AssertReplyActivity.$kind, type: AssertReplyActivity },
|
||||
{ kind: AssertReplyOneOf.$kind, type: AssertReplyOneOf },
|
||||
{ kind: CustomEvent.$kind, type: CustomEvent },
|
||||
{ kind: MemoryAssertions.$kind, type: MemoryAssertions },
|
||||
{ kind: HttpRequestSequenceMock.$kind, type: HttpRequestSequenceMock },
|
||||
{ kind: SetProperties.$kind, type: SetProperties },
|
||||
{ kind: SettingStringMock.$kind, type: SettingStringMock },
|
||||
{ kind: UserActivity.$kind, type: UserActivity },
|
||||
{ kind: UserConversationUpdate.$kind, type: UserConversationUpdate },
|
||||
{ kind: UserDelay.$kind, type: UserDelay },
|
||||
{ kind: UserSays.$kind, type: UserSays },
|
||||
{ kind: UserTyping.$kind, type: UserTyping },
|
||||
{ kind: TestScript.$kind, type: TestScript },
|
||||
{ kind: UserTokenBasicMock.$kind, type: UserTokenBasicMock },
|
||||
];
|
||||
},
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,108 +0,0 @@
|
|||
/**
|
||||
* @module botbuilder-dialogs-adaptive-testing
|
||||
*/
|
||||
/**
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License.
|
||||
*/
|
||||
|
||||
import { ComponentRegistration } from 'botbuilder-core';
|
||||
import {
|
||||
ComponentDeclarativeTypes,
|
||||
CustomDeserializer,
|
||||
DeclarativeType,
|
||||
ResourceExplorer,
|
||||
} from 'botbuilder-dialogs-declarative';
|
||||
import {
|
||||
AssertNoActivity,
|
||||
AssertNoActivityConfiguration,
|
||||
AssertReply,
|
||||
AssertReplyActivity,
|
||||
AssertReplyActivityConfiguration,
|
||||
AssertReplyConfiguration,
|
||||
AssertReplyOneOf,
|
||||
AssertReplyOneOfConfiguration,
|
||||
CustomEvent,
|
||||
CustomEventConfiguration,
|
||||
MemoryAssertions,
|
||||
MemoryAssertionsConfiguration,
|
||||
SetProperties,
|
||||
SetPropertiesConfiguration,
|
||||
UserActivity,
|
||||
UserActivityConfiguration,
|
||||
UserConversationUpdate,
|
||||
UserConversationUpdateConfiguration,
|
||||
UserDelay,
|
||||
UserDelayConfiguration,
|
||||
UserSays,
|
||||
UserSaysConfiguration,
|
||||
UserTyping,
|
||||
UserTypingConfiguration,
|
||||
} from './testActions';
|
||||
import { AssertCondition, AssertConditionConfiguration } from './actions';
|
||||
import { TestScript, TestScriptConfiguration } from './testScript';
|
||||
import { UserTokenBasicMock, UserTokenBasicMockConfiguration } from './userTokenMocks';
|
||||
import {
|
||||
HttpRequestSequenceMock,
|
||||
HttpRequestSequenceMockConfiguration,
|
||||
} from './httpRequestMocks/httpRequestSequenceMock';
|
||||
import { SettingStringMock, SettingStringMockConfiguration } from './settingMocks/settingStringMock';
|
||||
|
||||
type Type<T> = {
|
||||
$kind: string;
|
||||
new (...args: unknown[]): T;
|
||||
};
|
||||
|
||||
/**
|
||||
* `ComponentRegistration` implementation for adaptive testing resources.
|
||||
*/
|
||||
export class AdaptiveTestComponentRegistration extends ComponentRegistration implements ComponentDeclarativeTypes {
|
||||
private _declarativeTypes: DeclarativeType<unknown, unknown>[] = [];
|
||||
|
||||
/**
|
||||
* Initializes a new instance of `AdaptiveTestComponentRegistration`.
|
||||
*/
|
||||
public constructor() {
|
||||
super();
|
||||
this._addDeclarativeType<AssertCondition, AssertConditionConfiguration>(AssertCondition);
|
||||
this._addDeclarativeType<AssertNoActivity, AssertNoActivityConfiguration>(AssertNoActivity);
|
||||
this._addDeclarativeType<AssertReply, AssertReplyConfiguration>(AssertReply);
|
||||
this._addDeclarativeType<AssertReplyActivity, AssertReplyActivityConfiguration>(AssertReplyActivity);
|
||||
this._addDeclarativeType<AssertReplyOneOf, AssertReplyOneOfConfiguration>(AssertReplyOneOf);
|
||||
this._addDeclarativeType<CustomEvent, CustomEventConfiguration>(CustomEvent);
|
||||
this._addDeclarativeType<MemoryAssertions, MemoryAssertionsConfiguration>(MemoryAssertions);
|
||||
this._addDeclarativeType<HttpRequestSequenceMock, HttpRequestSequenceMockConfiguration>(
|
||||
HttpRequestSequenceMock
|
||||
);
|
||||
this._addDeclarativeType<SetProperties, SetPropertiesConfiguration>(SetProperties);
|
||||
this._addDeclarativeType<SettingStringMock, SettingStringMockConfiguration>(SettingStringMock);
|
||||
this._addDeclarativeType<UserActivity, UserActivityConfiguration>(UserActivity);
|
||||
this._addDeclarativeType<UserConversationUpdate, UserConversationUpdateConfiguration>(UserConversationUpdate);
|
||||
this._addDeclarativeType<UserDelay, UserDelayConfiguration>(UserDelay);
|
||||
this._addDeclarativeType<UserSays, UserSaysConfiguration>(UserSays);
|
||||
this._addDeclarativeType<UserTyping, UserTypingConfiguration>(UserTyping);
|
||||
this._addDeclarativeType<TestScript, TestScriptConfiguration>(TestScript);
|
||||
this._addDeclarativeType<UserTokenBasicMock, UserTokenBasicMockConfiguration>(UserTokenBasicMock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets adaptive testing `DeclarativeType` resources.
|
||||
* @param resourceExplorer `ResourceExplorer` with expected path to get all resources.
|
||||
* @returns Adaptive testing `DeclarativeType` resources.
|
||||
*/
|
||||
public getDeclarativeTypes(_resourceExplorer: ResourceExplorer): DeclarativeType[] {
|
||||
return this._declarativeTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
private _addDeclarativeType<T, C>(type: Type<T>, loader?: CustomDeserializer<T, C>): void {
|
||||
const declarativeType: DeclarativeType<T, C> = {
|
||||
kind: type.$kind,
|
||||
type,
|
||||
loader,
|
||||
};
|
||||
this._declarativeTypes.push(declarativeType);
|
||||
}
|
||||
}
|
|
@ -6,7 +6,7 @@
|
|||
* Licensed under the MIT License.
|
||||
*/
|
||||
|
||||
export * from './adaptiveTestComponentRegistration';
|
||||
export * from './adaptiveTestBotComponent';
|
||||
export * from './actions';
|
||||
export * from './mocks';
|
||||
export * from './testScript';
|
||||
|
|
|
@ -1,21 +1,15 @@
|
|||
const { createHash } = require('crypto');
|
||||
const path = require('path');
|
||||
const nock = require('nock');
|
||||
const { ActivityTypes, MessageFactory, SkillConversationIdFactoryBase, TurnContext } = require('botbuilder-core');
|
||||
const { TestUtils } = require('..');
|
||||
const { createHash } = require('crypto');
|
||||
const { makeResourceExplorer } = require('./utils');
|
||||
|
||||
const {
|
||||
ActivityTypes,
|
||||
ComponentRegistration,
|
||||
MessageFactory,
|
||||
SkillConversationIdFactoryBase,
|
||||
TurnContext,
|
||||
} = require('botbuilder-core');
|
||||
const { ResourceExplorer } = require('botbuilder-dialogs-declarative');
|
||||
const { AdaptiveTestComponentRegistration, TestUtils } = require('../lib');
|
||||
const {
|
||||
AdaptiveComponentRegistration,
|
||||
LanguageGenerationComponentRegistration,
|
||||
LanguageGenerationBotComponent,
|
||||
skillConversationIdFactoryKey,
|
||||
skillClientKey,
|
||||
} = require('botbuilder-dialogs-adaptive');
|
||||
|
||||
class MockSkillConversationIdFactory extends SkillConversationIdFactoryBase {
|
||||
constructor(opts = { useCreateSkillConversationId: false }) {
|
||||
super();
|
||||
|
@ -113,17 +107,10 @@ class SetSkillBotFrameworkClientMiddleware {
|
|||
}
|
||||
|
||||
describe('ActionTests', function () {
|
||||
this.timeout(10000);
|
||||
|
||||
ComponentRegistration.add(new AdaptiveComponentRegistration());
|
||||
ComponentRegistration.add(new LanguageGenerationComponentRegistration());
|
||||
ComponentRegistration.add(new AdaptiveTestComponentRegistration());
|
||||
|
||||
const resourceExplorer = new ResourceExplorer().addFolder(
|
||||
path.join(__dirname, 'resources/ActionTests'),
|
||||
true,
|
||||
false
|
||||
);
|
||||
let resourceExplorer;
|
||||
before(function () {
|
||||
resourceExplorer = makeResourceExplorer('ActionTests', LanguageGenerationBotComponent);
|
||||
});
|
||||
|
||||
it('AttachmentInput', async () => {
|
||||
await TestUtils.runTestScript(resourceExplorer, 'Action_AttachmentInput');
|
||||
|
|
|
@ -1,20 +1,11 @@
|
|||
const path = require('path');
|
||||
const { ComponentRegistration } = require('botbuilder-core');
|
||||
const { AdaptiveComponentRegistration } = require('botbuilder-dialogs-adaptive');
|
||||
const { ResourceExplorer } = require('botbuilder-dialogs-declarative');
|
||||
const { AdaptiveTestComponentRegistration, TestUtils } = require('../lib');
|
||||
const { TestUtils } = require('../lib');
|
||||
const { makeResourceExplorer } = require('./utils');
|
||||
|
||||
describe('ActionScopeTests', function () {
|
||||
this.timeout(5000);
|
||||
|
||||
ComponentRegistration.add(new AdaptiveComponentRegistration());
|
||||
ComponentRegistration.add(new AdaptiveTestComponentRegistration());
|
||||
|
||||
const resourceExplorer = new ResourceExplorer().addFolder(
|
||||
path.join(__dirname, 'resources/ActionScopeTests'),
|
||||
true,
|
||||
false
|
||||
);
|
||||
let resourceExplorer;
|
||||
before(function () {
|
||||
resourceExplorer = makeResourceExplorer('ActionScopeTests');
|
||||
});
|
||||
|
||||
it('Break', async () => {
|
||||
await TestUtils.runTestScript(resourceExplorer, 'ActionScope_Break');
|
||||
|
|
|
@ -1,20 +1,11 @@
|
|||
const path = require('path');
|
||||
const { ComponentRegistration } = require('botbuilder-core');
|
||||
const { AdaptiveComponentRegistration } = require('botbuilder-dialogs-adaptive');
|
||||
const { ResourceExplorer } = require('botbuilder-dialogs-declarative');
|
||||
const { AdaptiveTestComponentRegistration, TestUtils } = require('../lib');
|
||||
const { TestUtils } = require('../lib');
|
||||
const { makeResourceExplorer } = require('./utils');
|
||||
|
||||
describe('AdaptiveDialogTests', function () {
|
||||
this.timeout(10000);
|
||||
|
||||
ComponentRegistration.add(new AdaptiveComponentRegistration());
|
||||
ComponentRegistration.add(new AdaptiveTestComponentRegistration());
|
||||
|
||||
const resourceExplorer = new ResourceExplorer().addFolder(
|
||||
path.join(__dirname, 'resources/AdaptiveDialogTests'),
|
||||
true,
|
||||
false
|
||||
);
|
||||
let resourceExplorer;
|
||||
before(function () {
|
||||
resourceExplorer = makeResourceExplorer('AdaptiveDialogTests');
|
||||
});
|
||||
|
||||
it('ActivityAndIntentEvents', async () => {
|
||||
await TestUtils.runTestScript(resourceExplorer, 'AdaptiveDialog_ActivityAndIntentEvents');
|
||||
|
|
|
@ -1,20 +1,11 @@
|
|||
const path = require('path');
|
||||
const { ComponentRegistration } = require('botbuilder-core');
|
||||
const { AdaptiveComponentRegistration } = require('botbuilder-dialogs-adaptive');
|
||||
const { ResourceExplorer } = require('botbuilder-dialogs-declarative');
|
||||
const { AdaptiveTestComponentRegistration, TestUtils } = require('../lib');
|
||||
const { TestUtils } = require('../lib');
|
||||
const { makeResourceExplorer } = require('./utils');
|
||||
|
||||
describe('ConditionalsTests', function () {
|
||||
this.timeout(5000);
|
||||
|
||||
ComponentRegistration.add(new AdaptiveComponentRegistration());
|
||||
ComponentRegistration.add(new AdaptiveTestComponentRegistration());
|
||||
|
||||
const resourceExplorer = new ResourceExplorer().addFolder(
|
||||
path.join(__dirname, 'resources/ConditionalsTests'),
|
||||
true,
|
||||
false
|
||||
);
|
||||
let resourceExplorer;
|
||||
before(function () {
|
||||
resourceExplorer = makeResourceExplorer('ConditionalsTests');
|
||||
});
|
||||
|
||||
it('OnActivityTypes', async () => {
|
||||
await TestUtils.runTestScript(resourceExplorer, 'ConditionalsTests_OnActivityTypes');
|
||||
|
|
|
@ -1,13 +1,5 @@
|
|||
const path = require('path');
|
||||
const { ComponentRegistration } = require('botbuilder-core');
|
||||
const {
|
||||
AdaptiveComponentRegistration,
|
||||
CrossTrainedRecognizerSet,
|
||||
RegexRecognizer,
|
||||
IntentPattern,
|
||||
} = require('botbuilder-dialogs-adaptive');
|
||||
const { ResourceExplorer } = require('botbuilder-dialogs-declarative');
|
||||
const { AdaptiveTestComponentRegistration, TestUtils } = require('../lib');
|
||||
const { CrossTrainedRecognizerSet, RegexRecognizer, IntentPattern } = require('botbuilder-dialogs-adaptive');
|
||||
const { TestUtils } = require('../lib');
|
||||
const {
|
||||
crossTrainText,
|
||||
xIntentText,
|
||||
|
@ -15,6 +7,8 @@ const {
|
|||
spyOnTelemetryClientTrackEvent,
|
||||
} = require('./recognizerTelemetryUtils');
|
||||
|
||||
const { makeResourceExplorer } = require('./utils');
|
||||
|
||||
const createRecognizer = () =>
|
||||
new CrossTrainedRecognizerSet().configure({
|
||||
recognizers: [
|
||||
|
@ -34,16 +28,10 @@ const createRecognizer = () =>
|
|||
});
|
||||
|
||||
describe('CrossTrainedRecognizerSetTests', function () {
|
||||
this.timeout(5000);
|
||||
|
||||
ComponentRegistration.add(new AdaptiveComponentRegistration());
|
||||
ComponentRegistration.add(new AdaptiveTestComponentRegistration());
|
||||
|
||||
const resourceExplorer = new ResourceExplorer().addFolder(
|
||||
path.join(__dirname, 'resources/CrossTrainedRecognizerSetTests'),
|
||||
true,
|
||||
false
|
||||
);
|
||||
let resourceExplorer;
|
||||
before(function () {
|
||||
resourceExplorer = makeResourceExplorer('CrossTrainedRecognizerSetTests');
|
||||
});
|
||||
|
||||
it('AllNone', async () => {
|
||||
await TestUtils.runTestScript(resourceExplorer, 'CrossTrainedRecognizerSetTests_AllNone');
|
||||
|
|
|
@ -1,20 +1,11 @@
|
|||
const path = require('path');
|
||||
const { ComponentRegistration } = require('botbuilder-core');
|
||||
const { AdaptiveComponentRegistration } = require('botbuilder-dialogs-adaptive');
|
||||
const { ResourceExplorer } = require('botbuilder-dialogs-declarative');
|
||||
const { AdaptiveTestComponentRegistration, TestUtils } = require('../lib');
|
||||
const { TestUtils } = require('../lib');
|
||||
const { makeResourceExplorer } = require('./utils');
|
||||
|
||||
describe('ActionScopeTests', function () {
|
||||
this.timeout(5000);
|
||||
|
||||
ComponentRegistration.add(new AdaptiveComponentRegistration());
|
||||
ComponentRegistration.add(new AdaptiveTestComponentRegistration());
|
||||
|
||||
const resourceExplorer = new ResourceExplorer().addFolder(
|
||||
path.join(__dirname, 'resources/FunctionsTests'),
|
||||
true,
|
||||
false
|
||||
);
|
||||
let resourceExplorer;
|
||||
before(function () {
|
||||
resourceExplorer = makeResourceExplorer('FunctionsTests');
|
||||
});
|
||||
|
||||
it('HasPendingActions', async () => {
|
||||
await TestUtils.runTestScript(resourceExplorer, 'hasPendingActions');
|
||||
|
|
|
@ -1,20 +1,11 @@
|
|||
const path = require('path');
|
||||
const { ComponentRegistration } = require('botbuilder-core');
|
||||
const { AdaptiveComponentRegistration } = require('botbuilder-dialogs-adaptive');
|
||||
const { ResourceExplorer } = require('botbuilder-dialogs-declarative');
|
||||
const { AdaptiveTestComponentRegistration, TestUtils } = require('../lib');
|
||||
const { TestUtils } = require('../lib');
|
||||
const { makeResourceExplorer } = require('./utils');
|
||||
|
||||
describe('ActionScopeTests', function () {
|
||||
this.timeout(5000);
|
||||
|
||||
ComponentRegistration.add(new AdaptiveComponentRegistration());
|
||||
ComponentRegistration.add(new AdaptiveTestComponentRegistration());
|
||||
|
||||
const resourceExplorer = new ResourceExplorer().addFolder(
|
||||
path.join(__dirname, 'resources/InjectLGTests'),
|
||||
true,
|
||||
false
|
||||
);
|
||||
let resourceExplorer;
|
||||
before(function () {
|
||||
resourceExplorer = makeResourceExplorer('InjectLGTests');
|
||||
});
|
||||
|
||||
it('InjectLGTest', async () => {
|
||||
await TestUtils.runTestScript(resourceExplorer, 'inject');
|
||||
|
|
|
@ -1,20 +1,11 @@
|
|||
const path = require('path');
|
||||
const { ComponentRegistration } = require('botbuilder-core');
|
||||
const { AdaptiveComponentRegistration } = require('botbuilder-dialogs-adaptive');
|
||||
const { ResourceExplorer } = require('botbuilder-dialogs-declarative');
|
||||
const { AdaptiveTestComponentRegistration, TestUtils } = require('../lib');
|
||||
const { TestUtils } = require('../lib');
|
||||
const { makeResourceExplorer } = require('./utils');
|
||||
|
||||
describe('LGGeneratorTests', function () {
|
||||
this.timeout(5000);
|
||||
|
||||
ComponentRegistration.add(new AdaptiveComponentRegistration());
|
||||
ComponentRegistration.add(new AdaptiveTestComponentRegistration());
|
||||
|
||||
const resourceExplorer = new ResourceExplorer().addFolder(
|
||||
path.join(__dirname, 'resources/LGGeneratorTests'),
|
||||
true,
|
||||
false
|
||||
);
|
||||
let resourceExplorer;
|
||||
before(function () {
|
||||
resourceExplorer = makeResourceExplorer('LGGeneratorTests');
|
||||
});
|
||||
|
||||
it('MultiLandE2E', async () => {
|
||||
await TestUtils.runTestScript(resourceExplorer, 'MultiLangE2E');
|
||||
|
|
|
@ -1,31 +1,13 @@
|
|||
const path = require('path');
|
||||
const { ComponentRegistration } = require('botbuilder-core');
|
||||
const { LuisComponentRegistration, LuisAdaptiveRecognizer } = require('botbuilder-ai');
|
||||
const { AdaptiveComponentRegistration } = require('botbuilder-dialogs-adaptive');
|
||||
const { ResourceExplorer } = require('botbuilder-dialogs-declarative');
|
||||
const {
|
||||
AdaptiveTestComponentRegistration,
|
||||
MockLuisLoader,
|
||||
MockLuisRecognizer,
|
||||
TestUtils,
|
||||
useMockLuisSettings,
|
||||
} = require('../lib');
|
||||
const { LuisAdaptiveRecognizer, LuisBotComponent } = require('botbuilder-ai');
|
||||
const { MockLuisLoader, MockLuisRecognizer, TestUtils, useMockLuisSettings } = require('../lib');
|
||||
const { makeResourceExplorer } = require('./utils');
|
||||
|
||||
describe('LuisAdaptiveRecognizerTests', function () {
|
||||
this.timeout(5000);
|
||||
|
||||
ComponentRegistration.add(new AdaptiveComponentRegistration());
|
||||
ComponentRegistration.add(new AdaptiveTestComponentRegistration());
|
||||
ComponentRegistration.add(new LuisComponentRegistration());
|
||||
|
||||
it('Dynamic lists', async () => {
|
||||
const resourceDir = path.join(__dirname, 'resources/LuisAdaptiveRecognizerTests');
|
||||
const config = useMockLuisSettings(resourceDir);
|
||||
const explorer = new ResourceExplorer().addFolder(
|
||||
path.join(__dirname, 'resources/LuisAdaptiveRecognizerTests'),
|
||||
true,
|
||||
false
|
||||
);
|
||||
const explorer = makeResourceExplorer('LuisAdaptiveRecognizerTests', LuisBotComponent);
|
||||
explorer.registerType(LuisAdaptiveRecognizer.$kind, MockLuisRecognizer, new MockLuisLoader(explorer, config));
|
||||
await TestUtils.runTestScript(explorer, 'DynamicLists', undefined, config);
|
||||
});
|
||||
|
@ -33,11 +15,7 @@ describe('LuisAdaptiveRecognizerTests', function () {
|
|||
it('Dynamic lists expression', async () => {
|
||||
const resourceDir = path.join(__dirname, 'resources/LuisAdaptiveRecognizerTests');
|
||||
const config = useMockLuisSettings(resourceDir);
|
||||
const explorer = new ResourceExplorer().addFolder(
|
||||
path.join(__dirname, 'resources/LuisAdaptiveRecognizerTests'),
|
||||
true,
|
||||
false
|
||||
);
|
||||
const explorer = makeResourceExplorer('LuisAdaptiveRecognizerTests', LuisBotComponent);
|
||||
explorer.registerType(LuisAdaptiveRecognizer.$kind, MockLuisRecognizer, new MockLuisLoader(explorer, config));
|
||||
await TestUtils.runTestScript(explorer, 'DynamicListsExpression', undefined, config);
|
||||
});
|
||||
|
@ -45,11 +23,7 @@ describe('LuisAdaptiveRecognizerTests', function () {
|
|||
it('ExternalEntities', async () => {
|
||||
const resourceDir = path.join(__dirname, 'resources/LuisAdaptiveRecognizerTests');
|
||||
const config = useMockLuisSettings(resourceDir);
|
||||
const explorer = new ResourceExplorer().addFolder(
|
||||
path.join(__dirname, 'resources/LuisAdaptiveRecognizerTests'),
|
||||
true,
|
||||
false
|
||||
);
|
||||
const explorer = makeResourceExplorer('LuisAdaptiveRecognizerTests', LuisBotComponent);
|
||||
explorer.registerType(LuisAdaptiveRecognizer.$kind, MockLuisRecognizer, new MockLuisLoader(explorer, config));
|
||||
await TestUtils.runTestScript(explorer, 'ExternalEntities', undefined, config);
|
||||
});
|
||||
|
|
|
@ -1,16 +1,11 @@
|
|||
const path = require('path');
|
||||
const { ComponentRegistration } = require('botbuilder-core');
|
||||
const { AdaptiveComponentRegistration } = require('botbuilder-dialogs-adaptive');
|
||||
const { ResourceExplorer } = require('botbuilder-dialogs-declarative');
|
||||
const { AdaptiveTestComponentRegistration, TestUtils } = require('../lib');
|
||||
const { TestUtils } = require('../lib');
|
||||
const { makeResourceExplorer } = require('./utils');
|
||||
|
||||
describe('MiscTests', function () {
|
||||
this.timeout(10000);
|
||||
|
||||
ComponentRegistration.add(new AdaptiveComponentRegistration());
|
||||
ComponentRegistration.add(new AdaptiveTestComponentRegistration());
|
||||
|
||||
const resourceExplorer = new ResourceExplorer().addFolder(path.join(__dirname, 'resources/MiscTests'), true, false);
|
||||
let resourceExplorer;
|
||||
before(function () {
|
||||
resourceExplorer = makeResourceExplorer('MiscTests');
|
||||
});
|
||||
|
||||
it('IfCondition_EndDialog', async () => {
|
||||
await TestUtils.runTestScript(resourceExplorer, 'IfCondition_EndDialog');
|
||||
|
|
|
@ -1,18 +1,11 @@
|
|||
const path = require('path');
|
||||
const { ComponentRegistration } = require('botbuilder-core');
|
||||
const { AdaptiveComponentRegistration } = require('botbuilder-dialogs-adaptive');
|
||||
const { ResourceExplorer } = require('botbuilder-dialogs-declarative');
|
||||
const { AdaptiveTestComponentRegistration, TestUtils } = require('../lib');
|
||||
const { TestUtils } = require('../lib');
|
||||
const { makeResourceExplorer } = require('./utils');
|
||||
|
||||
describe('MultiLanguageGeneratorTests', function () {
|
||||
ComponentRegistration.add(new AdaptiveComponentRegistration());
|
||||
ComponentRegistration.add(new AdaptiveTestComponentRegistration());
|
||||
|
||||
const resourceExplorer = new ResourceExplorer().addFolder(
|
||||
path.join(__dirname, 'resources/MultiLanguageGeneratorTests'),
|
||||
true,
|
||||
false
|
||||
);
|
||||
let resourceExplorer;
|
||||
before(function () {
|
||||
resourceExplorer = makeResourceExplorer('MultiLanguageGeneratorTests');
|
||||
});
|
||||
|
||||
it('Switch Language Activity', async () => {
|
||||
await TestUtils.runTestScript(resourceExplorer, 'SwitchLanguageActivity');
|
||||
|
|
|
@ -1,13 +1,7 @@
|
|||
const path = require('path');
|
||||
const { ComponentRegistration } = require('botbuilder-core');
|
||||
const {
|
||||
AdaptiveComponentRegistration,
|
||||
MultiLanguageRecognizer,
|
||||
RegexRecognizer,
|
||||
IntentPattern,
|
||||
} = require('botbuilder-dialogs-adaptive');
|
||||
const { ResourceExplorer } = require('botbuilder-dialogs-declarative');
|
||||
const { AdaptiveTestComponentRegistration, TestUtils } = require('../lib');
|
||||
const { MultiLanguageRecognizer, RegexRecognizer, IntentPattern } = require('botbuilder-dialogs-adaptive');
|
||||
const { TestUtils } = require('../lib');
|
||||
const { makeResourceExplorer } = require('./utils');
|
||||
|
||||
const {
|
||||
greetingIntentTextEnUs,
|
||||
recognizeIntentAndValidateTelemetry,
|
||||
|
@ -30,16 +24,10 @@ const createRecognizer = () =>
|
|||
});
|
||||
|
||||
describe('MultiLanguageRecognizerTests', function () {
|
||||
this.timeout(5000);
|
||||
|
||||
ComponentRegistration.add(new AdaptiveComponentRegistration());
|
||||
ComponentRegistration.add(new AdaptiveTestComponentRegistration());
|
||||
|
||||
const resourceExplorer = new ResourceExplorer().addFolder(
|
||||
path.join(__dirname, 'resources/MultiLanguageRecognizerTests'),
|
||||
true,
|
||||
false
|
||||
);
|
||||
let resourceExplorer;
|
||||
before(function () {
|
||||
resourceExplorer = makeResourceExplorer('MultiLanguageRecognizerTests');
|
||||
});
|
||||
|
||||
it('DefaultFallback', async () => {
|
||||
await TestUtils.runTestScript(resourceExplorer, 'MultiLanguageRecognizerTest_DefaultFallback');
|
||||
|
|
|
@ -1,23 +1,15 @@
|
|||
const path = require('path');
|
||||
const nock = require('nock');
|
||||
const { ComponentRegistration } = require('botbuilder-core');
|
||||
const { QnAMakerComponentRegistration } = require('botbuilder-ai');
|
||||
const { AdaptiveComponentRegistration } = require('botbuilder-dialogs-adaptive');
|
||||
const { ResourceExplorer } = require('botbuilder-dialogs-declarative');
|
||||
const { AdaptiveTestComponentRegistration, TestUtils } = require('../lib');
|
||||
const path = require('path');
|
||||
const { QnAMakerBotComponent } = require('botbuilder-ai');
|
||||
const { TestUtils } = require('../lib');
|
||||
const { makeResourceExplorer } = require('./utils');
|
||||
|
||||
describe('QnAMakerRecognizerTests', function () {
|
||||
this.timeout(5000);
|
||||
let resourceExplorer;
|
||||
before(function () {
|
||||
resourceExplorer = makeResourceExplorer('QnAMakerRecognizerTests', QnAMakerBotComponent);
|
||||
});
|
||||
|
||||
ComponentRegistration.add(new AdaptiveComponentRegistration());
|
||||
ComponentRegistration.add(new AdaptiveTestComponentRegistration());
|
||||
ComponentRegistration.add(new QnAMakerComponentRegistration());
|
||||
|
||||
const resourceExplorer = new ResourceExplorer().addFolder(
|
||||
path.join(__dirname, 'resources/QnAMakerRecognizerTests'),
|
||||
true,
|
||||
false
|
||||
);
|
||||
const hostname = 'https://dummy-hostname.azurewebsites.net';
|
||||
|
||||
it('returns answer', async () => {
|
||||
|
|
|
@ -1,14 +1,7 @@
|
|||
const path = require('path');
|
||||
const { ComponentRegistration } = require('botbuilder-core');
|
||||
const {
|
||||
AdaptiveComponentRegistration,
|
||||
EntityRecognizerSet,
|
||||
RecognizerSet,
|
||||
RegexRecognizer,
|
||||
IntentPattern,
|
||||
} = require('botbuilder-dialogs-adaptive');
|
||||
const { ResourceExplorer } = require('botbuilder-dialogs-declarative');
|
||||
const { AdaptiveTestComponentRegistration, TestUtils } = require('../lib');
|
||||
const { EntityRecognizerSet, RecognizerSet, RegexRecognizer, IntentPattern } = require('botbuilder-dialogs-adaptive');
|
||||
const { TestUtils } = require('../lib');
|
||||
const { makeResourceExplorer } = require('./utils');
|
||||
|
||||
const {
|
||||
AgeEntityRecognizer,
|
||||
NumberEntityRecognizer,
|
||||
|
@ -55,16 +48,10 @@ const createRecognizer = () =>
|
|||
});
|
||||
|
||||
describe('RecognizerSetTests', function () {
|
||||
this.timeout(5000);
|
||||
|
||||
ComponentRegistration.add(new AdaptiveComponentRegistration());
|
||||
ComponentRegistration.add(new AdaptiveTestComponentRegistration());
|
||||
|
||||
const resourceExplorer = new ResourceExplorer().addFolder(
|
||||
path.join(__dirname, 'resources/RecognizerSetTests'),
|
||||
true,
|
||||
false
|
||||
);
|
||||
let resourceExplorer;
|
||||
before(function () {
|
||||
resourceExplorer = makeResourceExplorer('RecognizerSetTests');
|
||||
});
|
||||
|
||||
it('Merge', async () => {
|
||||
await TestUtils.runTestScript(resourceExplorer, 'RecognizerSetTests_Merge');
|
||||
|
|
|
@ -1,20 +1,11 @@
|
|||
const path = require('path');
|
||||
const { ComponentRegistration } = require('botbuilder-core');
|
||||
const { AdaptiveComponentRegistration } = require('botbuilder-dialogs-adaptive');
|
||||
const { ResourceExplorer } = require('botbuilder-dialogs-declarative');
|
||||
const { AdaptiveTestComponentRegistration, TestUtils } = require('../lib');
|
||||
const { TestUtils } = require('../lib');
|
||||
const { makeResourceExplorer } = require('./utils');
|
||||
|
||||
describe('RegexRecognizerTests', function () {
|
||||
this.timeout(5000);
|
||||
|
||||
ComponentRegistration.add(new AdaptiveComponentRegistration());
|
||||
ComponentRegistration.add(new AdaptiveTestComponentRegistration());
|
||||
|
||||
const resourceExplorer = new ResourceExplorer().addFolder(
|
||||
path.join(__dirname, 'resources/RegexRecognizerTests'),
|
||||
true,
|
||||
false
|
||||
);
|
||||
let resourceExplorer;
|
||||
before(function () {
|
||||
resourceExplorer = makeResourceExplorer('RegexRecognizerTests');
|
||||
});
|
||||
|
||||
it('Entities', async () => {
|
||||
await TestUtils.runTestScript(resourceExplorer, 'RegexRecognizerTests_Entities');
|
||||
|
|
|
@ -1,20 +1,11 @@
|
|||
const path = require('path');
|
||||
const { ComponentRegistration } = require('botbuilder-core');
|
||||
const { AdaptiveComponentRegistration } = require('botbuilder-dialogs-adaptive');
|
||||
const { ResourceExplorer } = require('botbuilder-dialogs-declarative');
|
||||
const { AdaptiveTestComponentRegistration, TestUtils } = require('../lib');
|
||||
const { TestUtils } = require('..');
|
||||
const { makeResourceExplorer } = require('./utils');
|
||||
|
||||
describe('SelectorTests', function () {
|
||||
this.timeout(10000);
|
||||
|
||||
ComponentRegistration.add(new AdaptiveComponentRegistration());
|
||||
ComponentRegistration.add(new AdaptiveTestComponentRegistration());
|
||||
|
||||
const resourceExplorer = new ResourceExplorer().addFolder(
|
||||
path.join(__dirname, 'resources/SelectorTests'),
|
||||
true,
|
||||
false
|
||||
);
|
||||
let resourceExplorer;
|
||||
before(function () {
|
||||
resourceExplorer = makeResourceExplorer('SelectorTests');
|
||||
});
|
||||
|
||||
it('ConditionalSelector', async () => {
|
||||
await TestUtils.runTestScript(resourceExplorer, 'SelectorTests_ConditionalSelector');
|
||||
|
|
|
@ -1,20 +1,12 @@
|
|||
const path = require('path');
|
||||
const { ComponentRegistration } = require('botbuilder-core');
|
||||
const { AdaptiveComponentRegistration } = require('botbuilder-dialogs-adaptive');
|
||||
const { ResourceExplorer } = require('botbuilder-dialogs-declarative');
|
||||
const { AdaptiveTestComponentRegistration, TestUtils } = require('../lib');
|
||||
const { TestUtils } = require('..');
|
||||
const { makeResourceExplorer } = require('./utils');
|
||||
|
||||
describe('SettingsStateTests', function () {
|
||||
this.timeout(10000);
|
||||
let resourceExplorer;
|
||||
before(function () {
|
||||
resourceExplorer = makeResourceExplorer('SettingsStateTests');
|
||||
});
|
||||
|
||||
ComponentRegistration.add(new AdaptiveComponentRegistration());
|
||||
ComponentRegistration.add(new AdaptiveTestComponentRegistration());
|
||||
|
||||
const resourceExplorer = new ResourceExplorer().addFolder(
|
||||
path.join(__dirname, 'resources/SettingsStateTests'),
|
||||
true,
|
||||
false
|
||||
);
|
||||
process.env['MicrosoftAppId'] = 'MICROSOFT_APP_ID';
|
||||
process.env['MicrosoftAppPassword'] = 'MICROSOFT_APP_PASSWORD';
|
||||
process.env['ApplicationInsightsInstrumentationKey'] = '00000000-0000-0000-0000-000000000000';
|
||||
|
|
|
@ -1,28 +1,14 @@
|
|||
const assert = require('assert');
|
||||
const path = require('path');
|
||||
const { ComponentRegistration } = require('botbuilder-core');
|
||||
const { AdaptiveComponentRegistration } = require('botbuilder-dialogs-adaptive');
|
||||
const { ResourceExplorer } = require('botbuilder-dialogs-declarative');
|
||||
const {
|
||||
AdaptiveTestComponentRegistration,
|
||||
MockLuisLoader,
|
||||
MockLuisRecognizer,
|
||||
TestUtils,
|
||||
useMockLuisSettings,
|
||||
} = require('../lib');
|
||||
const { LuisAdaptiveRecognizer } = require('botbuilder-ai');
|
||||
const { LuisAdaptiveRecognizer, QnAMakerBotComponent } = require('botbuilder-ai');
|
||||
const { MockLuisLoader, MockLuisRecognizer, TestUtils, useMockLuisSettings } = require('../lib');
|
||||
const { makeResourceExplorer } = require('./utils');
|
||||
|
||||
describe('TestScriptTests', function () {
|
||||
this.timeout(5000);
|
||||
|
||||
ComponentRegistration.add(new AdaptiveComponentRegistration());
|
||||
ComponentRegistration.add(new AdaptiveTestComponentRegistration());
|
||||
|
||||
const resourceExplorer = new ResourceExplorer().addFolder(
|
||||
path.join(__dirname, 'resources/TestScriptTests'),
|
||||
true,
|
||||
false
|
||||
);
|
||||
let resourceExplorer;
|
||||
before(function () {
|
||||
resourceExplorer = makeResourceExplorer('TestScriptTests', QnAMakerBotComponent);
|
||||
});
|
||||
|
||||
it('AssertReply_Assertions', async () => {
|
||||
await TestUtils.runTestScript(resourceExplorer, 'TestScriptTests_AssertReply_Assertions');
|
||||
|
@ -83,13 +69,12 @@ describe('TestScriptTests', function () {
|
|||
it('HttpRequestLuisMock', async () => {
|
||||
const resourceDir = path.join(__dirname, 'resources/TestScriptTests/LuisMock');
|
||||
const config = useMockLuisSettings(resourceDir);
|
||||
const explorer = new ResourceExplorer().addFolder(
|
||||
path.join(__dirname, 'resources/TestScriptTests'),
|
||||
true,
|
||||
false
|
||||
resourceExplorer.registerType(
|
||||
LuisAdaptiveRecognizer.$kind,
|
||||
MockLuisRecognizer,
|
||||
new MockLuisLoader(resourceExplorer, config)
|
||||
);
|
||||
explorer.registerType(LuisAdaptiveRecognizer.$kind, MockLuisRecognizer, new MockLuisLoader(explorer, config));
|
||||
await TestUtils.runTestScript(explorer, 'TestScriptTests_HttpRequestLuisMock', undefined, config);
|
||||
await TestUtils.runTestScript(resourceExplorer, 'TestScriptTests_HttpRequestLuisMock', undefined, config);
|
||||
});
|
||||
|
||||
it('HttpRequestMock', async () => {
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
const path = require('path');
|
||||
const { AdaptiveBotComponent } = require('botbuilder-dialogs-adaptive');
|
||||
const { AdaptiveTestBotComponent } = require('..');
|
||||
const { ResourceExplorer } = require('botbuilder-dialogs-declarative');
|
||||
const { ServiceCollection, noOpConfiguration } = require('botbuilder-runtime-core');
|
||||
|
||||
function makeResourceExplorer(resourceFolder, ...botComponents) {
|
||||
const services = new ServiceCollection({
|
||||
declarativeTypes: [],
|
||||
});
|
||||
|
||||
new AdaptiveBotComponent().configureServices(services, noOpConfiguration);
|
||||
new AdaptiveTestBotComponent().configureServices(services, noOpConfiguration);
|
||||
|
||||
botComponents.forEach((BotComponent) => {
|
||||
new BotComponent().configureServices(services, noOpConfiguration);
|
||||
});
|
||||
|
||||
const declarativeTypes = services.mustMakeInstance('declarativeTypes');
|
||||
|
||||
return new ResourceExplorer({
|
||||
declarativeTypes,
|
||||
}).addFolder(path.join(__dirname, 'resources', resourceFolder), true, false);
|
||||
}
|
||||
|
||||
module.exports = { makeResourceExplorer };
|
|
@ -1,20 +1,11 @@
|
|||
const path = require('path');
|
||||
const { ComponentRegistration } = require('botbuilder-core');
|
||||
const { AdaptiveComponentRegistration } = require('botbuilder-dialogs-adaptive');
|
||||
const { ResourceExplorer } = require('botbuilder-dialogs-declarative');
|
||||
const { AdaptiveTestComponentRegistration, TestUtils } = require('../lib');
|
||||
const { TestUtils } = require('..');
|
||||
const { makeResourceExplorer } = require('./utils');
|
||||
|
||||
describe('ValueRecognizerTests', function () {
|
||||
this.timeout(5000);
|
||||
|
||||
ComponentRegistration.add(new AdaptiveComponentRegistration());
|
||||
ComponentRegistration.add(new AdaptiveTestComponentRegistration());
|
||||
|
||||
const resourceExplorer = new ResourceExplorer().addFolder(
|
||||
path.join(__dirname, 'resources/ValueRecognizerTests'),
|
||||
true,
|
||||
false
|
||||
);
|
||||
let resourceExplorer;
|
||||
before(function () {
|
||||
resourceExplorer = makeResourceExplorer('ValueRecognizerTests');
|
||||
});
|
||||
|
||||
it('WithIntent', async () => {
|
||||
await TestUtils.runTestScript(resourceExplorer, 'ValueRecognizerTests_WithIntent');
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
"botbuilder-dialogs": "4.1.6",
|
||||
"botbuilder-dialogs-declarative": "4.1.6",
|
||||
"botbuilder-lg": "4.1.6",
|
||||
"botbuilder-runtime-core": "4.1.6",
|
||||
"botframework-connector": "4.1.6",
|
||||
"botframework-schema": "4.1.6",
|
||||
"lodash": "^4.17.21",
|
||||
|
|
|
@ -0,0 +1,268 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
import { AdaptiveDialog } from './adaptiveDialog';
|
||||
import { BotComponent } from 'botbuilder';
|
||||
import { ComponentDeclarativeTypes } from 'botbuilder-dialogs-declarative';
|
||||
import { ConditionalSelector, FirstSelector, MostSpecificSelector, RandomSelector, TrueSelector } from './selectors';
|
||||
import { Configuration, ServiceCollection } from 'botbuilder-runtime-core';
|
||||
import { DynamicBeginDialogDeserializer } from './dynamicBeginDialogDeserializer';
|
||||
import { Expression } from 'adaptive-expressions';
|
||||
import { HasPendingActionsFunction, IsDialogActiveFunction } from './functions';
|
||||
import { ResourceMultiLanguageGenerator, TemplateEngineLanguageGenerator } from './generators';
|
||||
|
||||
import {
|
||||
BeginDialog,
|
||||
BeginSkill,
|
||||
BreakLoop,
|
||||
CancelAllDialogs,
|
||||
CancelDialog,
|
||||
ContinueConversation,
|
||||
ContinueConversationLater,
|
||||
ContinueLoop,
|
||||
DeleteActivity,
|
||||
DeleteProperties,
|
||||
DeleteProperty,
|
||||
DynamicBeginDialog,
|
||||
EditActions,
|
||||
EditArray,
|
||||
EmitEvent,
|
||||
EndDialog,
|
||||
EndTurn,
|
||||
ForEach,
|
||||
ForEachPage,
|
||||
GetActivityMembers,
|
||||
GetConversationMembers,
|
||||
GetConversationReference,
|
||||
GotoAction,
|
||||
HttpRequest,
|
||||
IfCondition,
|
||||
LogAction,
|
||||
RepeatDialog,
|
||||
ReplaceDialog,
|
||||
SendActivity,
|
||||
SendHandoffActivity,
|
||||
SetProperties,
|
||||
SetProperty,
|
||||
SignOutUser,
|
||||
SwitchCondition,
|
||||
TelemetryTrackEventAction,
|
||||
TraceActivity,
|
||||
ThrowException,
|
||||
UpdateActivity,
|
||||
} from './actions';
|
||||
|
||||
import {
|
||||
OnActivity,
|
||||
OnAssignEntity,
|
||||
OnBeginDialog,
|
||||
OnCancelDialog,
|
||||
OnChooseEntity,
|
||||
OnChooseIntent,
|
||||
OnChooseProperty,
|
||||
OnCondition,
|
||||
OnContinueConversation,
|
||||
OnConversationUpdateActivity,
|
||||
OnDialogEvent,
|
||||
OnEndOfActions,
|
||||
OnEndOfConversationActivity,
|
||||
OnError,
|
||||
OnEventActivity,
|
||||
OnHandoffActivity,
|
||||
OnInstallationUpdateActivity,
|
||||
OnIntent,
|
||||
OnInvokeActivity,
|
||||
OnMessageActivity,
|
||||
OnMessageDeleteActivity,
|
||||
OnMessageReactionActivity,
|
||||
OnMessageUpdateActivity,
|
||||
OnQnAMatch,
|
||||
OnRepromptDialog,
|
||||
OnTypingActivity,
|
||||
OnUnknownIntent,
|
||||
} from './conditions';
|
||||
|
||||
import {
|
||||
Ask,
|
||||
AttachmentInput,
|
||||
ChoiceInput,
|
||||
ConfirmInput,
|
||||
DateTimeInput,
|
||||
NumberInput,
|
||||
OAuthInput,
|
||||
TextInput,
|
||||
} from './input';
|
||||
|
||||
import {
|
||||
AgeEntityRecognizer,
|
||||
ChannelMentionEntityRecognizer,
|
||||
ConfirmationEntityRecognizer,
|
||||
CrossTrainedRecognizerSet,
|
||||
CurrencyEntityRecognizer,
|
||||
DateTimeEntityRecognizer,
|
||||
DimensionEntityRecognizer,
|
||||
EmailEntityRecognizer,
|
||||
EntityRecognizerSet,
|
||||
GuidEntityRecognizer,
|
||||
HashtagEntityRecognizer,
|
||||
IpEntityRecognizer,
|
||||
MentionEntityRecognizer,
|
||||
MultiLanguageRecognizer,
|
||||
NumberEntityRecognizer,
|
||||
OrdinalEntityRecognizer,
|
||||
PercentageEntityRecognizer,
|
||||
PhoneNumberEntityRecognizer,
|
||||
RecognizerSet,
|
||||
RegexEntityRecognizer,
|
||||
RegexRecognizer,
|
||||
TemperatureEntityRecognizer,
|
||||
UrlEntityRecognizer,
|
||||
} from './recognizers';
|
||||
|
||||
export class AdaptiveBotComponent extends BotComponent {
|
||||
configureServices(services: ServiceCollection, _configuration: Configuration): void {
|
||||
Expression.functions.add(IsDialogActiveFunction.functionName, new IsDialogActiveFunction());
|
||||
Expression.functions.add(IsDialogActiveFunction.functionAlias, new IsDialogActiveFunction());
|
||||
Expression.functions.add(HasPendingActionsFunction.functionName, new HasPendingActionsFunction());
|
||||
|
||||
services.composeFactory<ComponentDeclarativeTypes[]>('declarativeTypes', (declarativeTypes) =>
|
||||
declarativeTypes.concat(
|
||||
{
|
||||
getDeclarativeTypes() {
|
||||
return [
|
||||
// Adaptive Dialog
|
||||
{ kind: AdaptiveDialog.$kind, type: AdaptiveDialog },
|
||||
|
||||
// Actions
|
||||
{ kind: BeginDialog.$kind, type: BeginDialog },
|
||||
{ kind: BeginSkill.$kind, type: BeginSkill },
|
||||
{ kind: BreakLoop.$kind, type: BreakLoop },
|
||||
{ kind: CancelAllDialogs.$kind, type: CancelAllDialogs },
|
||||
{ kind: CancelDialog.$kind, type: CancelDialog },
|
||||
{ kind: ContinueConversation.$kind, type: ContinueConversation },
|
||||
{ kind: ContinueConversationLater.$kind, type: ContinueConversation },
|
||||
{ kind: ContinueLoop.$kind, type: ContinueLoop },
|
||||
{ kind: DeleteActivity.$kind, type: DeleteActivity },
|
||||
{ kind: DeleteProperties.$kind, type: DeleteProperties },
|
||||
{ kind: DeleteProperty.$kind, type: DeleteProperty },
|
||||
{ kind: EditActions.$kind, type: EditActions },
|
||||
{ kind: EditArray.$kind, type: EditArray },
|
||||
{ kind: EmitEvent.$kind, type: EmitEvent },
|
||||
{ kind: EndDialog.$kind, type: EndDialog },
|
||||
{ kind: EndTurn.$kind, type: EndTurn },
|
||||
{ kind: ForEach.$kind, type: ForEach },
|
||||
{ kind: ForEachPage.$kind, type: ForEachPage },
|
||||
{ kind: GetActivityMembers.$kind, type: GetActivityMembers },
|
||||
{ kind: GetConversationMembers.$kind, type: GetConversationMembers },
|
||||
{ kind: GetConversationReference.$kind, type: GetConversationReference },
|
||||
{ kind: GotoAction.$kind, type: GotoAction },
|
||||
{ kind: HttpRequest.$kind, type: HttpRequest },
|
||||
{ kind: IfCondition.$kind, type: IfCondition },
|
||||
{ kind: LogAction.$kind, type: LogAction },
|
||||
{ kind: RepeatDialog.$kind, type: RepeatDialog },
|
||||
{ kind: ReplaceDialog.$kind, type: ReplaceDialog },
|
||||
{ kind: SendActivity.$kind, type: SendActivity },
|
||||
{ kind: SendHandoffActivity.$kind, type: SendHandoffActivity },
|
||||
{ kind: SetProperties.$kind, type: SetProperties },
|
||||
{ kind: SetProperty.$kind, type: SetProperty },
|
||||
{ kind: SignOutUser.$kind, type: SignOutUser },
|
||||
{ kind: SwitchCondition.$kind, type: SwitchCondition },
|
||||
{ kind: TelemetryTrackEventAction.$kind, type: TelemetryTrackEventAction },
|
||||
{ kind: ThrowException.$kind, type: ThrowException },
|
||||
{ kind: TraceActivity.$kind, type: TraceActivity },
|
||||
{ kind: UpdateActivity.$kind, type: UpdateActivity },
|
||||
|
||||
// Trigger conditions
|
||||
{ kind: OnActivity.$kind, type: OnActivity },
|
||||
{ kind: OnAssignEntity.$kind, type: OnAssignEntity },
|
||||
{ kind: OnBeginDialog.$kind, type: OnBeginDialog },
|
||||
{ kind: OnCancelDialog.$kind, type: OnCancelDialog },
|
||||
{ kind: OnChooseEntity.$kind, type: OnChooseEntity },
|
||||
{ kind: OnChooseIntent.$kind, type: OnChooseIntent },
|
||||
{ kind: OnChooseProperty.$kind, type: OnChooseProperty },
|
||||
{ kind: OnCondition.$kind, type: OnCondition },
|
||||
{ kind: OnContinueConversation.$kind, type: OnContinueConversation },
|
||||
{ kind: OnConversationUpdateActivity.$kind, type: OnConversationUpdateActivity },
|
||||
{ kind: OnDialogEvent.$kind, type: OnDialogEvent },
|
||||
{ kind: OnEndOfActions.$kind, type: OnEndOfActions },
|
||||
{ kind: OnEndOfConversationActivity.$kind, type: OnEndOfConversationActivity },
|
||||
{ kind: OnError.$kind, type: OnError },
|
||||
{ kind: OnEventActivity.$kind, type: OnEventActivity },
|
||||
{ kind: OnHandoffActivity.$kind, type: OnHandoffActivity },
|
||||
{ kind: OnInstallationUpdateActivity.$kind, type: OnInstallationUpdateActivity },
|
||||
{ kind: OnIntent.$kind, type: OnIntent },
|
||||
{ kind: OnInvokeActivity.$kind, type: OnInvokeActivity },
|
||||
{ kind: OnMessageActivity.$kind, type: OnMessageActivity },
|
||||
{ kind: OnMessageDeleteActivity.$kind, type: OnMessageDeleteActivity },
|
||||
{ kind: OnMessageReactionActivity.$kind, type: OnMessageReactionActivity },
|
||||
{ kind: OnMessageUpdateActivity.$kind, type: OnMessageUpdateActivity },
|
||||
{ kind: OnQnAMatch.$kind, type: OnQnAMatch },
|
||||
{ kind: OnRepromptDialog.$kind, type: OnRepromptDialog },
|
||||
{ kind: OnTypingActivity.$kind, type: OnTypingActivity },
|
||||
{ kind: OnUnknownIntent.$kind, type: OnUnknownIntent },
|
||||
|
||||
// Inputs
|
||||
{ kind: Ask.$kind, type: Ask },
|
||||
{ kind: AttachmentInput.$kind, type: AttachmentInput },
|
||||
{ kind: ChoiceInput.$kind, type: ChoiceInput },
|
||||
{ kind: ConfirmInput.$kind, type: ConfirmInput },
|
||||
{ kind: DateTimeInput.$kind, type: DateTimeInput },
|
||||
{ kind: NumberInput.$kind, type: NumberInput },
|
||||
{ kind: OAuthInput.$kind, type: OAuthInput },
|
||||
{ kind: TextInput.$kind, type: TextInput },
|
||||
|
||||
// Recognizers
|
||||
{ kind: CrossTrainedRecognizerSet.$kind, type: CrossTrainedRecognizerSet },
|
||||
{ kind: MultiLanguageRecognizer.$kind, type: MultiLanguageRecognizer },
|
||||
{ kind: RecognizerSet.$kind, type: RecognizerSet },
|
||||
{ kind: RegexRecognizer.$kind, type: RegexRecognizer },
|
||||
{ kind: AgeEntityRecognizer.$kind, type: AgeEntityRecognizer },
|
||||
{ kind: ChannelMentionEntityRecognizer.$kind, type: ChannelMentionEntityRecognizer },
|
||||
{ kind: ConfirmationEntityRecognizer.$kind, type: ConfirmationEntityRecognizer },
|
||||
{ kind: CurrencyEntityRecognizer.$kind, type: CurrencyEntityRecognizer },
|
||||
{ kind: DateTimeEntityRecognizer.$kind, type: DateTimeEntityRecognizer },
|
||||
{ kind: DimensionEntityRecognizer.$kind, type: DimensionEntityRecognizer },
|
||||
{ kind: EmailEntityRecognizer.$kind, type: EmailEntityRecognizer },
|
||||
{ kind: EntityRecognizerSet.$kind, type: EntityRecognizerSet },
|
||||
{ kind: GuidEntityRecognizer.$kind, type: GuidEntityRecognizer },
|
||||
{ kind: HashtagEntityRecognizer.$kind, type: HashtagEntityRecognizer },
|
||||
{ kind: IpEntityRecognizer.$kind, type: IpEntityRecognizer },
|
||||
{ kind: MentionEntityRecognizer.$kind, type: MentionEntityRecognizer },
|
||||
{ kind: NumberEntityRecognizer.$kind, type: NumberEntityRecognizer },
|
||||
{ kind: OrdinalEntityRecognizer.$kind, type: OrdinalEntityRecognizer },
|
||||
{ kind: PercentageEntityRecognizer.$kind, type: PercentageEntityRecognizer },
|
||||
{ kind: PhoneNumberEntityRecognizer.$kind, type: PhoneNumberEntityRecognizer },
|
||||
{ kind: RegexEntityRecognizer.$kind, type: RegexEntityRecognizer },
|
||||
{ kind: TemperatureEntityRecognizer.$kind, type: TemperatureEntityRecognizer },
|
||||
{ kind: UrlEntityRecognizer.$kind, type: UrlEntityRecognizer },
|
||||
|
||||
// Generators
|
||||
{ kind: TemplateEngineLanguageGenerator.$kind, type: TemplateEngineLanguageGenerator },
|
||||
{ kind: ResourceMultiLanguageGenerator.$kind, type: ResourceMultiLanguageGenerator },
|
||||
|
||||
// Selectors
|
||||
{ kind: ConditionalSelector.$kind, type: ConditionalSelector },
|
||||
{ kind: FirstSelector.$kind, type: FirstSelector },
|
||||
{ kind: RandomSelector.$kind, type: RandomSelector },
|
||||
{ kind: TrueSelector.$kind, type: TrueSelector },
|
||||
{ kind: MostSpecificSelector.$kind, type: MostSpecificSelector },
|
||||
];
|
||||
},
|
||||
},
|
||||
{
|
||||
getDeclarativeTypes(resourceExplorer) {
|
||||
return resourceExplorer
|
||||
.getResources('.schema')
|
||||
.map((schema) => schema.id.replace(/.schema$/, ''))
|
||||
.filter((resourceId) => resourceId.endsWith('.dialog'))
|
||||
.map((resourceId) => ({
|
||||
kind: resourceId,
|
||||
type: DynamicBeginDialog,
|
||||
loader: new DynamicBeginDialogDeserializer(resourceExplorer, resourceId),
|
||||
}));
|
||||
},
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,380 +0,0 @@
|
|||
/**
|
||||
* @module botbuilder-dialogs-adaptive
|
||||
*/
|
||||
/**
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License.
|
||||
*/
|
||||
|
||||
import { Expression } from 'adaptive-expressions';
|
||||
import { ComponentRegistration } from 'botbuilder';
|
||||
import {
|
||||
ResourceExplorer,
|
||||
ComponentDeclarativeTypes,
|
||||
DeclarativeType,
|
||||
CustomDeserializer,
|
||||
} from 'botbuilder-dialogs-declarative';
|
||||
import { AdaptiveDialog, AdaptiveDialogConfiguration } from './adaptiveDialog';
|
||||
import {
|
||||
BeginDialog,
|
||||
BeginDialogConfiguration,
|
||||
BeginSkill,
|
||||
BeginSkillConfiguration,
|
||||
BreakLoop,
|
||||
BreakLoopConfiguration,
|
||||
CancelAllDialogs,
|
||||
CancelDialog,
|
||||
CancelAllDialogsBaseConfiguration,
|
||||
ContinueConversation,
|
||||
ContinueConversationConfiguration,
|
||||
ContinueConversationLater,
|
||||
ContinueConversationLaterConfiguration,
|
||||
ContinueLoop,
|
||||
ContinueLoopConfiguration,
|
||||
DeleteActivity,
|
||||
DeleteActivityConfiguration,
|
||||
DeleteProperties,
|
||||
DeletePropertiesConfiguration,
|
||||
DeleteProperty,
|
||||
DeletePropertyConfiguration,
|
||||
DynamicBeginDialog,
|
||||
EditActions,
|
||||
EditActionsConfiguration,
|
||||
EditArray,
|
||||
EditArrayConfiguration,
|
||||
EmitEvent,
|
||||
EmitEventConfiguration,
|
||||
EndDialog,
|
||||
EndDialogConfiguration,
|
||||
EndTurn,
|
||||
EndTurnConfiguration,
|
||||
ForEach,
|
||||
ForEachConfiguration,
|
||||
ForEachPage,
|
||||
ForEachPageConfiguration,
|
||||
GetActivityMembers,
|
||||
GetActivityMembersConfiguration,
|
||||
GetConversationMembers,
|
||||
GetConversationMembersConfiguration,
|
||||
GetConversationReference,
|
||||
GetConversationReferenceConfiguration,
|
||||
GotoAction,
|
||||
GotoActionConfiguration,
|
||||
HttpRequest,
|
||||
HttpRequestConfiguration,
|
||||
IfCondition,
|
||||
IfConditionConfiguration,
|
||||
LogAction,
|
||||
LogActionConfiguration,
|
||||
RepeatDialog,
|
||||
RepeatDialogConfiguration,
|
||||
ReplaceDialog,
|
||||
ReplaceDialogConfiguration,
|
||||
SendActivity,
|
||||
SendActivityConfiguration,
|
||||
SendHandoffActivity,
|
||||
SendHandoffActivityConfiguration,
|
||||
SetProperties,
|
||||
SetPropertiesConfiguration,
|
||||
SetProperty,
|
||||
SetPropertyConfiguration,
|
||||
SignOutUser,
|
||||
SignOutUserConfiguration,
|
||||
SwitchCondition,
|
||||
SwitchConditionConfiguration,
|
||||
TelemetryTrackEventAction,
|
||||
TelemetryTrackEventActionConfiguration,
|
||||
TraceActivity,
|
||||
TraceActivityConfiguration,
|
||||
ThrowException,
|
||||
ThrowExceptionConfiguration,
|
||||
UpdateActivity,
|
||||
UpdateActivityConfiguration,
|
||||
} from './actions';
|
||||
import {
|
||||
OnActivity,
|
||||
OnActivityConfiguration,
|
||||
OnAssignEntity,
|
||||
OnAssignEntityConfiguration,
|
||||
OnBeginDialog,
|
||||
OnCancelDialog,
|
||||
OnChooseEntity,
|
||||
OnChooseEntityConfiguration,
|
||||
OnChooseIntent,
|
||||
OnChooseIntentConfiguration,
|
||||
OnChooseProperty,
|
||||
OnCondition,
|
||||
OnConditionConfiguration,
|
||||
OnContinueConversation,
|
||||
OnConversationUpdateActivity,
|
||||
OnDialogEvent,
|
||||
OnDialogEventConfiguration,
|
||||
OnEndOfActions,
|
||||
OnEndOfConversationActivity,
|
||||
OnError,
|
||||
OnEventActivity,
|
||||
OnHandoffActivity,
|
||||
OnInstallationUpdateActivity,
|
||||
OnIntent,
|
||||
OnIntentConfiguration,
|
||||
OnInvokeActivity,
|
||||
OnMessageActivity,
|
||||
OnMessageDeleteActivity,
|
||||
OnMessageReactionActivity,
|
||||
OnMessageUpdateActivity,
|
||||
OnQnAMatch,
|
||||
OnRepromptDialog,
|
||||
OnTypingActivity,
|
||||
OnUnknownIntent,
|
||||
} from './conditions';
|
||||
import {
|
||||
Ask,
|
||||
AskConfiguration,
|
||||
AttachmentInput,
|
||||
AttachmentInputConfiguration,
|
||||
ChoiceInput,
|
||||
ChoiceInputConfiguration,
|
||||
ConfirmInput,
|
||||
ConfirmInputConfiguration,
|
||||
DateTimeInput,
|
||||
DateTimeInputConfiguration,
|
||||
NumberInput,
|
||||
NumberInputConfiguration,
|
||||
OAuthInput,
|
||||
OAuthInputConfiguration,
|
||||
TextInput,
|
||||
TextInputConfiguration,
|
||||
} from './input';
|
||||
import {
|
||||
AgeEntityRecognizer,
|
||||
ChannelMentionEntityRecognizer,
|
||||
ConfirmationEntityRecognizer,
|
||||
CrossTrainedRecognizerSet,
|
||||
CrossTrainedRecognizerSetConfiguration,
|
||||
CurrencyEntityRecognizer,
|
||||
DateTimeEntityRecognizer,
|
||||
DimensionEntityRecognizer,
|
||||
EmailEntityRecognizer,
|
||||
EntityRecognizerSet,
|
||||
GuidEntityRecognizer,
|
||||
HashtagEntityRecognizer,
|
||||
IpEntityRecognizer,
|
||||
MentionEntityRecognizer,
|
||||
MultiLanguageRecognizer,
|
||||
MultiLanguageRecognizerConfiguration,
|
||||
NumberEntityRecognizer,
|
||||
OrdinalEntityRecognizer,
|
||||
PercentageEntityRecognizer,
|
||||
PhoneNumberEntityRecognizer,
|
||||
RecognizerSet,
|
||||
RecognizerSetConfiguration,
|
||||
RegexEntityRecognizer,
|
||||
RegexEntityRecognizerConfiguration,
|
||||
RegexRecognizer,
|
||||
RegexRecognizerConfiguration,
|
||||
TemperatureEntityRecognizer,
|
||||
UrlEntityRecognizer,
|
||||
} from './recognizers';
|
||||
import {
|
||||
ResourceMultiLanguageGenerator,
|
||||
ResourceMultiLanguageGeneratorConfiguration,
|
||||
TemplateEngineLanguageGenerator,
|
||||
TemplateEngineLanguageGeneratorConfiguration,
|
||||
} from './generators';
|
||||
import {
|
||||
ConditionalSelector,
|
||||
ConditionalSelectorConfiguration,
|
||||
FirstSelector,
|
||||
MostSpecificSelector,
|
||||
MostSpecificSelectorConfiguration,
|
||||
RandomSelector,
|
||||
TrueSelector,
|
||||
} from './selectors';
|
||||
import { DynamicBeginDialogDeserializer } from './dynamicBeginDialogDeserializer';
|
||||
import { HasPendingActionsFunction, IsDialogActiveFunction } from './functions';
|
||||
|
||||
type Type<T> = {
|
||||
$kind: string;
|
||||
new(...args: unknown[]): T;
|
||||
};
|
||||
|
||||
/**
|
||||
* `ComponentRegistration` implementation for adaptive components.
|
||||
*/
|
||||
export class AdaptiveComponentRegistration extends ComponentRegistration implements ComponentDeclarativeTypes {
|
||||
private _declarativeTypes: DeclarativeType<unknown, unknown>[] = [];
|
||||
|
||||
/**
|
||||
* Initializes a new instance of `AdaptiveComponentRegistration`.
|
||||
*/
|
||||
public constructor() {
|
||||
super();
|
||||
|
||||
// AdaptiveDialog
|
||||
this._addDeclarativeType<AdaptiveDialog, AdaptiveDialogConfiguration>(AdaptiveDialog);
|
||||
|
||||
// Actions
|
||||
this._addDeclarativeType<BeginDialog, BeginDialogConfiguration>(BeginDialog);
|
||||
this._addDeclarativeType<BeginSkill, BeginSkillConfiguration>(BeginSkill);
|
||||
this._addDeclarativeType<BreakLoop, BreakLoopConfiguration>(BreakLoop);
|
||||
this._addDeclarativeType<CancelAllDialogs, CancelAllDialogsBaseConfiguration>(CancelAllDialogs);
|
||||
this._addDeclarativeType<CancelDialog, CancelAllDialogsBaseConfiguration>(CancelDialog);
|
||||
this._addDeclarativeType<ContinueConversation, ContinueConversationConfiguration>(ContinueConversation);
|
||||
this._addDeclarativeType<ContinueConversationLater, ContinueConversationLaterConfiguration>(
|
||||
ContinueConversationLater
|
||||
);
|
||||
this._addDeclarativeType<ContinueLoop, ContinueLoopConfiguration>(ContinueLoop);
|
||||
this._addDeclarativeType<DeleteActivity, DeleteActivityConfiguration>(DeleteActivity);
|
||||
this._addDeclarativeType<DeleteProperties, DeletePropertiesConfiguration>(DeleteProperties);
|
||||
this._addDeclarativeType<DeleteProperty, DeletePropertyConfiguration>(DeleteProperty);
|
||||
this._addDeclarativeType<EditActions, EditActionsConfiguration>(EditActions);
|
||||
this._addDeclarativeType<EditArray, EditArrayConfiguration>(EditArray);
|
||||
this._addDeclarativeType<EmitEvent, EmitEventConfiguration>(EmitEvent);
|
||||
this._addDeclarativeType<EndDialog, EndDialogConfiguration>(EndDialog);
|
||||
this._addDeclarativeType<EndTurn, EndTurnConfiguration>(EndTurn);
|
||||
this._addDeclarativeType<ForEach, ForEachConfiguration>(ForEach);
|
||||
this._addDeclarativeType<ForEachPage, ForEachPageConfiguration>(ForEachPage);
|
||||
this._addDeclarativeType<GetActivityMembers, GetActivityMembersConfiguration>(GetActivityMembers);
|
||||
this._addDeclarativeType<GetConversationMembers, GetConversationMembersConfiguration>(GetConversationMembers);
|
||||
this._addDeclarativeType<GetConversationReference, GetConversationReferenceConfiguration>(
|
||||
GetConversationReference
|
||||
);
|
||||
this._addDeclarativeType<GotoAction, GotoActionConfiguration>(GotoAction);
|
||||
this._addDeclarativeType<HttpRequest, HttpRequestConfiguration>(HttpRequest);
|
||||
this._addDeclarativeType<IfCondition, IfConditionConfiguration>(IfCondition);
|
||||
this._addDeclarativeType<LogAction, LogActionConfiguration>(LogAction);
|
||||
this._addDeclarativeType<RepeatDialog, RepeatDialogConfiguration>(RepeatDialog);
|
||||
this._addDeclarativeType<ReplaceDialog, ReplaceDialogConfiguration>(ReplaceDialog);
|
||||
this._addDeclarativeType<SendActivity, SendActivityConfiguration>(SendActivity);
|
||||
this._addDeclarativeType<SendHandoffActivity, SendHandoffActivityConfiguration>(SendHandoffActivity);
|
||||
this._addDeclarativeType<SetProperties, SetPropertiesConfiguration>(SetProperties);
|
||||
this._addDeclarativeType<SetProperty, SetPropertyConfiguration>(SetProperty);
|
||||
this._addDeclarativeType<SignOutUser, SignOutUserConfiguration>(SignOutUser);
|
||||
this._addDeclarativeType<SwitchCondition, SwitchConditionConfiguration>(SwitchCondition);
|
||||
this._addDeclarativeType<TelemetryTrackEventAction, TelemetryTrackEventActionConfiguration>(
|
||||
TelemetryTrackEventAction
|
||||
);
|
||||
this._addDeclarativeType<ThrowException, ThrowExceptionConfiguration>(ThrowException);
|
||||
this._addDeclarativeType<TraceActivity, TraceActivityConfiguration>(TraceActivity);
|
||||
this._addDeclarativeType<UpdateActivity, UpdateActivityConfiguration>(UpdateActivity);
|
||||
|
||||
// Trigger conditions
|
||||
this._addDeclarativeType<OnActivity, OnActivityConfiguration>(OnActivity);
|
||||
this._addDeclarativeType<OnAssignEntity, OnAssignEntityConfiguration>(OnAssignEntity);
|
||||
this._addDeclarativeType<OnBeginDialog, OnDialogEventConfiguration>(OnBeginDialog);
|
||||
this._addDeclarativeType<OnCancelDialog, OnDialogEventConfiguration>(OnCancelDialog);
|
||||
this._addDeclarativeType<OnChooseEntity, OnChooseEntityConfiguration>(OnChooseEntity);
|
||||
this._addDeclarativeType<OnChooseIntent, OnChooseIntentConfiguration>(OnChooseIntent);
|
||||
this._addDeclarativeType<OnChooseProperty, OnDialogEventConfiguration>(OnChooseProperty);
|
||||
this._addDeclarativeType<OnCondition, OnConditionConfiguration>(OnCondition);
|
||||
this._addDeclarativeType<OnContinueConversation, OnActivityConfiguration>(OnContinueConversation);
|
||||
this._addDeclarativeType<OnConversationUpdateActivity, OnActivityConfiguration>(OnConversationUpdateActivity);
|
||||
this._addDeclarativeType<OnDialogEvent, OnDialogEventConfiguration>(OnDialogEvent);
|
||||
this._addDeclarativeType<OnEndOfActions, OnDialogEventConfiguration>(OnEndOfActions);
|
||||
this._addDeclarativeType<OnEndOfConversationActivity, OnActivityConfiguration>(OnEndOfConversationActivity);
|
||||
this._addDeclarativeType<OnError, OnDialogEventConfiguration>(OnError);
|
||||
this._addDeclarativeType<OnEventActivity, OnActivityConfiguration>(OnEventActivity);
|
||||
this._addDeclarativeType<OnHandoffActivity, OnActivityConfiguration>(OnHandoffActivity);
|
||||
this._addDeclarativeType<OnInstallationUpdateActivity, OnActivityConfiguration>(OnInstallationUpdateActivity);
|
||||
this._addDeclarativeType<OnIntent, OnIntentConfiguration>(OnIntent);
|
||||
this._addDeclarativeType<OnInvokeActivity, OnActivityConfiguration>(OnInvokeActivity);
|
||||
this._addDeclarativeType<OnMessageActivity, OnActivityConfiguration>(OnMessageActivity);
|
||||
this._addDeclarativeType<OnMessageDeleteActivity, OnActivityConfiguration>(OnMessageDeleteActivity);
|
||||
this._addDeclarativeType<OnMessageReactionActivity, OnActivityConfiguration>(OnMessageReactionActivity);
|
||||
this._addDeclarativeType<OnMessageUpdateActivity, OnActivityConfiguration>(OnMessageUpdateActivity);
|
||||
this._addDeclarativeType<OnQnAMatch, OnIntentConfiguration>(OnQnAMatch);
|
||||
this._addDeclarativeType<OnRepromptDialog, OnDialogEventConfiguration>(OnRepromptDialog);
|
||||
this._addDeclarativeType<OnTypingActivity, OnActivityConfiguration>(OnTypingActivity);
|
||||
this._addDeclarativeType<OnUnknownIntent, OnDialogEventConfiguration>(OnUnknownIntent);
|
||||
|
||||
// Inputs
|
||||
this._addDeclarativeType<Ask, AskConfiguration>(Ask);
|
||||
this._addDeclarativeType<AttachmentInput, AttachmentInputConfiguration>(AttachmentInput);
|
||||
this._addDeclarativeType<ChoiceInput, ChoiceInputConfiguration>(ChoiceInput);
|
||||
this._addDeclarativeType<ConfirmInput, ConfirmInputConfiguration>(ConfirmInput);
|
||||
this._addDeclarativeType<DateTimeInput, DateTimeInputConfiguration>(DateTimeInput);
|
||||
this._addDeclarativeType<NumberInput, NumberInputConfiguration>(NumberInput);
|
||||
this._addDeclarativeType<OAuthInput, OAuthInputConfiguration>(OAuthInput);
|
||||
this._addDeclarativeType<TextInput, TextInputConfiguration>(TextInput);
|
||||
|
||||
// Recognizers
|
||||
this._addDeclarativeType<CrossTrainedRecognizerSet, CrossTrainedRecognizerSetConfiguration>(
|
||||
CrossTrainedRecognizerSet
|
||||
);
|
||||
this._addDeclarativeType<MultiLanguageRecognizer, MultiLanguageRecognizerConfiguration>(
|
||||
MultiLanguageRecognizer
|
||||
);
|
||||
this._addDeclarativeType<RecognizerSet, RecognizerSetConfiguration>(RecognizerSet);
|
||||
this._addDeclarativeType<RegexRecognizer, RegexRecognizerConfiguration>(RegexRecognizer);
|
||||
this._addDeclarativeType<AgeEntityRecognizer, unknown>(AgeEntityRecognizer);
|
||||
this._addDeclarativeType<ChannelMentionEntityRecognizer, unknown>(ChannelMentionEntityRecognizer);
|
||||
this._addDeclarativeType<ConfirmationEntityRecognizer, unknown>(ConfirmationEntityRecognizer);
|
||||
this._addDeclarativeType<CurrencyEntityRecognizer, unknown>(CurrencyEntityRecognizer);
|
||||
this._addDeclarativeType<DateTimeEntityRecognizer, unknown>(DateTimeEntityRecognizer);
|
||||
this._addDeclarativeType<DimensionEntityRecognizer, unknown>(DimensionEntityRecognizer);
|
||||
this._addDeclarativeType<EmailEntityRecognizer, unknown>(EmailEntityRecognizer);
|
||||
this._addDeclarativeType<EntityRecognizerSet, unknown>(EntityRecognizerSet);
|
||||
this._addDeclarativeType<GuidEntityRecognizer, unknown>(GuidEntityRecognizer);
|
||||
this._addDeclarativeType<HashtagEntityRecognizer, unknown>(HashtagEntityRecognizer);
|
||||
this._addDeclarativeType<IpEntityRecognizer, unknown>(IpEntityRecognizer);
|
||||
this._addDeclarativeType<MentionEntityRecognizer, unknown>(MentionEntityRecognizer);
|
||||
this._addDeclarativeType<NumberEntityRecognizer, unknown>(NumberEntityRecognizer);
|
||||
this._addDeclarativeType<OrdinalEntityRecognizer, unknown>(OrdinalEntityRecognizer);
|
||||
this._addDeclarativeType<PercentageEntityRecognizer, unknown>(PercentageEntityRecognizer);
|
||||
this._addDeclarativeType<PhoneNumberEntityRecognizer, unknown>(PhoneNumberEntityRecognizer);
|
||||
this._addDeclarativeType<RegexEntityRecognizer, RegexEntityRecognizerConfiguration>(RegexEntityRecognizer);
|
||||
this._addDeclarativeType<TemperatureEntityRecognizer, unknown>(TemperatureEntityRecognizer);
|
||||
this._addDeclarativeType<UrlEntityRecognizer, unknown>(UrlEntityRecognizer);
|
||||
|
||||
// Generators
|
||||
this._addDeclarativeType<TemplateEngineLanguageGenerator, TemplateEngineLanguageGeneratorConfiguration>(
|
||||
TemplateEngineLanguageGenerator
|
||||
);
|
||||
this._addDeclarativeType<ResourceMultiLanguageGenerator, ResourceMultiLanguageGeneratorConfiguration>(
|
||||
ResourceMultiLanguageGenerator
|
||||
);
|
||||
|
||||
// Selectors
|
||||
this._addDeclarativeType<ConditionalSelector, ConditionalSelectorConfiguration>(ConditionalSelector);
|
||||
this._addDeclarativeType<FirstSelector, unknown>(FirstSelector);
|
||||
this._addDeclarativeType<RandomSelector, unknown>(RandomSelector);
|
||||
this._addDeclarativeType<TrueSelector, unknown>(TrueSelector);
|
||||
this._addDeclarativeType<MostSpecificSelector, MostSpecificSelectorConfiguration>(MostSpecificSelector);
|
||||
|
||||
Expression.functions.add(IsDialogActiveFunction.functionName, new IsDialogActiveFunction());
|
||||
Expression.functions.add(IsDialogActiveFunction.functionAlias, new IsDialogActiveFunction());
|
||||
Expression.functions.add(HasPendingActionsFunction.functionName, new HasPendingActionsFunction());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets adaptive `DeclarativeType` resources.
|
||||
* @param resourceExplorer `ResourceExplorer` with expected path to get all resources.
|
||||
* @returns Adaptive `DeclarativeType` resources.
|
||||
*/
|
||||
public getDeclarativeTypes(resourceExplorer: ResourceExplorer): DeclarativeType[] {
|
||||
const declarativeTypes: DeclarativeType[] = [...this._declarativeTypes];
|
||||
resourceExplorer.getResources('.schema').forEach((schema) => {
|
||||
const resourceId = schema.id.replace(/.schema$/, '');
|
||||
if (resourceId.endsWith('.dialog')) {
|
||||
declarativeTypes.push({
|
||||
kind: resourceId,
|
||||
type: DynamicBeginDialog,
|
||||
loader: new DynamicBeginDialogDeserializer(resourceExplorer, resourceId),
|
||||
});
|
||||
}
|
||||
});
|
||||
return declarativeTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
private _addDeclarativeType<T, C>(type: Type<T>, loader?: CustomDeserializer<T, C>): void {
|
||||
const declarativeType: DeclarativeType<T, C> = {
|
||||
kind: type.$kind,
|
||||
type,
|
||||
loader,
|
||||
};
|
||||
this._declarativeTypes.push(declarativeType);
|
||||
}
|
||||
}
|
|
@ -6,18 +6,17 @@
|
|||
* Licensed under the MIT License.
|
||||
*/
|
||||
|
||||
export * from './actions';
|
||||
export * from './actionContext';
|
||||
export * from './actions';
|
||||
export * from './adaptiveBotComponent';
|
||||
export * from './adaptiveDialog';
|
||||
export * from './adaptiveComponentRegistration';
|
||||
export * from './adaptiveEvents';
|
||||
export * from './conditions';
|
||||
export { DialogExpressionConverter } from './converters';
|
||||
export * from './expressions';
|
||||
export * from './functions';
|
||||
export * from './generators';
|
||||
export * from './input';
|
||||
export * from './languageGenerationComponentRegistration';
|
||||
export * from './languageGenerationBotComponent';
|
||||
export * from './languageGenerator';
|
||||
export * from './languageGeneratorExtensions';
|
||||
export * from './languagePolicy';
|
||||
|
@ -31,3 +30,5 @@ export * from './skillExtensions';
|
|||
export * from './telemetryExtensions';
|
||||
export * from './templates';
|
||||
export * from './triggerSelector';
|
||||
|
||||
export { DialogExpressionConverter } from './converters';
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
import { ActivityTemplate, StaticActivityTemplate, TextTemplate } from './templates';
|
||||
import { BotComponent } from 'botbuilder';
|
||||
import { ComponentDeclarativeTypes } from 'botbuilder-dialogs-declarative';
|
||||
import { Configuration, ServiceCollection } from 'botbuilder-runtime-core';
|
||||
|
||||
export class LanguageGenerationBotComponent extends BotComponent {
|
||||
configureServices(services: ServiceCollection, _configuration: Configuration): void {
|
||||
services.composeFactory<ComponentDeclarativeTypes[]>('declarativeTypes', (declarativeTypes) =>
|
||||
declarativeTypes.concat({
|
||||
getDeclarativeTypes() {
|
||||
return [
|
||||
{
|
||||
kind: TextTemplate.$kind,
|
||||
type: TextTemplate,
|
||||
},
|
||||
{
|
||||
kind: ActivityTemplate.$kind,
|
||||
type: ActivityTemplate,
|
||||
},
|
||||
{
|
||||
kind: StaticActivityTemplate.$kind,
|
||||
type: StaticActivityTemplate,
|
||||
},
|
||||
];
|
||||
},
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
/**
|
||||
* @module botbuilder-dialogs-adaptive
|
||||
*/
|
||||
/**
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License.
|
||||
*/
|
||||
|
||||
import { Activity, ComponentRegistration } from 'botbuilder-core';
|
||||
import { TemplateInterface } from 'botbuilder-dialogs';
|
||||
import { ComponentDeclarativeTypes, DeclarativeType, ResourceExplorer } from 'botbuilder-dialogs-declarative';
|
||||
import { ActivityTemplate, StaticActivityTemplate, TextTemplate } from './templates';
|
||||
|
||||
/**
|
||||
* ComponentRegistration class for language generation resources.
|
||||
*/
|
||||
export class LanguageGenerationComponentRegistration
|
||||
extends ComponentRegistration
|
||||
implements ComponentDeclarativeTypes {
|
||||
/**
|
||||
* Return declarative types for language generation.
|
||||
*
|
||||
* @param {ResourceExplorer} _resourceExplorer Resource explorer to use for resolving references.
|
||||
* @returns {DeclarativeType<TemplateInterface<string | Partial<Activity>, ?>, Record<string, ?>>[]} Declarative types.
|
||||
*/
|
||||
public getDeclarativeTypes(
|
||||
_resourceExplorer: ResourceExplorer
|
||||
): DeclarativeType<TemplateInterface<string | Partial<Activity>, unknown>, Record<string, unknown>>[] {
|
||||
return [
|
||||
{
|
||||
kind: TextTemplate.$kind,
|
||||
type: TextTemplate,
|
||||
},
|
||||
{
|
||||
kind: ActivityTemplate.$kind,
|
||||
type: ActivityTemplate,
|
||||
},
|
||||
{
|
||||
kind: StaticActivityTemplate.$kind,
|
||||
type: StaticActivityTemplate,
|
||||
},
|
||||
];
|
||||
}
|
||||
}
|
|
@ -7,8 +7,8 @@
|
|||
*/
|
||||
|
||||
import { Configurable } from 'botbuilder-dialogs';
|
||||
import { Newable } from 'botbuilder-stdlib';
|
||||
import { CustomDeserializer } from './customDeserializer';
|
||||
import { Newable } from 'botbuilder-stdlib';
|
||||
import { ResourceExplorer } from './resources';
|
||||
|
||||
/**
|
||||
|
@ -32,6 +32,7 @@ export class DefaultLoader implements CustomDeserializer<Configurable, Record<st
|
|||
public load(config: Record<string, unknown>, type: Newable<Configurable>): Configurable {
|
||||
return Object.entries(config).reduce((instance, [key, value]) => {
|
||||
let converter = instance.getConverter(key);
|
||||
|
||||
if (converter) {
|
||||
if (typeof converter === 'function') {
|
||||
converter = new converter(this._resourceExplorer);
|
||||
|
@ -40,6 +41,7 @@ export class DefaultLoader implements CustomDeserializer<Configurable, Record<st
|
|||
} else {
|
||||
instance[`${key}`] = value;
|
||||
}
|
||||
|
||||
return instance;
|
||||
}, new type());
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
* Licensed under the MIT License.
|
||||
*/
|
||||
|
||||
import { ComponentRegistration } from 'botbuilder-core';
|
||||
import { Dialog } from 'botbuilder-dialogs';
|
||||
import { Newable } from 'botbuilder-stdlib';
|
||||
import { normalize, join } from 'path';
|
||||
|
@ -324,26 +323,19 @@ export class ResourceExplorer {
|
|||
return result as T;
|
||||
}
|
||||
|
||||
private getComponentRegistrations(): ComponentRegistration[] {
|
||||
return (
|
||||
this._declarativeTypes ??
|
||||
ComponentRegistration.components.filter((component: ComponentRegistration) =>
|
||||
isComponentDeclarativeTypes(component)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private registerTypeInternal<T, C>(kind: string, type: Newable<T>, loader?: CustomDeserializer<T, C>): void {
|
||||
this._kindToType.set(kind, type);
|
||||
this._kindDeserializer.set(kind, loader || new DefaultLoader(this));
|
||||
this._kindDeserializer.set(kind, loader ?? new DefaultLoader(this));
|
||||
}
|
||||
|
||||
private registerComponentTypes(): void {
|
||||
if (this._typesLoaded) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._typesLoaded = true;
|
||||
this.getComponentRegistrations().forEach((component: ComponentDeclarativeTypes) => {
|
||||
|
||||
this._declarativeTypes.forEach((component: ComponentDeclarativeTypes) => {
|
||||
component.getDeclarativeTypes(this).forEach((declarativeType: DeclarativeType) => {
|
||||
const { kind, type, loader } = declarativeType;
|
||||
this.registerTypeInternal(kind, type, loader);
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
const assert = require('assert');
|
||||
const path = require('path');
|
||||
const { ResourceExplorer } = require('../lib');
|
||||
const { DialogManager } = require('botbuilder-dialogs');
|
||||
const { QnACardBuilder, RankerTypes, QnAMakerClientKey, QnAMakerBotComponent } = require('botbuilder-ai');
|
||||
const { ServiceCollection, noOpConfiguration } = require('botbuilder-runtime-core');
|
||||
const { StringExpression } = require('adaptive-expressions');
|
||||
|
||||
const {
|
||||
TestFlow,
|
||||
MemoryStorage,
|
||||
|
@ -9,11 +15,12 @@ const {
|
|||
useBotState,
|
||||
ActivityTypes,
|
||||
} = require('botbuilder-core');
|
||||
const { DialogManager } = require('botbuilder-dialogs');
|
||||
const { ResourceExtensions, LanguageGeneratorExtensions } = require('../../botbuilder-dialogs-adaptive/lib');
|
||||
const { QnACardBuilder, RankerTypes, QnAMakerClientKey } = require('../../botbuilder-ai/lib');
|
||||
const { ResourceExplorer } = require('../lib');
|
||||
const { StringExpression } = require('adaptive-expressions');
|
||||
|
||||
const {
|
||||
AdaptiveBotComponent,
|
||||
ResourceExtensions,
|
||||
LanguageGeneratorExtensions,
|
||||
} = require('botbuilder-dialogs-adaptive');
|
||||
|
||||
class MockQnAMakerClient {
|
||||
getAnswers(_turnContext, _options, _telemetryProperties, _telemetryMetrics) {
|
||||
|
@ -81,8 +88,6 @@ class MockQnAMakerClient {
|
|||
}
|
||||
}
|
||||
|
||||
const resourceExplorer = new ResourceExplorer().addFolder(path.join(__dirname, 'resources/JsonDialog'), true, false);
|
||||
|
||||
const initializeAdapter = (testName, sendTrace = false) => {
|
||||
const storage = new MemoryStorage();
|
||||
const convoState = new ConversationState(storage);
|
||||
|
@ -92,7 +97,7 @@ const initializeAdapter = (testName, sendTrace = false) => {
|
|||
return adapter;
|
||||
};
|
||||
|
||||
const getTestFlow = (dialog, adapter) => {
|
||||
const getTestFlow = (resourceExplorer, dialog, adapter) => {
|
||||
const dm = new DialogManager(dialog);
|
||||
ResourceExtensions.useResourceExplorer(dm, resourceExplorer);
|
||||
LanguageGeneratorExtensions.useLanguageGeneration(dm);
|
||||
|
@ -104,37 +109,53 @@ const getTestFlow = (dialog, adapter) => {
|
|||
});
|
||||
};
|
||||
|
||||
const buildTestFlow = (resourceName, testName, sendTrace = false) => {
|
||||
const buildTestFlow = (resourceExplorer, resourceName, testName, sendTrace = false) => {
|
||||
const adapter = initializeAdapter(testName, sendTrace);
|
||||
const dialog = resourceExplorer.loadType(resourceName);
|
||||
return getTestFlow(dialog, adapter);
|
||||
return getTestFlow(resourceExplorer, dialog, adapter);
|
||||
};
|
||||
|
||||
const buildQnAMakerTestFlow = (testName) => {
|
||||
const buildQnAMakerTestFlow = (resourceExplorer, testName) => {
|
||||
const adapter = initializeAdapter(testName);
|
||||
const dialog = resourceExplorer.loadType('QnAMakerBot.main.dialog');
|
||||
return getTestFlow(dialog, adapter);
|
||||
return getTestFlow(resourceExplorer, dialog, adapter);
|
||||
};
|
||||
|
||||
const buildQnAMakerTestFlowIsTest = (testName) => {
|
||||
const buildQnAMakerTestFlowIsTest = (resourceExplorer, testName) => {
|
||||
const adapter = initializeAdapter(testName);
|
||||
const dialog = resourceExplorer.loadType('QnAMakerBot.main.dialog');
|
||||
dialog.triggers[0].actions[0].isTest = true;
|
||||
return getTestFlow(dialog, adapter);
|
||||
return getTestFlow(resourceExplorer, dialog, adapter);
|
||||
};
|
||||
|
||||
const buildQnAMakerTestFlowRankerTypeQuestionOnly = (testName) => {
|
||||
const buildQnAMakerTestFlowRankerTypeQuestionOnly = (resourceExplorer, testName) => {
|
||||
const adapter = initializeAdapter(testName);
|
||||
const dialog = resourceExplorer.loadType('QnAMakerBot.main.dialog');
|
||||
dialog.triggers[0].actions[0].rankerType = new StringExpression(RankerTypes.questionOnly);
|
||||
return getTestFlow(dialog, adapter);
|
||||
return getTestFlow(resourceExplorer, dialog, adapter);
|
||||
};
|
||||
|
||||
describe('Json load tests', function () {
|
||||
this.timeout(5000);
|
||||
let resourceExplorer;
|
||||
beforeEach(function () {
|
||||
const services = new ServiceCollection({
|
||||
declarativeTypes: [],
|
||||
});
|
||||
|
||||
new AdaptiveBotComponent().configureServices(services, noOpConfiguration);
|
||||
new QnAMakerBotComponent().configureServices(services, noOpConfiguration);
|
||||
|
||||
const declarativeTypes = services.mustMakeInstance('declarativeTypes');
|
||||
|
||||
resourceExplorer = new ResourceExplorer({ declarativeTypes }).addFolder(
|
||||
path.join(__dirname, 'resources/JsonDialog'),
|
||||
true,
|
||||
false
|
||||
);
|
||||
});
|
||||
|
||||
it('DoubleReference', async () => {
|
||||
await buildTestFlow('DoubleReference.dialog', this.fullTitle())
|
||||
await buildTestFlow(resourceExplorer, 'DoubleReference.dialog', this.fullTitle())
|
||||
.sendConversationUpdate()
|
||||
.assertReply('what is your name?')
|
||||
.send('c')
|
||||
|
@ -143,7 +164,7 @@ describe('Json load tests', function () {
|
|||
});
|
||||
|
||||
it('CycleDetection', async () => {
|
||||
await buildTestFlow('Root.dialog', this.fullTitle())
|
||||
await buildTestFlow(resourceExplorer, 'Root.dialog', this.fullTitle())
|
||||
.sendConversationUpdate()
|
||||
.assertReply('Hello')
|
||||
.send('Hello what?')
|
||||
|
@ -162,7 +183,7 @@ describe('Json load tests', function () {
|
|||
});
|
||||
|
||||
it('Actions', async () => {
|
||||
await buildTestFlow('Actions.main.dialog', this.fullTitle())
|
||||
await buildTestFlow(resourceExplorer, 'Actions.main.dialog', this.fullTitle())
|
||||
.sendConversationUpdate()
|
||||
.assertReply('Action 1')
|
||||
.assertReply('Action 2')
|
||||
|
@ -171,7 +192,7 @@ describe('Json load tests', function () {
|
|||
});
|
||||
|
||||
it('EndTurn', async () => {
|
||||
await buildTestFlow('EndTurn.main.dialog', this.fullTitle())
|
||||
await buildTestFlow(resourceExplorer, 'EndTurn.main.dialog', this.fullTitle())
|
||||
.send('hello')
|
||||
.assertReply("What's up?")
|
||||
.send('Nothing')
|
||||
|
@ -180,7 +201,7 @@ describe('Json load tests', function () {
|
|||
});
|
||||
|
||||
it('IfProerty', async () => {
|
||||
await buildTestFlow('IfCondition.main.dialog', this.fullTitle())
|
||||
await buildTestFlow(resourceExplorer, 'IfCondition.main.dialog', this.fullTitle())
|
||||
.sendConversationUpdate()
|
||||
.assertReply("Hello, I'm Zoidberg. What is your name?")
|
||||
.send('Carlos')
|
||||
|
@ -189,14 +210,14 @@ describe('Json load tests', function () {
|
|||
});
|
||||
|
||||
it('SwitchCondition', async () => {
|
||||
await buildTestFlow('SwitchCondition.main.dialog', this.fullTitle())
|
||||
await buildTestFlow(resourceExplorer, 'SwitchCondition.main.dialog', this.fullTitle())
|
||||
.send('Hi')
|
||||
.assertReply('Age is 22!')
|
||||
.startTest();
|
||||
});
|
||||
|
||||
it('TextInputWithoutProperty', async () => {
|
||||
await buildTestFlow('TextInput.WithoutProperty.main.dialog', this.fullTitle())
|
||||
await buildTestFlow(resourceExplorer, 'TextInput.WithoutProperty.main.dialog', this.fullTitle())
|
||||
.sendConversationUpdate()
|
||||
.assertReply("Hello, I'm Zoidberg. What is your name?")
|
||||
.send('Carlos')
|
||||
|
@ -205,7 +226,7 @@ describe('Json load tests', function () {
|
|||
});
|
||||
|
||||
it('TextInput', async () => {
|
||||
await buildTestFlow('TextInput.main.dialog', this.fullTitle())
|
||||
await buildTestFlow(resourceExplorer, 'TextInput.main.dialog', this.fullTitle())
|
||||
.sendConversationUpdate()
|
||||
.assertReply("Hello, I'm Zoidberg. What is your name?")
|
||||
.send('Cancel')
|
||||
|
@ -220,7 +241,7 @@ describe('Json load tests', function () {
|
|||
});
|
||||
|
||||
it('NumberInput', async () => {
|
||||
await buildTestFlow('NumberInput.main.dialog', this.fullTitle())
|
||||
await buildTestFlow(resourceExplorer, 'NumberInput.main.dialog', this.fullTitle())
|
||||
.sendConversationUpdate()
|
||||
.assertReply('What is your age?')
|
||||
.send('Blablabla')
|
||||
|
@ -234,7 +255,7 @@ describe('Json load tests', function () {
|
|||
});
|
||||
|
||||
it('RepeatDialog', async () => {
|
||||
await buildTestFlow('RepeatDialog.main.dialog', this.fullTitle())
|
||||
await buildTestFlow(resourceExplorer, 'RepeatDialog.main.dialog', this.fullTitle())
|
||||
.sendConversationUpdate()
|
||||
.assertReply('RepeatDialog.main.dialog starting')
|
||||
.assertReply('Hello, what is your name?')
|
||||
|
@ -247,7 +268,7 @@ describe('Json load tests', function () {
|
|||
});
|
||||
|
||||
it('TraceAndLog', async () => {
|
||||
await buildTestFlow('TraceAndLog.main.dialog', this.fullTitle(), true)
|
||||
await buildTestFlow(resourceExplorer, 'TraceAndLog.main.dialog', this.fullTitle(), true)
|
||||
.sendConversationUpdate()
|
||||
.assertReply('Hello, what is your name?')
|
||||
.send('Carlos')
|
||||
|
@ -264,7 +285,7 @@ describe('Json load tests', function () {
|
|||
});
|
||||
|
||||
it('DoActions', async () => {
|
||||
await buildTestFlow('DoActions.main.dialog', this.fullTitle())
|
||||
await buildTestFlow(resourceExplorer, 'DoActions.main.dialog', this.fullTitle())
|
||||
.send({ type: ActivityTypes.ConversationUpdate, membersAdded: [{ id: 'bot', name: 'Bot' }] })
|
||||
.sendConversationUpdate()
|
||||
.assertReply("Hello, I'm Zoidberg. What is your name?")
|
||||
|
@ -283,7 +304,7 @@ describe('Json load tests', function () {
|
|||
});
|
||||
|
||||
it('BeginDialog', async () => {
|
||||
await buildTestFlow('BeginDialog.main.dialog', this.fullTitle())
|
||||
await buildTestFlow(resourceExplorer, 'BeginDialog.main.dialog', this.fullTitle())
|
||||
.send({ type: ActivityTypes.ConversationUpdate, membersAdded: [{ id: 'bot', name: 'Bot' }] })
|
||||
.sendConversationUpdate()
|
||||
.assertReply("Hello, I'm Zoidberg. What is your name?")
|
||||
|
@ -302,7 +323,7 @@ describe('Json load tests', function () {
|
|||
});
|
||||
|
||||
it('ChoiceInput', async () => {
|
||||
await buildTestFlow('ChoiceInput.main.dialog', this.fullTitle())
|
||||
await buildTestFlow(resourceExplorer, 'ChoiceInput.main.dialog', this.fullTitle())
|
||||
.sendConversationUpdate()
|
||||
.assertReply('Please select a value from below:\n\n 1. Test1\n 2. Test2\n 3. Test3')
|
||||
.send('Test1')
|
||||
|
@ -311,7 +332,7 @@ describe('Json load tests', function () {
|
|||
});
|
||||
|
||||
it('ExternalLanguage', async () => {
|
||||
await buildTestFlow('ExternalLanguage.main.dialog', this.fullTitle())
|
||||
await buildTestFlow(resourceExplorer, 'ExternalLanguage.main.dialog', this.fullTitle())
|
||||
.sendConversationUpdate()
|
||||
.assertReplyOneOf([
|
||||
'Zoidberg here, welcome to my world!',
|
||||
|
@ -334,7 +355,7 @@ describe('Json load tests', function () {
|
|||
});
|
||||
|
||||
it('ToDoBot', async () => {
|
||||
await buildTestFlow('ToDoBot.main.dialog', this.fullTitle())
|
||||
await buildTestFlow(resourceExplorer, 'ToDoBot.main.dialog', this.fullTitle())
|
||||
.send({ type: ActivityTypes.ConversationUpdate, membersAdded: [{ id: 'bot', name: 'Bot' }] })
|
||||
.sendConversationUpdate()
|
||||
.assertReply('Hi! I\'m a ToDo bot. Say "add a todo named first" to get started.')
|
||||
|
@ -366,7 +387,7 @@ describe('Json load tests', function () {
|
|||
});
|
||||
|
||||
it('HttpRequest', async () => {
|
||||
await buildTestFlow('HttpRequest.main.dialog', this.fullTitle())
|
||||
await buildTestFlow(resourceExplorer, 'HttpRequest.main.dialog', this.fullTitle())
|
||||
.send({ type: ActivityTypes.ConversationUpdate, membersAdded: [{ id: 'bot', name: 'Bot' }] })
|
||||
.assertReply('Welcome! Here is a http request sample, please enter a name for you visual pet.')
|
||||
.send('TestPetName')
|
||||
|
@ -387,7 +408,7 @@ describe('Json load tests', function () {
|
|||
'Did you mean:',
|
||||
'None of the above.'
|
||||
);
|
||||
await buildQnAMakerTestFlow(this.fullTitle())
|
||||
await buildQnAMakerTestFlow(resourceExplorer, this.fullTitle())
|
||||
.send('Q11')
|
||||
.assertReply((reply, _description) => {
|
||||
assert(reply.attachments);
|
||||
|
@ -406,7 +427,7 @@ describe('Json load tests', function () {
|
|||
'None of the above.'
|
||||
);
|
||||
const noAnswerActivity = 'Answers not found in kb.';
|
||||
await buildQnAMakerTestFlow(this.fullTitle())
|
||||
await buildQnAMakerTestFlow(resourceExplorer, this.fullTitle())
|
||||
.send('Q11')
|
||||
.assertReply((reply, _description) => {
|
||||
assert(reply.attachments);
|
||||
|
@ -424,7 +445,7 @@ describe('Json load tests', function () {
|
|||
'Did you mean:',
|
||||
'None of the above.'
|
||||
);
|
||||
await buildQnAMakerTestFlow(this.fullTitle())
|
||||
await buildQnAMakerTestFlow(resourceExplorer, this.fullTitle())
|
||||
.send('Q11')
|
||||
.assertReply((reply, _description) => {
|
||||
assert(reply.attachments);
|
||||
|
@ -436,14 +457,14 @@ describe('Json load tests', function () {
|
|||
});
|
||||
|
||||
it('QnAMakerDialog_isTest', async () => {
|
||||
await buildQnAMakerTestFlowIsTest(this.fullTitle())
|
||||
await buildQnAMakerTestFlowIsTest(resourceExplorer, this.fullTitle())
|
||||
.send('Surface book 2 price')
|
||||
.assertReply('Surface book 2 price is $1400.')
|
||||
.startTest();
|
||||
});
|
||||
|
||||
it('QnAMakerDialog_RankerType_QuestionOnly', async () => {
|
||||
await buildQnAMakerTestFlowRankerTypeQuestionOnly(this.fullTitle())
|
||||
await buildQnAMakerTestFlowRankerTypeQuestionOnly(resourceExplorer, this.fullTitle())
|
||||
.send('What ranker do you want to use?')
|
||||
.assertReply('We are using QuestionOnly ranker.')
|
||||
.startTest();
|
||||
|
|
|
@ -1,17 +1,11 @@
|
|||
const {
|
||||
ComponentRegistration,
|
||||
TestAdapter,
|
||||
MemoryStorage,
|
||||
useBotState,
|
||||
UserState,
|
||||
ConversationState,
|
||||
} = require('botbuilder-core');
|
||||
const { DialogManager } = require('botbuilder-dialogs');
|
||||
const { AdaptiveComponentRegistration } = require('../../botbuilder-dialogs-adaptive/lib');
|
||||
const { ResourceExplorer, FolderResourceProvider, ResourceChangeEvent } = require('../lib');
|
||||
const assert = require('assert');
|
||||
const { writeFileSync, existsSync, unlinkSync } = require('fs');
|
||||
const { AdaptiveBotComponent } = require('botbuilder-dialogs-adaptive');
|
||||
const { DialogManager } = require('botbuilder-dialogs');
|
||||
const { ResourceExplorer, FolderResourceProvider, ResourceChangeEvent } = require('../lib');
|
||||
const { ServiceCollection, noOpConfiguration } = require('botbuilder-runtime-core');
|
||||
const { TestAdapter, MemoryStorage, useBotState, UserState, ConversationState } = require('botbuilder-core');
|
||||
const { extname, join } = require('path');
|
||||
const { writeFileSync, existsSync, unlinkSync } = require('fs');
|
||||
|
||||
function assertResourceType(explorer, resourceType) {
|
||||
const resources = explorer.getResources(resourceType);
|
||||
|
@ -23,30 +17,34 @@ function assertResourceFound(explorer, id) {
|
|||
const resource = explorer.getResource(id);
|
||||
assert(resource, `getResource(${id}) should return resource`);
|
||||
const dialogs = explorer.getResources('dialog');
|
||||
assert(dialogs.some(dialog => dialog.id == id), `getResources('dialog') should return resources`);
|
||||
assert(
|
||||
dialogs.some((dialog) => dialog.id == id),
|
||||
`getResources('dialog') should return resources`
|
||||
);
|
||||
}
|
||||
|
||||
function assertResourceNotFound(explorer, id) {
|
||||
const resource = explorer.getResource(id);
|
||||
assert.strictEqual(resource, undefined, `getResource(${id}) should not return resource`);
|
||||
const dialogs = explorer.getResources('dialog');
|
||||
assert(dialogs.every(dialog => dialog.id != id), `getResouces('dialog') should not return resources`);
|
||||
assert(
|
||||
dialogs.every((dialog) => dialog.id != id),
|
||||
`getResouces('dialog') should not return resources`
|
||||
);
|
||||
}
|
||||
|
||||
function assertResourceContents(explorer, id, contents) {
|
||||
const resource = explorer.getResource(id);
|
||||
let text = resource.readText();
|
||||
assert.strictEqual(text, contents, `getResource(${id}) contents not the same`);
|
||||
const dialogs = explorer.getResources('dialog').filter(dialog => dialog.id == id);
|
||||
const dialogs = explorer.getResources('dialog').filter((dialog) => dialog.id == id);
|
||||
assert(dialogs.length == 1, `getResouces('dialog') should return resources`);
|
||||
const dialog = dialogs[0];
|
||||
text = dialog.readText();
|
||||
assert.strictEqual(text, contents, `getResouces('dialog') contents not the same`);
|
||||
}
|
||||
|
||||
describe('ResourecExplorer', function () {
|
||||
this.timeout(5000);
|
||||
|
||||
describe('ResourceExplorer', function () {
|
||||
it('add folders recursively', async () => {
|
||||
const explorer = new ResourceExplorer();
|
||||
explorer.addFolder(join(__dirname, 'resources'), true, false);
|
||||
|
@ -99,12 +97,21 @@ describe('ResourecExplorer', function () {
|
|||
});
|
||||
|
||||
it('dialog id assignment', async () => {
|
||||
const explorer = new ResourceExplorer();
|
||||
explorer.addFolders(join(__dirname, 'resources'), [], false);
|
||||
ComponentRegistration.add(new AdaptiveComponentRegistration());
|
||||
const services = new ServiceCollection({
|
||||
declarativeTypes: [],
|
||||
});
|
||||
|
||||
new AdaptiveBotComponent().configureServices(services, noOpConfiguration);
|
||||
|
||||
const declarativeTypes = services.mustMakeInstance('declarativeTypes');
|
||||
const explorer = new ResourceExplorer({ declarativeTypes }).addFolders(join(__dirname, 'resources'), [], false);
|
||||
|
||||
const dialog = explorer.loadType('test.dialog');
|
||||
assert.strictEqual(dialog.id, 'test.dialog', 'resource id should be used as default dialog id if none assigned.');
|
||||
assert.strictEqual(
|
||||
dialog.id,
|
||||
'test.dialog',
|
||||
'resource id should be used as default dialog id if none assigned.'
|
||||
);
|
||||
assert.strictEqual(dialog.triggers[0].actions[0].id, '1234567890');
|
||||
assert.strictEqual(dialog.triggers[0].actions[1].id, 'test3.dialog');
|
||||
|
||||
|
@ -126,13 +133,17 @@ describe('ResourecExplorer', function () {
|
|||
|
||||
let event, resource;
|
||||
explorer.changed = (e, resources) => {
|
||||
if (!event) { event = e; }
|
||||
if (!resource) { resource = resources[0]; }
|
||||
if (!event) {
|
||||
event = e;
|
||||
}
|
||||
if (!resource) {
|
||||
resource = resources[0];
|
||||
}
|
||||
};
|
||||
|
||||
// write test file
|
||||
writeFileSync(testPath, '{"test": 123}');
|
||||
await new Promise(resolve => setTimeout(resolve, 200));
|
||||
await new Promise((resolve) => setTimeout(resolve, 200));
|
||||
assert.strictEqual(event, ResourceChangeEvent.added);
|
||||
assert.strictEqual(resource.id, 'file_to_be_added.dialog');
|
||||
|
||||
|
@ -155,17 +166,21 @@ describe('ResourecExplorer', function () {
|
|||
|
||||
// write test file
|
||||
writeFileSync(testPath, '{"test": 123}');
|
||||
await new Promise(resolve => setTimeout(resolve, 100));
|
||||
await new Promise((resolve) => setTimeout(resolve, 100));
|
||||
|
||||
let event, resource;
|
||||
explorer.changed = (e, resources) => {
|
||||
if (!event) { event = e; }
|
||||
if (!resource) { resource = resources[0]; }
|
||||
if (!event) {
|
||||
event = e;
|
||||
}
|
||||
if (!resource) {
|
||||
resource = resources[0];
|
||||
}
|
||||
};
|
||||
|
||||
// change test file
|
||||
writeFileSync(testPath, '{"test": 1234}');
|
||||
await new Promise(resolve => setTimeout(resolve, 200));
|
||||
await new Promise((resolve) => setTimeout(resolve, 200));
|
||||
assert.strictEqual(event, ResourceChangeEvent.changed);
|
||||
assert.strictEqual(resource.id, 'file_to_be_changed.dialog');
|
||||
|
||||
|
@ -188,17 +203,21 @@ describe('ResourecExplorer', function () {
|
|||
|
||||
// write test file
|
||||
writeFileSync(testPath, '{"test": 123}');
|
||||
await new Promise(resolve => setTimeout(resolve, 100));
|
||||
await new Promise((resolve) => setTimeout(resolve, 100));
|
||||
|
||||
let event, resource;
|
||||
explorer.changed = (e, resources) => {
|
||||
if (!event) { event = e; }
|
||||
if (!resource) { resource = resources[0]; }
|
||||
if (!event) {
|
||||
event = e;
|
||||
}
|
||||
if (!resource) {
|
||||
resource = resources[0];
|
||||
}
|
||||
};
|
||||
|
||||
// remove test file
|
||||
unlinkSync(testPath);
|
||||
await new Promise(resolve => setTimeout(resolve, 200));
|
||||
await new Promise((resolve) => setTimeout(resolve, 200));
|
||||
assert.strictEqual(event, ResourceChangeEvent.removed);
|
||||
assert.strictEqual(resource.id, 'file_to_be_removed.dialog');
|
||||
|
||||
|
@ -222,7 +241,7 @@ describe('ResourecExplorer', function () {
|
|||
writeFileSync(testPath, '{"test": 123}');
|
||||
|
||||
// wait 200ms for file changes
|
||||
await new Promise(resolve => setTimeout(resolve, 200));
|
||||
await new Promise((resolve) => setTimeout(resolve, 200));
|
||||
assertResourceFound(explorer, 'foobar.dialog');
|
||||
assertResourceContents(explorer, 'foobar.dialog', '{"test": 123}');
|
||||
|
||||
|
@ -230,7 +249,7 @@ describe('ResourecExplorer', function () {
|
|||
writeFileSync(testPath, '{"test": 1234}');
|
||||
|
||||
// wait 200ms for file changes
|
||||
await new Promise(resolve => setTimeout(resolve, 200));
|
||||
await new Promise((resolve) => setTimeout(resolve, 200));
|
||||
assertResourceFound(explorer, 'foobar.dialog');
|
||||
assertResourceContents(explorer, 'foobar.dialog', '{"test": 1234}');
|
||||
|
||||
|
@ -238,7 +257,7 @@ describe('ResourecExplorer', function () {
|
|||
unlinkSync(testPath);
|
||||
|
||||
// wait 200ms for file changes
|
||||
await new Promise(resolve => setTimeout(resolve, 200));
|
||||
await new Promise((resolve) => setTimeout(resolve, 200));
|
||||
assertResourceNotFound(explorer, 'foobar.dialog');
|
||||
|
||||
const resourceProvider = explorer.resourceProviders[0];
|
||||
|
@ -246,12 +265,19 @@ describe('ResourecExplorer', function () {
|
|||
});
|
||||
|
||||
it('cycle reference', async () => {
|
||||
ComponentRegistration.add(new AdaptiveComponentRegistration());
|
||||
const resourceExplorer = new ResourceExplorer().addFolder(
|
||||
const services = new ServiceCollection({
|
||||
declarativeTypes: [],
|
||||
});
|
||||
|
||||
new AdaptiveBotComponent().configureServices(services, noOpConfiguration);
|
||||
|
||||
const declarativeTypes = services.mustMakeInstance('declarativeTypes');
|
||||
const resourceExplorer = new ResourceExplorer({ declarativeTypes }).addFolder(
|
||||
join(__dirname, './resources/CycleDetection'),
|
||||
false,
|
||||
false
|
||||
);
|
||||
|
||||
const root = resourceExplorer.loadType('root.dialog');
|
||||
const dm = new DialogManager(root);
|
||||
const adapter = new TestAdapter(async (context) => {
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
"@microsoft/recognizers-text-number": "1.1.4",
|
||||
"@microsoft/recognizers-text-suite": "1.1.4",
|
||||
"botbuilder-core": "4.1.6",
|
||||
"botbuilder-runtime-core": "4.1.6",
|
||||
"botbuilder-stdlib": "4.1.6",
|
||||
"botframework-connector": "4.1.6",
|
||||
"globalize": "^1.4.2",
|
||||
|
@ -49,7 +50,8 @@
|
|||
"clean": "rimraf _ts3.4 lib tsconfig.tsbuildinfo",
|
||||
"lint": "eslint . --ext .js,.ts",
|
||||
"postbuild": "downlevel-dts lib _ts3.4/lib --checksum",
|
||||
"test": "yarn build && nyc mocha tests/",
|
||||
"test": "npm-run-all build test:mocha",
|
||||
"test:mocha": "nyc mocha tests",
|
||||
"test:compat": "api-extractor run --verbose"
|
||||
},
|
||||
"files": [
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
import { BotComponent } from 'botbuilder-core';
|
||||
import { Configuration, ServiceCollection } from 'botbuilder-runtime-core';
|
||||
import { MemoryScope, PathResolver } from './memory';
|
||||
|
||||
import {
|
||||
ClassMemoryScope,
|
||||
ConversationMemoryScope,
|
||||
DialogClassMemoryScope,
|
||||
DialogContextMemoryScope,
|
||||
DialogMemoryScope,
|
||||
SettingsMemoryScope,
|
||||
ThisMemoryScope,
|
||||
TurnMemoryScope,
|
||||
UserMemoryScope,
|
||||
} from './memory/scopes';
|
||||
|
||||
import {
|
||||
AtAtPathResolver,
|
||||
AtPathResolver,
|
||||
DollarPathResolver,
|
||||
HashPathResolver,
|
||||
PercentPathResolver,
|
||||
} from './memory/pathResolvers';
|
||||
|
||||
export class DialogsBotComponent extends BotComponent {
|
||||
configureServices(services: ServiceCollection, _configuration: Configuration): void {
|
||||
services.composeFactory<MemoryScope[]>('memoryScopes', (memoryScopes) => {
|
||||
return memoryScopes.concat(
|
||||
new TurnMemoryScope(),
|
||||
new SettingsMemoryScope(),
|
||||
new DialogMemoryScope(),
|
||||
new DialogContextMemoryScope(),
|
||||
new DialogClassMemoryScope(),
|
||||
new ClassMemoryScope(),
|
||||
new ThisMemoryScope(),
|
||||
new ConversationMemoryScope(),
|
||||
new UserMemoryScope()
|
||||
);
|
||||
});
|
||||
|
||||
services.composeFactory<PathResolver[]>('pathResolvers', (pathResolvers) =>
|
||||
pathResolvers.concat(
|
||||
new DollarPathResolver(),
|
||||
new HashPathResolver(),
|
||||
new AtAtPathResolver(),
|
||||
new AtPathResolver(),
|
||||
new PercentPathResolver()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
|
@ -7,31 +7,34 @@
|
|||
*/
|
||||
|
||||
import { ComponentRegistration } from 'botbuilder-core';
|
||||
import { ServiceCollection, noOpConfiguration } from 'botbuilder-runtime-core';
|
||||
import { DialogsBotComponent } from './dialogsBotComponent';
|
||||
import { ComponentMemoryScopes, ComponentPathResolvers, MemoryScope, PathResolver } from './memory';
|
||||
import { AtAtPathResolver, AtPathResolver, DollarPathResolver, HashPathResolver, PercentPathResolver } from './memory/pathResolvers';
|
||||
import { ClassMemoryScope, ConversationMemoryScope, DialogClassMemoryScope, DialogContextMemoryScope, DialogMemoryScope, SettingsMemoryScope, ThisMemoryScope, TurnMemoryScope, UserMemoryScope } from './memory/scopes';
|
||||
|
||||
/**
|
||||
* Makes dialogs component available to the system registering functionality.
|
||||
*/
|
||||
export class DialogsComponentRegistration extends ComponentRegistration implements ComponentMemoryScopes, ComponentPathResolvers {
|
||||
export class DialogsComponentRegistration
|
||||
extends ComponentRegistration
|
||||
implements ComponentMemoryScopes, ComponentPathResolvers {
|
||||
private readonly services = new ServiceCollection({
|
||||
memoryScopes: [],
|
||||
pathResolvers: [],
|
||||
});
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
new DialogsBotComponent().configureServices(this.services, noOpConfiguration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the dialogs memory scopes.
|
||||
*
|
||||
* @returns {MemoryScope[]} A list of [MemoryScope](xref:botbuilder-dialogs.MemoryScope).
|
||||
*/
|
||||
public getMemoryScopes(): MemoryScope[] {
|
||||
return [
|
||||
new TurnMemoryScope(),
|
||||
new SettingsMemoryScope(),
|
||||
new DialogMemoryScope(),
|
||||
new DialogContextMemoryScope(),
|
||||
new DialogClassMemoryScope(),
|
||||
new ClassMemoryScope(),
|
||||
new ThisMemoryScope(),
|
||||
new ConversationMemoryScope(),
|
||||
new UserMemoryScope(),
|
||||
];
|
||||
return this.services.mustMakeInstance<MemoryScope[]>('memoryScopes');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -40,13 +43,6 @@ export class DialogsComponentRegistration extends ComponentRegistration implemen
|
|||
* @returns {PathResolver[]} A list of [PathResolver](xref:botbuilder-dialogs.PathResolver).
|
||||
*/
|
||||
public getPathResolvers(): PathResolver[] {
|
||||
return [
|
||||
new DollarPathResolver(),
|
||||
new HashPathResolver(),
|
||||
new AtAtPathResolver(),
|
||||
new AtPathResolver(),
|
||||
new PercentPathResolver(),
|
||||
];
|
||||
return this.services.mustMakeInstance<PathResolver[]>('pathResolvers');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -16,11 +16,10 @@ export * from './dialogContainer';
|
|||
export * from './dialogContext';
|
||||
export * from './dialogContextError';
|
||||
export * from './dialogEvents';
|
||||
export { runDialog } from './dialogHelper';
|
||||
export * from './dialogManager';
|
||||
export * from './dialogsComponentRegistration';
|
||||
export * from './dialogSet';
|
||||
export * from './dialogTurnStateConstants';
|
||||
export * from './dialogsBotComponent';
|
||||
export * from './memory';
|
||||
export * from './prompts';
|
||||
export * from './recognizer';
|
||||
|
@ -29,3 +28,5 @@ export * from './skillDialogOptions';
|
|||
export * from './template';
|
||||
export * from './waterfallDialog';
|
||||
export * from './waterfallStepContext';
|
||||
|
||||
export { runDialog } from './dialogHelper';
|
||||
|
|
|
@ -5,14 +5,15 @@
|
|||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License.
|
||||
*/
|
||||
import { PathResolver } from './pathResolvers';
|
||||
import { MemoryScope } from './scopes';
|
||||
import { DialogContext } from '../dialogContext';
|
||||
import { DialogPath } from './dialogPath';
|
||||
import { ComponentRegistration } from 'botbuilder-core';
|
||||
import { DialogsComponentRegistration } from '../dialogsComponentRegistration';
|
||||
|
||||
import { ComponentMemoryScopes, isComponentMemoryScopes } from './componentMemoryScopes';
|
||||
import { ComponentPathResolvers, isComponentPathResolvers } from './componentPathResolvers';
|
||||
import { ComponentRegistration } from 'botbuilder-core';
|
||||
import { DialogContext } from '../dialogContext';
|
||||
import { DialogPath } from './dialogPath';
|
||||
import { DialogsComponentRegistration } from '../dialogsComponentRegistration';
|
||||
import { MemoryScope } from './scopes';
|
||||
import { PathResolver } from './pathResolvers';
|
||||
|
||||
export interface DialogStateManagerConfiguration {
|
||||
/**
|
||||
|
@ -43,6 +44,7 @@ export class DialogStateManager {
|
|||
|
||||
/**
|
||||
* Initializes a new instance of the [DialogStateManager](xref:botbuilder-dialogs.DialogStateManager) class.
|
||||
*
|
||||
* @param dc The dialog context for the current turn of the conversation.
|
||||
* @param configuration Configuration for the dialog state manager.
|
||||
*/
|
||||
|
@ -51,22 +53,31 @@ export class DialogStateManager {
|
|||
|
||||
this.dialogContext = dc;
|
||||
this.configuration = configuration ?? dc.context.turnState.get(DIALOG_STATE_MANAGER_CONFIGURATION);
|
||||
|
||||
if (!this.configuration) {
|
||||
this.configuration = { memoryScopes: [], pathResolvers: [] };
|
||||
|
||||
// get all of the component memory scopes.
|
||||
ComponentRegistration.components.filter((component: ComponentRegistration) =>
|
||||
isComponentMemoryScopes(component)
|
||||
).forEach((component: ComponentMemoryScopes) => {
|
||||
this.configuration.memoryScopes.push(...component.getMemoryScopes());
|
||||
})
|
||||
ComponentRegistration.components
|
||||
.filter((component: ComponentRegistration) => isComponentMemoryScopes(component))
|
||||
.forEach((component: ComponentMemoryScopes) => {
|
||||
this.configuration.memoryScopes.push(...component.getMemoryScopes());
|
||||
});
|
||||
|
||||
// merge in turn state memory scopes
|
||||
const memoryScopes = dc.context.turnState.get<MemoryScope[]>('memoryScopes') ?? [];
|
||||
this.configuration.memoryScopes.push(...memoryScopes);
|
||||
|
||||
// get all of the component path resolvers.
|
||||
ComponentRegistration.components.filter((component: ComponentRegistration) =>
|
||||
isComponentPathResolvers(component)
|
||||
).forEach((component: ComponentPathResolvers) => {
|
||||
this.configuration.pathResolvers.push(...component.getPathResolvers());
|
||||
});
|
||||
ComponentRegistration.components
|
||||
.filter((component: ComponentRegistration) => isComponentPathResolvers(component))
|
||||
.forEach((component: ComponentPathResolvers) => {
|
||||
this.configuration.pathResolvers.push(...component.getPathResolvers());
|
||||
});
|
||||
|
||||
// merge in turn state ones path resolvers
|
||||
const pathResolvers = dc.context.turnState.get<PathResolver[]>('pathResolvers') ?? [];
|
||||
this.configuration.pathResolvers.push(...pathResolvers);
|
||||
|
||||
// cache for any other new dialogStateManager instances in this turn
|
||||
dc.context.turnState.set(DIALOG_STATE_MANAGER_CONFIGURATION, this.configuration);
|
||||
|
|
|
@ -5,10 +5,11 @@
|
|||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License.
|
||||
*/
|
||||
import { MemoryScope } from './memoryScope';
|
||||
import { ScopePath } from '../scopePath';
|
||||
|
||||
import { DialogContext } from '../../dialogContext';
|
||||
import { DialogTurnStateConstants } from '../../dialogTurnStateConstants';
|
||||
import { MemoryScope } from './memoryScope';
|
||||
import { ScopePath } from '../scopePath';
|
||||
|
||||
/**
|
||||
* The setting node.
|
||||
|
@ -58,12 +59,15 @@ export class SettingsMemoryScope extends MemoryScope {
|
|||
return dc.context.turnState.get(ScopePath.settings) ?? {};
|
||||
} else {
|
||||
const configuration = dc.context.turnState.get(DialogTurnStateConstants.configuration) ?? {};
|
||||
|
||||
Object.entries(process.env).reduce((result, [key, value]) => {
|
||||
result[`${key}`] = value;
|
||||
return result;
|
||||
}, configuration);
|
||||
|
||||
const settings = SettingsMemoryScope.loadSettings(configuration);
|
||||
dc.context.turnState.set(ScopePath.settings, settings);
|
||||
|
||||
return settings;
|
||||
}
|
||||
}
|
||||
|
@ -76,6 +80,7 @@ export class SettingsMemoryScope extends MemoryScope {
|
|||
*/
|
||||
protected static loadSettings(configuration: Record<string, string>): Record<string, unknown> {
|
||||
const settings = {};
|
||||
|
||||
if (configuration) {
|
||||
// load configuration into settings
|
||||
const root = this.convertFlattenSettingToNode(Object.entries(configuration));
|
||||
|
@ -84,6 +89,7 @@ export class SettingsMemoryScope extends MemoryScope {
|
|||
return result;
|
||||
}, settings);
|
||||
}
|
||||
|
||||
return settings;
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"dependency-graph": "^0.10.0",
|
||||
"p-reduce": "^2.1.0",
|
||||
"runtypes": "^5.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
@ -21,3 +21,15 @@ export interface Configuration {
|
|||
*/
|
||||
set(path: string[], value: unknown): void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Useful for shimming BotComponents into ComponentRegistrations
|
||||
*/
|
||||
export const noOpConfiguration: Configuration = {
|
||||
get(_path: string[]): unknown | undefined {
|
||||
return undefined;
|
||||
},
|
||||
set(_path: string[], _value: unknown): void {
|
||||
// no-op
|
||||
},
|
||||
};
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
// Licensed under the MIT License.
|
||||
|
||||
import assert from 'assert';
|
||||
import preduce from 'p-reduce';
|
||||
import { DepGraph } from 'dependency-graph';
|
||||
import { ok } from 'assert';
|
||||
import { stringify } from './util';
|
||||
|
@ -15,7 +14,7 @@ import { stringify } from './util';
|
|||
*/
|
||||
export type Factory<Type, Initial extends boolean> = (
|
||||
initialValue: Initial extends true ? Type : Type | undefined
|
||||
) => Type | Promise<Type>;
|
||||
) => Type;
|
||||
|
||||
/**
|
||||
* DependencyFactory is a function signature that produces an instance that depends on a set of
|
||||
|
@ -28,7 +27,7 @@ export type Factory<Type, Initial extends boolean> = (
|
|||
export type DependencyFactory<Type, Dependencies, Initial extends boolean> = (
|
||||
dependencies: Dependencies,
|
||||
initialValue: Initial extends true ? Type : Type | undefined
|
||||
) => Type | Promise<Type>;
|
||||
) => Type;
|
||||
|
||||
/**
|
||||
* ServiceCollection is an interface that describes a set of methods to register services. This, in a lighter way,
|
||||
|
@ -188,10 +187,10 @@ export class ServiceCollection {
|
|||
|
||||
// Register dependencies and then build nodes. Note: `nodes` is a function because ordering may
|
||||
// depend on results of dependency registration
|
||||
private async buildNodes<ReturnType = Record<string, unknown>>(
|
||||
private buildNodes<ReturnType = Record<string, unknown>>(
|
||||
generateNodes: () => string[],
|
||||
reuseServices: Record<string, unknown> = {}
|
||||
): Promise<ReturnType> {
|
||||
): ReturnType {
|
||||
// Consume all dependencies and then reset so updating registrations without re-registering
|
||||
// dependencies works
|
||||
this.dependencies.forEach((dependencies, node) =>
|
||||
|
@ -201,40 +200,32 @@ export class ServiceCollection {
|
|||
// Generate nodes after registering dependencies so ordering is correct
|
||||
const nodes = generateNodes();
|
||||
|
||||
const services = await preduce(
|
||||
nodes,
|
||||
async (services, service) => {
|
||||
// Extra precaution
|
||||
if (!this.graph.hasNode(service)) {
|
||||
return services;
|
||||
}
|
||||
const services = nodes.reduce((services, service) => {
|
||||
// Extra precaution
|
||||
if (!this.graph.hasNode(service)) {
|
||||
return services;
|
||||
}
|
||||
|
||||
// Helper to generate return value
|
||||
const assignValue = (value: unknown) => ({
|
||||
...services,
|
||||
[service]: value,
|
||||
});
|
||||
// Helper to generate return value
|
||||
const assignValue = (value: unknown) => ({
|
||||
...services,
|
||||
[service]: value,
|
||||
});
|
||||
|
||||
// Optionally reuse existing service
|
||||
const reusedService = reuseServices[service];
|
||||
if (reusedService !== undefined) {
|
||||
return assignValue(reusedService);
|
||||
}
|
||||
// Optionally reuse existing service
|
||||
const reusedService = reuseServices[service];
|
||||
if (reusedService !== undefined) {
|
||||
return assignValue(reusedService);
|
||||
}
|
||||
|
||||
// Each node stores a list of factory methods.
|
||||
const factories = this.graph.getNodeData(service);
|
||||
// Each node stores a list of factory methods.
|
||||
const factories = this.graph.getNodeData(service);
|
||||
|
||||
// Produce the instance by reducing those factories, passing the instance along for composition.
|
||||
const instance = await preduce(
|
||||
factories,
|
||||
(value, factory) => factory(services, value),
|
||||
<unknown>services[service]
|
||||
);
|
||||
// Produce the instance by reducing those factories, passing the instance along for composition.
|
||||
const instance = factories.reduce((value, factory) => factory(services, value), <unknown>services[service]);
|
||||
|
||||
return assignValue(instance);
|
||||
},
|
||||
<Record<string, unknown>>{}
|
||||
);
|
||||
return assignValue(instance);
|
||||
}, <Record<string, unknown>>{});
|
||||
|
||||
// Cache results for subsequent invocations that may desire pre-constructed instances
|
||||
Object.assign(this.cache, services);
|
||||
|
@ -249,7 +240,7 @@ export class ServiceCollection {
|
|||
* @param deep reconstruct all dependencies
|
||||
* @returns the service instance, or undefined
|
||||
*/
|
||||
async makeInstance<InstanceType = unknown>(key: string, deep = false): Promise<InstanceType | undefined> {
|
||||
makeInstance<InstanceType = unknown>(key: string, deep = false): InstanceType | undefined {
|
||||
// If this is not a deep reconstruction, reuse any services that `key` depends on
|
||||
let initialServices: Record<string, unknown> | undefined;
|
||||
if (!deep) {
|
||||
|
@ -257,7 +248,7 @@ export class ServiceCollection {
|
|||
initialServices = cached;
|
||||
}
|
||||
|
||||
const services = await this.buildNodes<Record<string, InstanceType | undefined>>(
|
||||
const services = this.buildNodes<Record<string, InstanceType | undefined>>(
|
||||
() => this.graph.dependenciesOf(key).concat(key),
|
||||
initialServices
|
||||
);
|
||||
|
@ -272,8 +263,8 @@ export class ServiceCollection {
|
|||
* @param deep reconstruct all dependencies
|
||||
* @returns the service instance
|
||||
*/
|
||||
async mustMakeInstance<InstanceType = unknown>(key: string, deep = false): Promise<InstanceType> {
|
||||
const instance = await this.makeInstance<InstanceType>(key, deep);
|
||||
mustMakeInstance<InstanceType = unknown>(key: string, deep = false): InstanceType {
|
||||
const instance = this.makeInstance<InstanceType>(key, deep);
|
||||
assert.ok(instance, `\`${key}\` instance undefined!`);
|
||||
|
||||
return instance;
|
||||
|
@ -284,7 +275,7 @@ export class ServiceCollection {
|
|||
*
|
||||
* @returns all resolved services
|
||||
*/
|
||||
makeInstances<InstancesType>(): Promise<InstancesType> {
|
||||
makeInstances<InstancesType>(): InstancesType {
|
||||
return this.buildNodes<InstancesType>(() => this.graph.overallOrder());
|
||||
}
|
||||
|
||||
|
@ -294,10 +285,10 @@ export class ServiceCollection {
|
|||
* @param keys instances that must be not undefined
|
||||
* @returns all resolve services
|
||||
*/
|
||||
async mustMakeInstances<InstancesType extends Record<string, unknown> = Record<string, unknown>>(
|
||||
mustMakeInstances<InstancesType extends Record<string, unknown> = Record<string, unknown>>(
|
||||
...keys: string[]
|
||||
): Promise<InstancesType> {
|
||||
const instances = await this.makeInstances<InstancesType>();
|
||||
): InstancesType {
|
||||
const instances = this.makeInstances<InstancesType>();
|
||||
|
||||
keys.forEach((key) => {
|
||||
assert.ok(instances[key], `\`${key}\` instance undefined!`);
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
import assert from 'assert';
|
||||
import { ServiceCollection } from '../src/serviceCollection';
|
||||
import { deepStrictEqual, notStrictEqual, ok, rejects, strictEqual } from 'assert';
|
||||
|
||||
class Foo {}
|
||||
|
||||
|
@ -26,98 +26,98 @@ describe('ServiceCollection', () => {
|
|||
const services = new ServiceCollection(defaultServices);
|
||||
|
||||
services.addInstance('foo', new Foo());
|
||||
services.addFactory<Bar, { foo: Foo }>('bar', ['foo'], async ({ foo }) => new Bar(foo));
|
||||
services.addFactory<Bar, { foo: Foo }>('bar', ['foo'], ({ foo }) => new Bar(foo));
|
||||
services.addFactory<Baz, { foo: Foo; bar: Bar }>('baz', ['foo', 'bar'], ({ foo, bar }) => new Baz(foo, bar));
|
||||
|
||||
return services;
|
||||
};
|
||||
|
||||
describe('makeInstances', () => {
|
||||
it('works', async () => {
|
||||
it('works', () => {
|
||||
const services = makeServiceCollection();
|
||||
|
||||
const { foo, bar, baz, bil } = await services.mustMakeInstances<{
|
||||
const { foo, bar, baz, bil } = services.mustMakeInstances<{
|
||||
foo: Foo;
|
||||
bar: Bar;
|
||||
baz: Baz;
|
||||
bil?: unknown;
|
||||
}>('foo', 'bar', 'baz');
|
||||
|
||||
ok(bil === undefined);
|
||||
assert.ok(bil === undefined);
|
||||
|
||||
strictEqual(bar.foo, foo);
|
||||
strictEqual(baz.bar, bar);
|
||||
strictEqual(baz.bar.foo, foo);
|
||||
assert.strictEqual(bar.foo, foo);
|
||||
assert.strictEqual(baz.bar, bar);
|
||||
assert.strictEqual(baz.bar.foo, foo);
|
||||
});
|
||||
|
||||
describe('providing defaults', () => {
|
||||
it('initialValue style', async () => {
|
||||
it('initialValue style', () => {
|
||||
const services = new ServiceCollection();
|
||||
|
||||
services.addFactory<number[]>('values', async (values = [1]) => values.concat(2));
|
||||
services.composeFactory<number[]>('values', async (values) => values.concat(3));
|
||||
services.addFactory<number[]>('values', (values = [1]) => values.concat(2));
|
||||
services.composeFactory<number[]>('values', (values) => values.concat(3));
|
||||
|
||||
const { values } = await services.makeInstances();
|
||||
deepStrictEqual(values, [1, 2, 3]);
|
||||
const { values } = services.makeInstances();
|
||||
assert.deepStrictEqual(values, [1, 2, 3]);
|
||||
});
|
||||
|
||||
it('constructor style', async () => {
|
||||
it('constructor style', () => {
|
||||
const services = new ServiceCollection({
|
||||
values: [1],
|
||||
});
|
||||
|
||||
services.composeFactory<number[]>('values', async (values) => values.concat(2));
|
||||
services.composeFactory<number[]>('values', async (values) => values.concat(3));
|
||||
services.composeFactory<number[]>('values', (values) => values.concat(2));
|
||||
services.composeFactory<number[]>('values', (values) => values.concat(3));
|
||||
|
||||
const { values } = await services.makeInstances();
|
||||
deepStrictEqual(values, [1, 2, 3]);
|
||||
const { values } = services.makeInstances();
|
||||
assert.deepStrictEqual(values, [1, 2, 3]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('mustMakeInstances', () => {
|
||||
it('throws if a service instance is undefined', async () => {
|
||||
it('throws if a service instance is undefined', () => {
|
||||
const services = new ServiceCollection();
|
||||
await rejects(services.mustMakeInstances('value'));
|
||||
assert.throws(() => services.mustMakeInstances('value'));
|
||||
});
|
||||
});
|
||||
|
||||
describe('makeInstance', () => {
|
||||
it('uses cached dependencies by default', async () => {
|
||||
it('uses cached dependencies by default', () => {
|
||||
const services = makeServiceCollection();
|
||||
|
||||
const { bar, baz } = await services.mustMakeInstances<{ bar: Bar; baz: Baz }>('bar', 'baz');
|
||||
const newBaz = await services.mustMakeInstance<Baz>('baz');
|
||||
const { bar, baz } = services.mustMakeInstances<{ bar: Bar; baz: Baz }>('bar', 'baz');
|
||||
const newBaz = services.mustMakeInstance<Baz>('baz');
|
||||
|
||||
notStrictEqual(newBaz, baz);
|
||||
strictEqual(newBaz.bar, bar);
|
||||
assert.notStrictEqual(newBaz, baz);
|
||||
assert.strictEqual(newBaz.bar, bar);
|
||||
});
|
||||
|
||||
it('optionally fully reconstructs dependencies', async () => {
|
||||
it('optionally fully reconstructs dependencies', () => {
|
||||
const services = makeServiceCollection();
|
||||
|
||||
const { foo, bar, baz } = await services.makeInstances();
|
||||
ok(foo);
|
||||
ok(bar);
|
||||
ok(baz);
|
||||
const { foo, bar, baz } = services.makeInstances();
|
||||
assert.ok(foo);
|
||||
assert.ok(bar);
|
||||
assert.ok(baz);
|
||||
|
||||
const newBaz = await services.makeInstance<Baz>('baz', true);
|
||||
ok(newBaz);
|
||||
const newBaz = services.makeInstance<Baz>('baz', true);
|
||||
assert.ok(newBaz);
|
||||
|
||||
notStrictEqual(newBaz, baz);
|
||||
notStrictEqual(newBaz.bar, bar);
|
||||
assert.notStrictEqual(newBaz, baz);
|
||||
assert.notStrictEqual(newBaz.bar, bar);
|
||||
});
|
||||
});
|
||||
|
||||
describe('mustMakeInstance', () => {
|
||||
it('throws if a service instance is undefined', async () => {
|
||||
it('throws if a service instance is undefined', () => {
|
||||
const services = new ServiceCollection();
|
||||
await rejects(services.mustMakeInstance('value'));
|
||||
assert.throws(() => services.mustMakeInstance('value'));
|
||||
});
|
||||
});
|
||||
|
||||
describe('factory handling', () => {
|
||||
it('works', async () => {
|
||||
it('works', () => {
|
||||
const services = new ServiceCollection({
|
||||
a: {},
|
||||
b: {},
|
||||
|
@ -133,11 +133,11 @@ describe('ServiceCollection', () => {
|
|||
({ a }, b) => ({ ...a, ...b })
|
||||
);
|
||||
|
||||
const a = await services.mustMakeInstance('a');
|
||||
deepStrictEqual(a, { key: 'value' });
|
||||
const a = services.mustMakeInstance('a');
|
||||
assert.deepStrictEqual(a, { key: 'value' });
|
||||
});
|
||||
|
||||
it('throws for undefined initial value', async () => {
|
||||
it('throws for undefined initial value', () => {
|
||||
const services = new ServiceCollection({
|
||||
a: {},
|
||||
});
|
||||
|
@ -147,7 +147,7 @@ describe('ServiceCollection', () => {
|
|||
['a'],
|
||||
({ a }, b) => ({ ...a, ...b })
|
||||
);
|
||||
await rejects(services.makeInstance('b'));
|
||||
assert.throws(() => services.makeInstance('b'));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -63,17 +63,14 @@ export async function makeApp(
|
|||
): Promise<[app: express.Application, listen: (callback?: () => void) => http.Server]> {
|
||||
const configOverrides: Partial<Options> = {};
|
||||
|
||||
const port = (await Promise.all(['port', 'PORT'].map((key) => configuration.string([key])))).find(
|
||||
(port) => port !== undefined
|
||||
);
|
||||
|
||||
const port = ['port', 'PORT'].map((key) => configuration.string([key])).find((port) => port !== undefined);
|
||||
if (port !== undefined) {
|
||||
configOverrides.port = port;
|
||||
}
|
||||
|
||||
const validatedOptions = TypedOptions.check(Object.assign({}, defaultOptions, configOverrides, options));
|
||||
|
||||
const { adapter, bot, customAdapters } = await services.mustMakeInstances<{
|
||||
const { adapter, bot, customAdapters } = services.mustMakeInstances<{
|
||||
adapter: BotFrameworkAdapter;
|
||||
bot: ActivityHandlerBase;
|
||||
customAdapters: Map<string, BotFrameworkAdapter>;
|
||||
|
@ -125,7 +122,8 @@ export async function makeApp(
|
|||
);
|
||||
|
||||
server.on('upgrade', async (req, socket, head) => {
|
||||
const adapter = await services.mustMakeInstance<BotFrameworkAdapter>('adapter');
|
||||
const adapter = services.mustMakeInstance<BotFrameworkAdapter>('adapter');
|
||||
|
||||
adapter.useWebSocket(req, socket, head, async (context) => {
|
||||
await bot.run(context);
|
||||
});
|
||||
|
|
|
@ -32,10 +32,7 @@ const defaultOptions: Options = {
|
|||
async function resolveOptions(options: Partial<Options>, configuration: Configuration): Promise<Options> {
|
||||
const configOverrides: Partial<Options> = {};
|
||||
|
||||
const port = (await Promise.all(['port', 'PORT'].map((key) => configuration.string([key])))).find(
|
||||
(port) => port !== undefined
|
||||
);
|
||||
|
||||
const port = ['port', 'PORT'].map((key) => configuration.string([key])).find((port) => port !== undefined);
|
||||
if (port !== undefined) {
|
||||
configOverrides.port = port;
|
||||
}
|
||||
|
@ -77,14 +74,13 @@ export async function makeServer(
|
|||
configuration: Configuration,
|
||||
options: Partial<Options> = {}
|
||||
): Promise<restify.Server> {
|
||||
const [{ adapter, bot, customAdapters }, resolvedOptions] = await Promise.all([
|
||||
services.mustMakeInstances<{
|
||||
adapter: BotFrameworkAdapter;
|
||||
bot: ActivityHandlerBase;
|
||||
customAdapters: Map<string, BotFrameworkAdapter>;
|
||||
}>('adapter', 'bot', 'customAdapters'),
|
||||
resolveOptions(options, configuration),
|
||||
]);
|
||||
const { adapter, bot, customAdapters } = services.mustMakeInstances<{
|
||||
adapter: BotFrameworkAdapter;
|
||||
bot: ActivityHandlerBase;
|
||||
customAdapters: Map<string, BotFrameworkAdapter>;
|
||||
}>('adapter', 'bot', 'customAdapters');
|
||||
|
||||
const resolvedOptions = await resolveOptions(options, configuration);
|
||||
|
||||
const server = restify.createServer();
|
||||
|
||||
|
@ -122,7 +118,8 @@ export async function makeServer(
|
|||
});
|
||||
|
||||
server.on('upgrade', async (req, socket, head) => {
|
||||
const adapter = await services.mustMakeInstance<BotFrameworkAdapter>('adapter');
|
||||
const adapter = services.mustMakeInstance<BotFrameworkAdapter>('adapter');
|
||||
|
||||
adapter.useWebSocket(req, socket, head, async (context) => {
|
||||
await bot.run(context);
|
||||
});
|
||||
|
|
|
@ -41,6 +41,11 @@ export class Configuration implements CoreConfiguration {
|
|||
* @returns the value, or undefined
|
||||
*/
|
||||
get(path: string[]): unknown | undefined {
|
||||
// Note: empty path should yield the entire configuration
|
||||
if (!path.length) {
|
||||
return this.provider.get();
|
||||
}
|
||||
|
||||
return this.provider.get(this.key(path));
|
||||
}
|
||||
|
||||
|
|
|
@ -2,14 +2,14 @@
|
|||
// Licensed under the MIT License.
|
||||
|
||||
import { Configuration } from './configuration';
|
||||
import { FolderResourceProvider, ResourceExplorer } from 'botbuilder-dialogs-declarative';
|
||||
import { ComponentDeclarativeTypes, FolderResourceProvider, ResourceExplorer } from 'botbuilder-dialogs-declarative';
|
||||
import { ok } from 'assert';
|
||||
|
||||
export class ConfigurationResourceExporer extends ResourceExplorer {
|
||||
private readonly folderResourceProvider: FolderResourceProvider;
|
||||
|
||||
constructor(configuration: Configuration) {
|
||||
super();
|
||||
constructor(configuration: Configuration, declarativeTypes: ComponentDeclarativeTypes[]) {
|
||||
super({ declarativeTypes });
|
||||
|
||||
const applicationRoot = configuration.string(['applicationRoot']);
|
||||
ok(applicationRoot);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
import { DialogManager } from 'botbuilder-dialogs';
|
||||
import { DialogManager, MemoryScope, PathResolver } from 'botbuilder-dialogs';
|
||||
import { ResourceExplorer } from 'botbuilder-dialogs-declarative';
|
||||
|
||||
import {
|
||||
|
@ -31,7 +31,9 @@ export class CoreBot extends ActivityHandler {
|
|||
skillConversationIdFactory: SkillConversationIdFactoryBase,
|
||||
botTelemetryClient: BotTelemetryClient,
|
||||
defaultLocale: string,
|
||||
defaultRootDialog: string
|
||||
defaultRootDialog: string,
|
||||
memoryScopes: MemoryScope[],
|
||||
pathResolvers: PathResolver[]
|
||||
) {
|
||||
super();
|
||||
|
||||
|
@ -50,6 +52,21 @@ export class CoreBot extends ActivityHandler {
|
|||
SkillExtensions.useSkillConversationIdFactory(dialogManager, skillConversationIdFactory);
|
||||
useTelemetry(dialogManager, botTelemetryClient);
|
||||
|
||||
/* TODO(jgummersall) reconcile:
|
||||
* _dialogManager.InitialTurnState.Set(botFrameworkClient);
|
||||
* _dialogManager.InitialTurnState.Set(conversationIdfactory);
|
||||
* _dialogManager.InitialTurnState.Set(_userState); (handled by useBotState?)
|
||||
* _dialogManager.InitialTurnState.Set(_conversationState); (handled by useBotState?)
|
||||
*/
|
||||
|
||||
if (memoryScopes.length) {
|
||||
dialogManager.initialTurnState.set('memoryScopes', memoryScopes);
|
||||
}
|
||||
|
||||
if (pathResolvers.length) {
|
||||
dialogManager.initialTurnState.set('pathResolvers', pathResolvers);
|
||||
}
|
||||
|
||||
this.onTurn(async (turnContext) => {
|
||||
await dialogManager.onTurn(turnContext);
|
||||
await conversationState.saveChanges(turnContext, false);
|
||||
|
|
|
@ -6,15 +6,16 @@ import fs from 'fs';
|
|||
import path from 'path';
|
||||
import { Configuration } from './configuration';
|
||||
|
||||
import { AdaptiveComponentRegistration } from 'botbuilder-dialogs-adaptive';
|
||||
import { DialogsBotComponent, MemoryScope, PathResolver } from 'botbuilder-dialogs';
|
||||
import { AdaptiveBotComponent, LanguageGenerationBotComponent } from 'botbuilder-dialogs-adaptive';
|
||||
import { ApplicationInsightsTelemetryClient, TelemetryInitializerMiddleware } from 'botbuilder-applicationinsights';
|
||||
import { BlobsStorage, BlobsTranscriptStore } from 'botbuilder-azure-blobs';
|
||||
import { ConfigurationResourceExporer } from './configurationResourceExplorer';
|
||||
import { CoreBot } from './coreBot';
|
||||
import { CoreBotAdapter } from './coreBotAdapter';
|
||||
import { CosmosDbPartitionedStorage } from 'botbuilder-azure';
|
||||
import { LuisComponentRegistration, QnAMakerComponentRegistration } from 'botbuilder-ai';
|
||||
import { ResourceExplorer } from 'botbuilder-dialogs-declarative';
|
||||
import { ComponentDeclarativeTypes, ResourceExplorer } from 'botbuilder-dialogs-declarative';
|
||||
import { LuisBotComponent, QnAMakerBotComponent } from 'botbuilder-ai';
|
||||
import { ServiceCollection } from 'botbuilder-runtime-core';
|
||||
|
||||
import {
|
||||
|
@ -28,11 +29,9 @@ import {
|
|||
ActivityHandlerBase,
|
||||
BotAdapter,
|
||||
BotComponent,
|
||||
isBotComponent,
|
||||
BotFrameworkAdapter,
|
||||
BotTelemetryClient,
|
||||
ChannelServiceHandler,
|
||||
ComponentRegistration,
|
||||
ConsoleTranscriptLogger,
|
||||
ConversationState,
|
||||
InspectionMiddleware,
|
||||
|
@ -51,6 +50,7 @@ import {
|
|||
TelemetryLoggerMiddleware,
|
||||
TranscriptLoggerMiddleware,
|
||||
UserState,
|
||||
assertBotComponent,
|
||||
} from 'botbuilder';
|
||||
|
||||
function addFeatures(services: ServiceCollection, configuration: Configuration): void {
|
||||
|
@ -237,6 +237,8 @@ function addCoreBot(services: ServiceCollection, configuration: Configuration):
|
|||
{
|
||||
botTelemetryClient: BotTelemetryClient;
|
||||
conversationState: ConversationState;
|
||||
memoryScopes: MemoryScope[];
|
||||
pathResolvers: PathResolver[];
|
||||
resourceExplorer: ResourceExplorer;
|
||||
skillClient: SkillHttpClient;
|
||||
skillConversationIdFactory: SkillConversationIdFactoryBase;
|
||||
|
@ -245,12 +247,14 @@ function addCoreBot(services: ServiceCollection, configuration: Configuration):
|
|||
>(
|
||||
'bot',
|
||||
[
|
||||
'resourceExplorer',
|
||||
'userState',
|
||||
'botTelemetryClient',
|
||||
'conversationState',
|
||||
'memoryScopes',
|
||||
'pathResolvers',
|
||||
'resourceExplorer',
|
||||
'skillClient',
|
||||
'skillConversationIdFactory',
|
||||
'botTelemetryClient',
|
||||
'userState',
|
||||
],
|
||||
(dependencies) =>
|
||||
new CoreBot(
|
||||
|
@ -261,7 +265,9 @@ function addCoreBot(services: ServiceCollection, configuration: Configuration):
|
|||
dependencies.skillConversationIdFactory,
|
||||
dependencies.botTelemetryClient,
|
||||
configuration.string(['defaultLocale']) ?? 'en-US',
|
||||
configuration.string(['defaultRootDialog']) ?? 'main.dialog'
|
||||
configuration.string(['defaultRootDialog']) ?? 'main.dialog',
|
||||
dependencies.memoryScopes,
|
||||
dependencies.pathResolvers
|
||||
)
|
||||
);
|
||||
|
||||
|
@ -292,21 +298,22 @@ function addCoreBot(services: ServiceCollection, configuration: Configuration):
|
|||
);
|
||||
}
|
||||
|
||||
async function addBotComponents(services: ServiceCollection, configuration: Configuration): Promise<void> {
|
||||
const loadBotComponent = async (name: string): Promise<BotComponent | undefined> => {
|
||||
try {
|
||||
const DefaultExport = (await import(name))?.default;
|
||||
if (DefaultExport) {
|
||||
const instance = new DefaultExport();
|
||||
if (isBotComponent(instance)) {
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
} catch (_err) {
|
||||
// no-op
|
||||
async function addSettingsBotComponents(services: ServiceCollection, configuration: Configuration): Promise<void> {
|
||||
const loadBotComponent = async (name: string): Promise<BotComponent> => {
|
||||
const Export = await import(name);
|
||||
if (!Export) {
|
||||
throw new Error(`Unable to import ${name}`);
|
||||
}
|
||||
|
||||
return undefined;
|
||||
const DefaultExport = Export.default;
|
||||
if (!DefaultExport) {
|
||||
throw new Error(`${name} has no default export`);
|
||||
}
|
||||
|
||||
const instance = new DefaultExport();
|
||||
assertBotComponent(instance, [`import(${name})`, 'default']);
|
||||
|
||||
return instance;
|
||||
};
|
||||
|
||||
const components =
|
||||
|
@ -320,13 +327,20 @@ async function addBotComponents(services: ServiceCollection, configuration: Conf
|
|||
)
|
||||
) ?? [];
|
||||
|
||||
for (const { name, settingsPrefix } of components) {
|
||||
const botComponent = await loadBotComponent(name);
|
||||
if (!botComponent) {
|
||||
throw new TypeError(`Unable to load ${botComponent} component`);
|
||||
}
|
||||
const errs: Error[] = [];
|
||||
|
||||
await Promise.resolve(botComponent.configureServices(services, configuration.bind([settingsPrefix ?? name])));
|
||||
for (const { name, settingsPrefix } of components) {
|
||||
try {
|
||||
const botComponent = await loadBotComponent(name);
|
||||
|
||||
botComponent.configureServices(services, configuration.bind([settingsPrefix ?? name]));
|
||||
} catch (err) {
|
||||
errs.push(err);
|
||||
}
|
||||
}
|
||||
|
||||
if (errs.length) {
|
||||
throw new Error(errs.map((err) => `[${err}]`).join(', '));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -346,25 +360,21 @@ async function normalizeConfiguration(configuration: Configuration, applicationR
|
|||
);
|
||||
}
|
||||
|
||||
function registerAdaptiveComponents(services: ServiceCollection): void {
|
||||
services.composeFactory<typeof ComponentRegistration>('componentRegistration', (componentRegistration) => {
|
||||
componentRegistration.add(new AdaptiveComponentRegistration());
|
||||
return componentRegistration;
|
||||
});
|
||||
function registerAdaptiveComponents(services: ServiceCollection, configuration: Configuration): void {
|
||||
new AdaptiveBotComponent().configureServices(services, configuration);
|
||||
new LanguageGenerationBotComponent().configureServices(services, configuration);
|
||||
}
|
||||
|
||||
function registerLuisComponents(services: ServiceCollection): void {
|
||||
services.composeFactory<typeof ComponentRegistration>('componentRegistration', (componentRegistration) => {
|
||||
componentRegistration.add(new LuisComponentRegistration());
|
||||
return componentRegistration;
|
||||
});
|
||||
function registerDialogsComponents(services: ServiceCollection, configuration: Configuration): void {
|
||||
new DialogsBotComponent().configureServices(services, configuration);
|
||||
}
|
||||
|
||||
function registerQnAComponents(services: ServiceCollection): void {
|
||||
services.composeFactory<typeof ComponentRegistration>('componentRegistration', (componentRegistration) => {
|
||||
componentRegistration.add(new QnAMakerComponentRegistration());
|
||||
return componentRegistration;
|
||||
});
|
||||
function registerLuisComponents(services: ServiceCollection, configuration: Configuration): void {
|
||||
new LuisBotComponent().configureServices(services, configuration);
|
||||
}
|
||||
|
||||
function registerQnAComponents(services: ServiceCollection, configuration: Configuration): void {
|
||||
new QnAMakerBotComponent().configureServices(services, configuration);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -413,20 +423,23 @@ export async function getRuntimeServices(
|
|||
await normalizeConfiguration(configuration, applicationRoot);
|
||||
|
||||
const services = new ServiceCollection({
|
||||
componentRegistration: ComponentRegistration,
|
||||
customAdapters: new Map(),
|
||||
declarativeTypes: [],
|
||||
memoryScopes: [],
|
||||
middlewares: new MiddlewareSet(),
|
||||
pathResolvers: [],
|
||||
});
|
||||
|
||||
services.addFactory(
|
||||
services.addFactory<ResourceExplorer, { declarativeTypes: ComponentDeclarativeTypes[] }>(
|
||||
'resourceExplorer',
|
||||
['componentRegistration'], // implicit dependency
|
||||
() => new ConfigurationResourceExporer(configuration)
|
||||
['declarativeTypes'],
|
||||
({ declarativeTypes }) => new ConfigurationResourceExporer(configuration, declarativeTypes)
|
||||
);
|
||||
|
||||
registerAdaptiveComponents(services);
|
||||
registerLuisComponents(services);
|
||||
registerQnAComponents(services);
|
||||
registerAdaptiveComponents(services, configuration);
|
||||
registerDialogsComponents(services, configuration);
|
||||
registerLuisComponents(services, configuration);
|
||||
registerQnAComponents(services, configuration);
|
||||
|
||||
const runtimeSettings = configuration.bind(['runtimeSettings']);
|
||||
|
||||
|
@ -435,7 +448,7 @@ export async function getRuntimeServices(
|
|||
addSkills(services, runtimeSettings.bind(['skills']));
|
||||
addStorage(services, configuration);
|
||||
addTelemetry(services, runtimeSettings.bind(['telemetry']));
|
||||
await addBotComponents(services, configuration);
|
||||
await addSettingsBotComponents(services, configuration);
|
||||
|
||||
return [services, configuration];
|
||||
}
|
||||
|
|
|
@ -12,19 +12,19 @@ describe('getRuntimeServices', () => {
|
|||
it('works', async () => {
|
||||
const [services] = await getRuntimeServices(__dirname, __dirname);
|
||||
ok(services);
|
||||
ok(await services.makeInstances());
|
||||
ok(services.makeInstances());
|
||||
});
|
||||
|
||||
it('works with preset configuration', async () => {
|
||||
const [services] = await getRuntimeServices(__dirname, new Configuration());
|
||||
ok(services);
|
||||
ok(await services.makeInstances());
|
||||
ok(services.makeInstances());
|
||||
});
|
||||
|
||||
it('supports bot components and late binding configuration', async () => {
|
||||
class MyComponent extends BotComponent {
|
||||
configureServices(services: ServiceCollection, configuration: CoreConfiguration): void {
|
||||
services.composeFactory<Map<string, BotFrameworkAdapter>>('customAdapters', async (customAdapters) => {
|
||||
services.composeFactory<Map<string, BotFrameworkAdapter>>('customAdapters', (customAdapters) => {
|
||||
const name = configuration.get(['customAdapter', 'name']);
|
||||
ok(typeof name === 'string');
|
||||
|
||||
|
@ -43,7 +43,7 @@ describe('getRuntimeServices', () => {
|
|||
|
||||
configuration.set(['customAdapter', 'name'], 'foo');
|
||||
|
||||
const customAdapter = await services.mustMakeInstance<Map<string, BotFrameworkAdapter>>('customAdapters');
|
||||
const customAdapter = services.mustMakeInstance<Map<string, BotFrameworkAdapter>>('customAdapters');
|
||||
ok(customAdapter.get('foo'));
|
||||
});
|
||||
|
||||
|
@ -52,7 +52,7 @@ describe('getRuntimeServices', () => {
|
|||
const [services] = await getRuntimeServices(__dirname, __dirname);
|
||||
ok(services);
|
||||
|
||||
const storage = await services.mustMakeInstance('storage');
|
||||
const storage = services.mustMakeInstance('storage');
|
||||
ok(storage instanceof MemoryStorage);
|
||||
});
|
||||
|
||||
|
@ -69,7 +69,7 @@ describe('getRuntimeServices', () => {
|
|||
const [services] = await getRuntimeServices(__dirname, configuration);
|
||||
ok(services);
|
||||
|
||||
const storage = await services.mustMakeInstance('storage');
|
||||
const storage = services.mustMakeInstance('storage');
|
||||
ok(storage instanceof BlobsStorage);
|
||||
});
|
||||
|
||||
|
@ -88,7 +88,7 @@ describe('getRuntimeServices', () => {
|
|||
const [services] = await getRuntimeServices(__dirname, configuration);
|
||||
ok(services);
|
||||
|
||||
const storage = await services.mustMakeInstance('storage');
|
||||
const storage = services.mustMakeInstance('storage');
|
||||
ok(storage instanceof CosmosDbPartitionedStorage);
|
||||
});
|
||||
});
|
||||
|
|
13
yarn.lock
13
yarn.lock
|
@ -9428,10 +9428,10 @@ ora@^4.0.3:
|
|||
strip-ansi "^6.0.0"
|
||||
wcwidth "^1.0.1"
|
||||
|
||||
orchestrator-core@4.12.0-preview:
|
||||
version "4.12.0-preview"
|
||||
resolved "https://registry.yarnpkg.com/orchestrator-core/-/orchestrator-core-4.12.0-preview.tgz#e16703ff0fe45a96cd7b637fcec7697448584a36"
|
||||
integrity sha512-RHQM5UK7xZuV9eN+NJKv/iGKBeQ/Pvxkki1j2Bgm1pq845Icor51MrlJKmAeJSIVxIUY0r4JBBNulLfq3I4UPA==
|
||||
orchestrator-core@next:
|
||||
version "4.13.0-dev.20210325.421845fh"
|
||||
resolved "https://registry.yarnpkg.com/orchestrator-core/-/orchestrator-core-4.13.0-dev.20210325.421845fh.tgz#8d7481c7a48d3c144fc1611bb735c2b7e507fa1a"
|
||||
integrity sha512-wnWEuWC4iR78F7j1p0R7v0YfKIv21atpmz0gTIcvfT7WrQudAFIlmp2uRUUx3AFdV+SngZiLBxTZ7lOKnp/Q9Q==
|
||||
dependencies:
|
||||
bindings "1.2.1"
|
||||
node-addon-api "^3.0.0"
|
||||
|
@ -9574,11 +9574,6 @@ p-map@^4.0.0:
|
|||
dependencies:
|
||||
aggregate-error "^3.0.0"
|
||||
|
||||
p-reduce@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/p-reduce/-/p-reduce-2.1.0.tgz#09408da49507c6c274faa31f28df334bc712b64a"
|
||||
integrity sha512-2USApvnsutq8uoxZBGbbWM0JIYLiEMJ9RlaN7fAzVNb9OZN0SHjjTTfIcb667XynS5Y1VhwDJVDa72TnPzAYWw==
|
||||
|
||||
p-timeout@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-2.0.1.tgz#d8dd1979595d2dc0139e1fe46b8b646cb3cdf038"
|
||||
|
|
Загрузка…
Ссылка в новой задаче