Skip to content
This repository was archived by the owner on Jan 15, 2025. It is now read-only.

Commit e3e08c7

Browse files
authored
optimzie cross train to care only trigger intents and allow empty trigger intent or dialog (#706)
1 parent d0e65ab commit e3e08c7

File tree

2 files changed

+136
-12
lines changed

2 files changed

+136
-12
lines changed

packages/lu/src/parser/cross-train/crossTrainer.js

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -95,10 +95,10 @@ const constructResoureTree = function (fileIdToLuResourceMap, triggerRules) {
9595

9696
const destLuFileToIntent = triggerRules[fileId]
9797
for (const destLuFile of Object.keys(destLuFileToIntent)) {
98-
if (!fileIdsFromInput.includes(destLuFile)) continue
98+
if (destLuFile !== '' && !fileIdsFromInput.includes(destLuFile)) continue
9999

100100
const triggerIntentName = destLuFileToIntent[destLuFile]
101-
if (!intents.some(i => i.Name === triggerIntentName)) {
101+
if (triggerIntentName !== '' && !intents.some(i => i.Name === triggerIntentName)) {
102102
throw (new exception(retCode.errorCode.INVALID_INPUT, `Sorry, trigger intent '${triggerIntentName}' is not found in lu file: ${fileId}`))
103103
}
104104

@@ -144,7 +144,7 @@ const mergeRootInterruptionToLeaves = function (rootResource, result, qnaFileToR
144144
mergeBrothersInterruption(rootResource, result, intentName)
145145
for (const child of rootResource.children) {
146146
let childResource = result.get(child.target)
147-
if (childResource.visited === undefined) {
147+
if (childResource && childResource.visited === undefined) {
148148
const rootQnaFileId = rootResource.id.replace(new RegExp(helpers.FileExtTypeEnum.LUFile + '$'), helpers.FileExtTypeEnum.QnAFile)
149149
const rootQnaResource = qnaFileToResourceMap.get(rootQnaFileId)
150150
const newChildResource = mergeFatherInterruptionToChild(rootResource, rootQnaResource, childResource, intentName)
@@ -161,7 +161,8 @@ const mergeBrothersInterruption = function (resource, result, intentName) {
161161
let triggerIntent = child.intent
162162
const brotherSections = resource.content.Sections.filter(s => s.Name !== triggerIntent
163163
&& s.Name !== intentName
164-
&& (s.SectionType === LUSectionTypes.SIMPLEINTENTSECTION || s.SectionType === LUSectionTypes.NESTEDINTENTSECTION))
164+
&& (s.SectionType === LUSectionTypes.SIMPLEINTENTSECTION || s.SectionType === LUSectionTypes.NESTEDINTENTSECTION)
165+
&& children.some(brotherChild => brotherChild.intent === s.Name))
165166

166167
let brotherUtterances = []
167168
brotherSections.forEach(s => {
@@ -177,8 +178,10 @@ const mergeBrothersInterruption = function (resource, result, intentName) {
177178
let targetResource = result.get(child.target)
178179

179180
// Merge direct brother's utterances
180-
targetResource = mergeInterruptionIntent(brotherUtterances, targetResource, intentName)
181-
result.set(targetResource.id, targetResource)
181+
if (targetResource) {
182+
targetResource = mergeInterruptionIntent(brotherUtterances, targetResource, intentName)
183+
result.set(targetResource.id, targetResource)
184+
}
182185
}
183186
}
184187

packages/lu/test/parser/cross-train/crossTrainer.test.js

Lines changed: 127 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -242,12 +242,11 @@ describe('luis:cross training tests among lu and qna contents', () => {
242242
assert.equal(luResult.get('dia1.fr-fr.lu').Sections[2].Name, '_Interruption')
243243
assert.equal(luResult.get('dia1.fr-fr.lu').Sections[2].Body, `- guide de l'utilisateur${NEWLINE}${NEWLINE}> Source: cross training. Please do not edit these directly!`)
244244
assert.equal(luResult.get('dia1.fr-fr.lu').Sections[3].Name, 'DeferToRecognizer_QnA_dia1')
245-
assert.equal(luResult.get('dia1.fr-fr.lu').Sections[3].Body, `- raconter la blague`)
245+
assert.equal(luResult.get('dia1.fr-fr.lu').Sections[3].Body, '- raconter la blague')
246246

247247
assert.equal(qnaResult.get('dia1.fr-fr.qna').Sections[1].Questions.join(', '), 'J\'ai besoin d\'un hôtel quatre étoiles, puis-je réserver un hôtel près de l\'aiguille spatiale, guide de l\'utilisateur')
248248
})
249249

250-
251250
it('luis:cross training can get expected result when nestedIntentSection is enabled', () => {
252251
let luContentArray = []
253252

@@ -297,7 +296,7 @@ describe('luis:cross training tests among lu and qna contents', () => {
297296
const luResult = trainedResult.luResult
298297

299298
assert.equal(luResult.get('./dia2/dia2.lu').Sections[1].Name, '_Interruption')
300-
assert.equal(luResult.get('./dia2/dia2.lu').Sections[1].Body, `- book a flight for me`)
299+
assert.equal(luResult.get('./dia2/dia2.lu').Sections[1].Body, '- book a flight for me')
301300
})
302301

303302
it('luis:cross training can get expected result when multiple dialog invocations occur in same trigger', () => {
@@ -353,12 +352,134 @@ describe('luis:cross training tests among lu and qna contents', () => {
353352
const luResult = trainedResult.luResult
354353

355354
assert.equal(luResult.get('./dia1/dia1.lu').Sections[1].Name, '_Interruption')
356-
assert.equal(luResult.get('./dia1/dia1.lu').Sections[1].Body, `- book a hotel for me`)
355+
assert.equal(luResult.get('./dia1/dia1.lu').Sections[1].Body, '- book a hotel for me')
356+
357+
assert.equal(luResult.get('./dia2/dia2.lu').Sections[1].Name, '_Interruption')
358+
assert.equal(luResult.get('./dia2/dia2.lu').Sections[1].Body, '- book a hotel for me')
359+
360+
assert.equal(luResult.get('./dia3/dia3.lu').Sections[1].Name, '_Interruption')
361+
assert.equal(luResult.get('./dia3/dia3.lu').Sections[1].Body, '- I want to travel to Seattle')
362+
})
363+
364+
it('luis:cross training can get expected result when local intents exist', () => {
365+
let luContentArray = []
366+
367+
luContentArray.push({
368+
content:
369+
`# dia1_trigger
370+
- I want to travel to Seattle
371+
372+
# dia2_trigger
373+
- book a hotel for me
374+
375+
# local_intent
376+
- help`,
377+
id: './main/main.lu'}
378+
)
379+
380+
luContentArray.push({
381+
content:
382+
`# bookTicket
383+
- book a flight for me
384+
- book a train ticket for me`,
385+
id: './dia1/dia1.lu'}
386+
)
387+
388+
luContentArray.push({
389+
content:
390+
`# hotelLevel
391+
- I prefer 4 stars hotel`,
392+
id: './dia2/dia2.lu'}
393+
)
394+
395+
let crossTrainConfig = {
396+
rootIds: [
397+
'./main/main.lu'
398+
],
399+
triggerRules: {
400+
'./main/main.lu': {
401+
'./dia1/dia1.lu': 'dia1_trigger',
402+
'./dia2/dia2.lu': 'dia2_trigger'
403+
}
404+
},
405+
intentName: '_Interruption',
406+
verbose: true
407+
}
408+
409+
const trainedResult = crossTrainer.crossTrain(luContentArray, [], crossTrainConfig)
410+
const luResult = trainedResult.luResult
411+
412+
assert.equal(luResult.get('./dia1/dia1.lu').Sections[1].Name, '_Interruption')
413+
assert.equal(luResult.get('./dia1/dia1.lu').Sections[1].Body, '- book a hotel for me')
414+
415+
assert.equal(luResult.get('./dia2/dia2.lu').Sections[1].Name, '_Interruption')
416+
assert.equal(luResult.get('./dia2/dia2.lu').Sections[1].Body, '- I want to travel to Seattle')
417+
})
418+
419+
it('luis:cross training can get expected result when trigger intent or dialog is empty', () => {
420+
let luContentArray = []
421+
422+
luContentArray.push({
423+
content:
424+
`# dia1_trigger
425+
- I want to travel to Seattle
426+
427+
# dia2_trigger
428+
- book a hotel for me
429+
430+
# dia3_trigger
431+
- cancel`,
432+
id: './main/main.lu'}
433+
)
434+
435+
luContentArray.push({
436+
content:
437+
`# bookTicket
438+
- book a flight for me
439+
- book a train ticket for me`,
440+
id: './dia1/dia1.lu'}
441+
)
442+
443+
luContentArray.push({
444+
content:
445+
`# hotelLevel
446+
- I prefer 4 stars hotel`,
447+
id: './dia2/dia2.lu'}
448+
)
449+
450+
luContentArray.push({
451+
content:
452+
`# help
453+
- can I help you`,
454+
id: './dia3/dia3.lu'}
455+
)
456+
457+
let crossTrainConfig = {
458+
rootIds: [
459+
'./main/main.lu'
460+
],
461+
triggerRules: {
462+
'./main/main.lu': {
463+
'./dia1/dia1.lu': 'dia1_trigger',
464+
'./dia2/dia2.lu': 'dia2_trigger',
465+
'': 'dia3_trigger',
466+
'./dia3/dia3.lu': ''
467+
}
468+
},
469+
intentName: '_Interruption',
470+
verbose: true
471+
}
472+
473+
const trainedResult = crossTrainer.crossTrain(luContentArray, [], crossTrainConfig)
474+
const luResult = trainedResult.luResult
475+
476+
assert.equal(luResult.get('./dia1/dia1.lu').Sections[1].Name, '_Interruption')
477+
assert.equal(luResult.get('./dia1/dia1.lu').Sections[1].Body, `- book a hotel for me${NEWLINE}- cancel`)
357478

358479
assert.equal(luResult.get('./dia2/dia2.lu').Sections[1].Name, '_Interruption')
359-
assert.equal(luResult.get('./dia2/dia2.lu').Sections[1].Body, `- book a hotel for me`)
480+
assert.equal(luResult.get('./dia2/dia2.lu').Sections[1].Body, `- I want to travel to Seattle${NEWLINE}- cancel`)
360481

361482
assert.equal(luResult.get('./dia3/dia3.lu').Sections[1].Name, '_Interruption')
362-
assert.equal(luResult.get('./dia3/dia3.lu').Sections[1].Body, `- I want to travel to Seattle`)
483+
assert.equal(luResult.get('./dia3/dia3.lu').Sections[1].Body, `- I want to travel to Seattle${NEWLINE}- book a hotel for me${NEWLINE}- cancel`)
363484
})
364485
})

0 commit comments

Comments
 (0)