Skip to content

Commit

Permalink
feat: Add QnA files to dispatch model in skill manifest (#3985)
Browse files Browse the repository at this point in the history
* [feat]: Add QnA files to dispatch model in skill manifest

* conditionally add lu files

Co-authored-by: Chris Whitten <christopher.whitten@microsoft.com>
Co-authored-by: Andy Brown <asbrown002@gmail.com>
  • Loading branch information
3 people committed Sep 15, 2020
1 parent a78a8f4 commit f5c30f3
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -187,34 +187,47 @@ describe('generateDispatchModels', () => {
const dialogs: any = [{ id: 'test', content: { recognizer: 'test.lu' } }];
const selectedTriggers = [];
const luFiles = [];
const result = generateDispatchModels(schema, dialogs, selectedTriggers, luFiles);
const qnaFiles = [];
const result = generateDispatchModels(schema, dialogs, selectedTriggers, luFiles, qnaFiles);
expect(result).toEqual({});
});

it("should return empty object if the schema doesn't include dispatchModels", () => {
const schema = { properties: {} };
const dialogs: any = [{ id: 'test', content: { recognizer: 'test.lu' } }];
const dialogs: any = [{ id: 'test', content: { recognizer: 'test.lu.qna' } }];
const selectedTriggers = [{ $kind: SDKKinds.OnIntent, intent: 'testIntent' }];
const luFiles: any = [{ id: 'test.en-us' }, { id: 'test.fr-FR' }];
const result = generateDispatchModels(schema, dialogs, selectedTriggers, luFiles);
const luFiles: any = [
{ id: 'test.en-us', empty: false },
{ id: 'test.fr-FR', empty: false },
];
const qnaFiles = [];
const result = generateDispatchModels(schema, dialogs, selectedTriggers, luFiles, qnaFiles);
expect(result).toEqual({});
});

it('should return empty object if the recognizer type is not luis', () => {
const schema = { properties: {} };
const dialogs: any = [{ id: 'test', content: {} }];
const selectedTriggers = [{ $kind: SDKKinds.OnIntent, intent: 'testIntent' }];
const luFiles: any = [{ id: 'test.en-us' }, { id: 'test.fr-FR' }];
const result = generateDispatchModels(schema, dialogs, selectedTriggers, luFiles);
const luFiles: any = [
{ id: 'test.en-us', empty: false },
{ id: 'test.fr-FR', empty: false },
];
const qnaFiles = [];
const result = generateDispatchModels(schema, dialogs, selectedTriggers, luFiles, qnaFiles);
expect(result).toEqual({});
});

it('should return dispatch models', () => {
const schema = { properties: { dispatchModels: {} } };
const dialogs: any = [{ id: 'test', content: { recognizer: 'test.lu' }, isRoot: true }];
const dialogs: any = [{ id: 'test', content: { recognizer: 'test.lu.qna' }, isRoot: true }];
const selectedTriggers = [{ $kind: SDKKinds.OnIntent, intent: 'testIntent' }];
const luFiles: any = [{ id: 'test.en-us' }, { id: 'test.fr-FR' }];
const result = generateDispatchModels(schema, dialogs, selectedTriggers, luFiles);
const luFiles: any = [
{ id: 'test.en-us', empty: false },
{ id: 'test.fr-FR', empty: false },
];
const qnaFiles: any = [{ id: 'test.es-es', empty: false }];
const result = generateDispatchModels(schema, dialogs, selectedTriggers, luFiles, qnaFiles);
expect(result).toEqual(
expect.objectContaining({
dispatchModels: {
Expand All @@ -223,15 +236,23 @@ describe('generateDispatchModels', () => {
{
name: 'test',
contentType: 'application/lu',
url: `<test.en-us url>`,
url: `<test.en-us.lu url>`,
description: '<description>',
},
],
'fr-FR': [
{
name: 'test',
contentType: 'application/lu',
url: `<test.fr-FR url>`,
url: `<test.fr-FR.lu url>`,
description: '<description>',
},
],
'es-es': [
{
name: 'test',
contentType: 'application/qna',
url: `<test.es-es.qna url>`,
description: '<description>',
},
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Licensed under the MIT License.

import get from 'lodash/get';
import { DialogInfo, DialogSchemaFile, ITrigger, SDKKinds, SkillManifest, LuFile } from '@bfc/shared';
import { DialogInfo, DialogSchemaFile, ITrigger, SDKKinds, SkillManifest, LuFile, QnAFile } from '@bfc/shared';
import { JSONSchema7 } from '@bfc/extension-client';

import { Activities, Activity, activityHandlerMap, ActivityTypes, DispatchModels } from './constants';
Expand All @@ -17,6 +17,7 @@ export const generateSkillManifest = (
dialogs: DialogInfo[],
dialogSchemas: DialogSchemaFile[],
luFiles: LuFile[],
qnaFiles: QnAFile[],
selectedTriggers: ITrigger[],
selectedDialogs: Partial<DialogInfo>[]
) => {
Expand All @@ -41,7 +42,7 @@ export const generateSkillManifest = (
}, []);

const activities = generateActivities(dialogSchemas, triggers, resolvedDialogs);
const dispatchModels = generateDispatchModels(schema, dialogs, triggers, luFiles);
const dispatchModels = generateDispatchModels(schema, dialogs, triggers, luFiles, qnaFiles);
const definitions = getDefinitions(dialogSchemas, resolvedDialogs);

return {
Expand Down Expand Up @@ -104,7 +105,8 @@ export const generateDispatchModels = (
schema: JSONSchema7,
dialogs: DialogInfo[],
selectedTriggers: any[],
luFiles: LuFile[]
luFiles: LuFile[],
qnaFiles: QnAFile[]
): { dispatchModels?: DispatchModels } => {
const intents = selectedTriggers.filter(({ $kind }) => $kind === SDKKinds.OnIntent).map(({ intent }) => intent);
const { id: rootId } = dialogs.find((dialog) => dialog?.isRoot) || {};
Expand All @@ -114,16 +116,46 @@ export const generateDispatchModels = (
return luId === rootId;
});

if (!intents.length || !schema.properties?.dispatchModels) {
const rootQnAFiles = qnaFiles.filter(({ id: qnaFileId }) => {
const [qnaId] = qnaFileId.split('.');
return qnaId === rootId;
});

if (!schema.properties?.dispatchModels) {
return {};
}

const languages = rootLuFiles.reduce((acc, { id }) => {
const luLanguages = intents.length
? rootLuFiles.reduce((acc, { empty, id }) => {
const [name, locale] = id.split('.');
const { content = {} } = dialogs.find(({ id }) => id === name) || {};
const { recognizer = '' } = content;

if (!recognizer.includes('.lu') || empty) {
return acc;
}

return {
...acc,
[locale]: [
...(acc[locale] ?? []),
{
name,
contentType: 'application/lu',
url: `<${id}.lu url>`,
description: '<description>',
},
],
};
}, {})
: {};

const languages = rootQnAFiles.reduce((acc, { empty, id }) => {
const [name, locale] = id.split('.');
const { content = {} } = dialogs.find(({ id }) => id === name) || {};
const { recognizer = '' } = content;

if (!''.endsWith.call(recognizer, '.lu')) {
if (!recognizer.includes('.qna') || empty) {
return acc;
}

Expand All @@ -133,19 +165,21 @@ export const generateDispatchModels = (
...(acc[locale] ?? []),
{
name,
contentType: 'application/lu',
url: `<${id} url>`,
contentType: 'application/qna',
url: `<${id}.qna url>`,
description: '<description>',
},
],
};
}, {});
}, luLanguages);

const dispatchModels = {
...(Object.keys(languages).length ? { languages } : {}),
...(intents.length ? { intents } : {}),
};

return {
dispatchModels: {
...(Object.keys(languages).length ? { languages } : {}),
...(intents.length ? { intents } : {}),
},
...(Object.keys(dispatchModels).length ? { dispatchModels } : {}),
};
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
dispatcherState,
luFilesState,
skillManifestsState,
qnaFilesState,
} from '../../../recoilModel';

import { editorSteps, ManifestEditorSteps, order } from './constants';
Expand All @@ -34,6 +35,7 @@ const ExportSkillModal: React.FC<ExportSkillModalProps> = ({ onSubmit, onDismiss
const dialogs = useRecoilValue(dialogsState);
const dialogSchemas = useRecoilValue(dialogSchemasState);
const luFiles = useRecoilValue(luFilesState);
const qnaFiles = useRecoilValue(qnaFilesState);
const skillManifests = useRecoilValue(skillManifestsState);
const { updateSkillManifest } = useRecoilValue(dispatcherState);

Expand All @@ -59,6 +61,7 @@ const ExportSkillModal: React.FC<ExportSkillModalProps> = ({ onSubmit, onDismiss
dialogs,
dialogSchemas,
luFiles,
qnaFiles,
selectedTriggers,
selectedDialogs
);
Expand Down

0 comments on commit f5c30f3

Please sign in to comment.