Skip to content
This repository was archived by the owner on Jul 9, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
a4c2292
Genericizing OnChooseIntent
taicchoumsft Apr 14, 2021
c538ca6
Merge branch 'main' into tachou/disambigTemplateUpdate
taicchoumsft Apr 14, 2021
231ebc4
Merge branch 'main' into tachou/disambigTemplateUpdate
taicchoumsft Apr 14, 2021
a5f488d
Merge branch 'main' into tachou/disambigTemplateUpdate
taicchoumsft Apr 14, 2021
4923d39
Merge branch 'main' into tachou/disambigTemplateUpdate
taicchoumsft Apr 14, 2021
16516fb
Fix broken schema
taicchoumsft Apr 15, 2021
60998df
Allow more than 2 choices
taicchoumsft Apr 15, 2021
994e58b
linter fixes
taicchoumsft Apr 15, 2021
004ea3e
Merge branch 'main' into tachou/disambigTemplateUpdate
taicchoumsft Apr 15, 2021
a543c82
Merge branch 'main' into tachou/disambigTemplateUpdate
taicchoumsft Apr 15, 2021
1cbca49
Merge branch 'main' into tachou/disambigTemplateUpdate
taicchoumsft Apr 15, 2021
b0e837b
Merge branch 'main' into tachou/disambigTemplateUpdate
taicchoumsft Apr 15, 2021
7772aae
Merge branch 'main' into tachou/disambigTemplateUpdate
cwhitten Apr 15, 2021
6cf44a4
Merge branch 'main' into tachou/disambigTemplateUpdate
cwhitten Apr 15, 2021
262776f
Merge branch 'main' into tachou/disambigTemplateUpdate
taicchoumsft Apr 16, 2021
b042a91
Merge branch 'main' into tachou/disambigTemplateUpdate
cwhitten Apr 16, 2021
eb1d062
trigger.ts not sending locale to worker
taicchoumsft Apr 18, 2021
7077369
Merge branch 'main' into tachou/disambigTemplateUpdate
taicchoumsft Apr 18, 2021
58a9277
Fix to normalize the names in lgUtil
taicchoumsft Apr 19, 2021
e6277ea
Remove all OnChooseIntent LG from common
taicchoumsft Apr 19, 2021
6e7db66
Rename parent template name to ChooseIntent
taicchoumsft Apr 19, 2021
d82b583
Merge branch 'main' into tachou/disambigTemplateUpdate
taicchoumsft Apr 19, 2021
dabc744
Minor refactor
taicchoumsft Apr 19, 2021
722508e
fix linter issues
taicchoumsft Apr 19, 2021
cc5c129
Merge branch 'main' into tachou/disambigTemplateUpdate
taicchoumsft Apr 19, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 13 additions & 18 deletions Composer/packages/client/src/recoilModel/dispatchers/trigger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,29 +80,24 @@ const getNewDialogWithTrigger = async (
];
await createLgTemplates({ id: lgFile.id, templates: lgTemplates, projectId });
} else if (formData.$kind === onChooseIntentKey) {
const designerId1 = getDesignerIdFromDialogPath(newDialog, `content.triggers[${index}].actions[4].prompt`);
const designerId1 = getDesignerIdFromDialogPath(newDialog, `content.triggers[${index}].actions[2].prompt`);
const designerId2 = getDesignerIdFromDialogPath(
newDialog,
`content.triggers[${index}].actions[5].elseActions[0].activity`
`content.triggers[${index}].actions[3].elseActions[0].activity`
);
const lgTemplates1: LgTemplate[] = [
LgTemplateSamples.TextInputPromptForOnChooseIntent(designerId1) as LgTemplate,
const lgTemplates: LgTemplate[] = [
LgTemplateSamples.textInputPromptForOnChooseIntent(designerId1) as LgTemplate,
LgTemplateSamples.onChooseIntentAdaptiveCard(designerId1) as LgTemplate,
LgTemplateSamples.whichOneDidYouMean(designerId1) as LgTemplate,
LgTemplateSamples.pickOne(designerId1) as LgTemplate,
LgTemplateSamples.getAnswerReadBack(designerId1) as LgTemplate,
LgTemplateSamples.getIntentReadBack(designerId1) as LgTemplate,
LgTemplateSamples.generateChoices(designerId1) as LgTemplate,
LgTemplateSamples.choice(designerId1) as LgTemplate,
LgTemplateSamples.SendActivityForOnChooseIntent(designerId2) as LgTemplate,
];

let lgTemplates2: LgTemplate[] = [
LgTemplateSamples.adaptiveCardJson as LgTemplate,
LgTemplateSamples.whichOneDidYouMean as LgTemplate,
LgTemplateSamples.pickOne as LgTemplate,
LgTemplateSamples.getAnswerReadBack as LgTemplate,
LgTemplateSamples.getIntentReadBack as LgTemplate,
];
const commonlgFile = lgFiles.find(({ id }) => id === `common.${locale}`);

lgTemplates2 = lgTemplates2.filter((t) => commonlgFile?.templates.findIndex((clft) => clft.name === t.name) === -1);

await createLgTemplates({ id: `common.${locale}`, templates: lgTemplates2, projectId });
await createLgTemplates({ id: lgFile.id, templates: lgTemplates1, projectId });
await createLgTemplates({ id: lgFile.id, templates: lgTemplates, projectId });
}
return {
id: newDialog.id,
Expand Down Expand Up @@ -165,7 +160,7 @@ export const triggerDispatcher = () => {
luFile &&
deleteActions(
actions,
(templateNames: string[]) => removeLgTemplates({ id: dialogId, templateNames, projectId }),
(templateNames: string[]) => removeLgTemplates({ id: `${dialogId}.${locale}`, templateNames, projectId }),
(intentNames: string[]) =>
Promise.all(intentNames.map((intentName) => removeLuIntent({ id: luFile.id, intentName, projectId })))
);
Expand Down
34 changes: 33 additions & 1 deletion Composer/packages/lib/indexers/src/utils/lgUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
Range,
LgFile,
DiagnosticSeverity,
LgTemplateRef,
} from '@bfc/shared';
import formatMessage from 'format-message';
import isEmpty from 'lodash/isEmpty';
Expand Down Expand Up @@ -238,12 +239,43 @@ export function removeTemplates(
): LgFile {
const { id } = lgFile;
let resource = getLgResource(lgFile, importResolver);
templateNames.forEach((templateName) => {

const normalizedLgTemplates = templateNames
.map((x) => {
const lgTemplateRef = LgTemplateRef.parse(x);
return lgTemplateRef ? lgTemplateRef.name : x;
})
.filter((x) => !!x);

const generatedLgTemplateNames = getGeneratedLgTemplateNames(lgFile, normalizedLgTemplates);

[...normalizedLgTemplates, ...generatedLgTemplateNames].forEach((templateName) => {
resource = resource.deleteTemplate(templateName);
});
return convertTemplatesToLgFile(id, resource.toString(), resource);
}

/**
* This util function returns the names of all auto generated templates associated with the templates being removed.
* @param file Lg file that contains the templates.
* @param toBeRemovedLgTemplateNames Names of Lg templates that are being removed.
*/
const getGeneratedLgTemplateNames = (file: LgFile, toBeRemovedLgTemplateNames: string[]) => {
const generatedLgTemplateNames: string[] = [];
const lgTemplates = file.templates.filter((t) => toBeRemovedLgTemplateNames.includes(t.name) && !!t.properties);
for (const lgTemplate of lgTemplates) {
// Auto-generated templates in structured responses have the following pattern
// [name of the parent template]_text OR [name of the parent template]_speak OR [name of the parent template]_attachment_[random string]
const pattern = `${lgTemplate.name}_((text|speak)|(attachment_.+))$`;
// eslint-disable-next-line security/detect-non-literal-regexp
const regex = new RegExp(`^${pattern}`);
const generatedLgTemplates = file.templates.map((t) => t.name).filter((name) => regex.test(name));
generatedLgTemplateNames.push(...generatedLgTemplates);
}

return generatedLgTemplateNames;
};

export function textFromTemplate(template: LgTemplate): string {
const { name, parameters = [], body } = template;
const textBuilder: string[] = [];
Expand Down
183 changes: 107 additions & 76 deletions Composer/packages/lib/shared/src/constant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -349,60 +349,55 @@ export const QnALocales = [
'vi-vn',
];

const adaptiveCardJsonBody =
'-```\
\n{\
\n "$schema",\
\n "version": "1.0",\
\n "type": "AdaptiveCard",\
\n "speak": "",\
\n "body": [\
\n {\
\n "type": "TextBlock",\
\n "text": "${whichOneDidYouMean()}",\
\n "weight": "Bolder"\
\n },\
\n {\
\n "type": "TextBlock",\
\n "text": "${pickOne()}",\
\n "separator": "true"\
\n },\
\n {\
\n "type": "Input.ChoiceSet",\
\n "placeholder": "Placeholder text",\
\n "id": "userChosenIntent",\
\n "choices": [\
\n {\
\n "title": "${getIntentReadBack()}",\
\n "value": "luisResult"\
\n },\
\n {\
\n "title": "${getAnswerReadBack()}",\
\n "value": "qnaResult"\
\n },\
\n {\
\n "title": "None of the above",\
\n "value": "none"\
\n }\
\n ],\
\n "style": "expanded",\
\n "value": "luis"\
\n },\
\n {\
\n "type": "ActionSet",\
\n "actions": [\
\n {\
\n "type": "Action.Submit",\
\n "title": "Submit",\
\n "data": {\
\n "intent": "chooseIntentCardResponse"\
\n }\
\n }\
\n ]\
\n }\
\n ]\
\n}\
```';
export const chooseIntentTemplatePrefix = 'ChooseIntent';

const adaptiveCardJsonBody = (designerId: string) =>
`-\`\`\`{
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"version": "1.0",
"type": "AdaptiveCard",
"speak": "",
"body": [
{
"type": "TextBlock",
"text": "\${${chooseIntentTemplatePrefix}_${designerId}_attachment_whichOneDidYouMean()}",
"weight": "Bolder"
},
{
"type": "TextBlock",
"text": "\${${chooseIntentTemplatePrefix}_${designerId}_attachment_pickOne()}",
"separator": "true"
},
{
"type": "Input.ChoiceSet",
"placeholder": "Placeholder text",
"id": "userChosenIntent",
"choices": [
\${${chooseIntentTemplatePrefix}_${designerId}_attachment_generateChoices()},
{
"title": "None of the above",
"value": "none"
}
],
"style": "expanded",
"value": "luis"
},
{
"type": "ActionSet",
"actions": [
{
"type": "Action.Submit",
"title": "Submit",
"data": {
"intent": "chooseIntentCardResponse"
}
}
]
}
]
}
\`\`\`
`;

const whichOneDidYouMeanBody = `\
- I'm not sure which one you mean.
Expand All @@ -414,50 +409,86 @@ const pickOne = `\
- Can you help clarify by choosing one ?
`;

const getIntentReadBack = `\
- SWITCH : \${toLower(dialog.luisResult.intent)}
const getIntentReadBack = (designerId: string) => `\
- SWITCH : \${intent}
- CASE: \${'QnAMatch'}
- \${${chooseIntentTemplatePrefix}_${designerId}_attachment_getAnswerReadBack()}
- CASE : \${'GetUserProfile'}
- Start filling in your profile(GetUserProfile intent)
- DEFAULT :
- \${dialog.luisResult.intent}
- \${intent}
`;

const generateChoices = (designerId: string) => `\
- \${join(foreach(indicesAndValues(candidates), c, ${chooseIntentTemplatePrefix}_${designerId}_attachment_choice(c.value.intent, c.index)), ',')}
`;

const choice = (designerId: string) => `\
- { "title": "\${${chooseIntentTemplatePrefix}_${designerId}_attachment_getIntentReadBack(title)}", "value": "\${value}" }
`;

const getAnswerReadBack = `- See an answer from the Knowledge Base
`;

export const LgTemplateSamples = {
['adaptiveCardJson']: {
name: 'AdaptiveCardJson',
body: adaptiveCardJsonBody,
onChooseIntentAdaptiveCard: (designerId: string) => {
return {
name: `${chooseIntentTemplatePrefix}_${designerId}_attachment_card`,
body: adaptiveCardJsonBody(designerId),
parameters: ['candidates'],
};
},
whichOneDidYouMean: (designerId: string) => {
return {
name: `${chooseIntentTemplatePrefix}_${designerId}_attachment_whichOneDidYouMean`,
body: whichOneDidYouMeanBody,
};
},
pickOne: (designerId: string) => {
return {
name: `${chooseIntentTemplatePrefix}_${designerId}_attachment_pickOne`,
body: pickOne,
};
},
['whichOneDidYouMean']: {
name: `whichOneDidYouMean`,
body: whichOneDidYouMeanBody,
getAnswerReadBack: (designerId: string) => {
return {
name: `${chooseIntentTemplatePrefix}_${designerId}_attachment_getAnswerReadBack`,
body: getAnswerReadBack,
};
},
['pickOne']: {
name: 'pickOne',
body: pickOne,
getIntentReadBack: (designerId: string) => {
return {
name: `${chooseIntentTemplatePrefix}_${designerId}_attachment_getIntentReadBack`,
parameters: ['intent'],
body: getIntentReadBack(designerId),
};
},
['getAnswerReadBack']: {
name: 'getAnswerReadBack',
body: getAnswerReadBack,
generateChoices: (designerId: string) => {
return {
name: `${chooseIntentTemplatePrefix}_${designerId}_attachment_generateChoices`,
parameters: ['candidates'],
body: generateChoices(designerId),
};
},
['getIntentReadBack']: {
name: 'getIntentReadBack',
body: getIntentReadBack,
choice: (designerId: string) => {
return {
name: `${chooseIntentTemplatePrefix}_${designerId}_attachment_choice`,
parameters: ['title', 'value'],
body: choice(designerId),
};
},
TextInputPromptForOnChooseIntent: (designerId) => {
textInputPromptForOnChooseIntent: (designerId) => {
return {
name: `TextInput_Prompt_${designerId}`,
name: `${chooseIntentTemplatePrefix}_${designerId}`,
body: `[Activity
Attachments = \${json(AdaptiveCardJson())}
Attachments = \${json(${chooseIntentTemplatePrefix}_${designerId}_attachment_card(dialog.candidates))}
]
`,
};
},
SendActivityForOnChooseIntent: (designerId) => {
return {
name: `SendActivity_${designerId}`,
name: `${chooseIntentTemplatePrefix}_SendActivity_${designerId}`,
body: '- Sure, no worries.\n',
};
},
Expand Down
Loading