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

Commit 67ed91d

Browse files
authored
fix pattern issue in cross train (#759)
1 parent 417edfc commit 67ed91d

File tree

2 files changed

+122
-8
lines changed

2 files changed

+122
-8
lines changed

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

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ const DiagnosticSeverity = require('../lufile/diagnostic').DiagnosticSeverity
1212
const fileHelper = require('../../utils/filehelper')
1313
const exception = require('../utils/exception')
1414
const retCode = require('../utils/enums/CLI-errors')
15+
const prebuiltEntityTypes = require('../utils/enums/luisbuiltintypes').consolidatedList
1516
const NEWLINE = require('os').EOL
1617
const path = require('path')
1718
const QNA_GENERIC_SOURCE = "custom editorial"
@@ -185,10 +186,10 @@ const mergeBrothersInterruption = function (resource, result, intentName) {
185186
let brotherUtterances = []
186187
brotherSections.forEach(s => {
187188
if (s.SectionType === LUSectionTypes.SIMPLEINTENTSECTION) {
188-
brotherUtterances = brotherUtterances.concat(s.UtteranceAndEntitiesMap.map(u => u.utterance))
189+
brotherUtterances = brotherUtterances.concat(s.UtteranceAndEntitiesMap.map(u => u.utterance).filter(i => !patternWithPrebuiltEntity(i)))
189190
} else {
190191
s.SimpleIntentSections.forEach(section => {
191-
brotherUtterances = brotherUtterances.concat(section.UtteranceAndEntitiesMap.map(u => u.utterance))
192+
brotherUtterances = brotherUtterances.concat(section.UtteranceAndEntitiesMap.map(u => u.utterance).filter(i => !patternWithPrebuiltEntity(i)))
192193
})
193194
}
194195
})
@@ -300,21 +301,20 @@ const removeDupUtterances = function (resource) {
300301

301302
const extractIntentUtterances = function(resource, intentName) {
302303
const intentSections = resource.Sections.filter(s => s.SectionType === LUSectionTypes.SIMPLEINTENTSECTION || s.SectionType === LUSectionTypes.NESTEDINTENTSECTION)
303-
const curlyRe = /.*\{.*\}.*/
304304

305305
let intentUtterances = []
306306
if (intentName && intentName !== '') {
307307
const specificSections = intentSections.filter(s => s.Name === intentName)
308308
if (specificSections.length > 0) {
309-
intentUtterances = intentUtterances.concat(specificSections[0].UtteranceAndEntitiesMap.map(u => u.utterance).filter(i => curlyRe.exec(i) === null))
309+
intentUtterances = intentUtterances.concat(specificSections[0].UtteranceAndEntitiesMap.map(u => u.utterance))
310310
}
311311
} else {
312312
intentSections.forEach(s => {
313313
if (s.SectionType === LUSectionTypes.SIMPLEINTENTSECTION) {
314-
intentUtterances = intentUtterances.concat(s.UtteranceAndEntitiesMap.map(u => u.utterance).filter(i => curlyRe.exec(i) === null))
314+
intentUtterances = intentUtterances.concat(s.UtteranceAndEntitiesMap.map(u => u.utterance))
315315
} else {
316316
s.SimpleIntentSections.forEach(section => {
317-
intentUtterances = intentUtterances.concat(section.UtteranceAndEntitiesMap.map(u => u.utterance).filter(i => curlyRe.exec(i) === null))
317+
intentUtterances = intentUtterances.concat(section.UtteranceAndEntitiesMap.map(u => u.utterance))
318318
})
319319
}
320320
})}
@@ -397,7 +397,7 @@ const qnaCrossTrainCore = function (luResource, qnaResource, fileName, interrupt
397397
}
398398

399399
// construct questions content
400-
dedupedQuestions = dedupedQuestions.map(q => '- '.concat(q))
400+
dedupedQuestions = dedupedQuestions.map(q => '- '.concat(q)).filter(i => !patternWithPrebuiltEntity(i))
401401
let questionsContent = dedupedQuestions.join(NEWLINE)
402402

403403
// cross training comments
@@ -440,8 +440,11 @@ const qnaCrossTrainCore = function (luResource, qnaResource, fileName, interrupt
440440
trainedQnaResource = new SectionOperator(new LUResource([], modelInforContent, [])).addSection(qnaContents)
441441
}
442442

443+
// remove utterances with curly brackets
444+
const utterancesWithoutPatterns = utterances.filter(i => /{([^}]+)}/g.exec(i) === null)
445+
443446
// remove utterances which are duplicated with local qna questions
444-
const dedupedUtterances = utterances.filter(u => !questions.includes(u))
447+
const dedupedUtterances = utterancesWithoutPatterns.filter(u => !questions.includes(u))
445448

446449
// construct new question content for qna resource
447450
let utterancesContent = dedupedUtterances.join(NEWLINE + '- ')
@@ -494,4 +497,23 @@ const pretreatment = function (luContents, qnaContents) {
494497
const qnaObjectArray = fileHelper.getParsedObjects(qnaContents)
495498

496499
return {luObjectArray, qnaObjectArray}
500+
}
501+
502+
const patternWithPrebuiltEntity = function (utterance) {
503+
let patternAnyEntity
504+
let matchedEntity = /{([^}]+)}/g.exec(utterance)
505+
506+
if (matchedEntity !== null) {
507+
patternAnyEntity = matchedEntity[1]
508+
509+
if (patternAnyEntity && patternAnyEntity.startsWith('@')) {
510+
patternAnyEntity = patternAnyEntity.slice(1)
511+
}
512+
513+
if (prebuiltEntityTypes.includes(patternAnyEntity)) {
514+
return true
515+
}
516+
}
517+
518+
return false
497519
}

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

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -541,4 +541,96 @@ describe('luis:cross training tests among lu and qna contents', () => {
541541
assert.equal(luResult.get('./dia2/dia2.lu').Sections[1].Name, '_Interruption')
542542
assert.equal(luResult.get('./dia2/dia2.lu').Sections[1].Body, `- I want to travel to Seattle${NEWLINE}- book a hotel for me`)
543543
})
544+
545+
it('luis:cross training can get expected result when handling patterns', () => {
546+
let luContentArray = []
547+
let qnaContentArray = []
548+
549+
luContentArray.push({
550+
content:
551+
`# dia1_trigger
552+
- book a hotel for me
553+
- book a hotel for {personName}
554+
- book a hotel for {name}
555+
556+
# dia2_trigger
557+
- book a flight for me
558+
- book a train ticket for me`,
559+
id: 'main.lu'})
560+
561+
qnaContentArray.push({
562+
content:
563+
`# ?user guide
564+
565+
**Filters:**
566+
- aa=bb
567+
568+
\`\`\`
569+
Here is the [user guide](http://contoso.com/userguide.pdf)
570+
\`\`\`
571+
572+
# ?tell joke
573+
\`\`\`
574+
tell a funny joke
575+
\`\`\``,
576+
id: 'main.qna'}
577+
)
578+
579+
luContentArray.push({
580+
content:
581+
`> !# @app.name = my luis application
582+
583+
# hotelLevel
584+
- I need a four star hotel
585+
586+
# hotelLocation
587+
- can I book a hotel near space needle`,
588+
id: 'dia1.lu'}
589+
)
590+
591+
luContentArray.push({
592+
content:
593+
`# dia3_trigger
594+
- book a flight from {fromLocation = Seattle} to {toLocation = Beijing}
595+
596+
# dia4_trigger
597+
- book a train ticket from Seattle to Portland`,
598+
id: 'dia2.lu'}
599+
)
600+
601+
let crossTrainConfig = {
602+
rootIds: [
603+
'main.lu'
604+
],
605+
triggerRules: {
606+
'main.lu': {
607+
'dia1_trigger': 'dia1.lu',
608+
'dia2_trigger': 'dia2.lu'
609+
}
610+
},
611+
intentName: '_Interruption',
612+
verbose: true
613+
}
614+
615+
const trainedResult = crossTrainer.crossTrain(luContentArray, qnaContentArray, crossTrainConfig)
616+
const luResult = trainedResult.luResult
617+
const qnaResult = trainedResult.qnaResult
618+
619+
assert.equal(luResult.get('main.lu').Sections[2].Name, 'DeferToRecognizer_QnA_main')
620+
assert.equal(luResult.get('main.lu').Sections[2].Body, `- user guide${NEWLINE}- tell joke`)
621+
622+
assert.equal(qnaResult.get('main.qna').Sections[2].Answer, 'intent=DeferToRecognizer_LUIS_main')
623+
assert.equal(qnaResult.get('main.qna').Sections[2].FilterPairs[0].key, 'dialogName')
624+
assert.equal(qnaResult.get('main.qna').Sections[2].FilterPairs[0].value, 'main')
625+
assert.equal(qnaResult.get('main.qna').Sections[2].Questions.length, 3)
626+
assert.equal(qnaResult.get('main.qna').Sections[2].Questions[0], 'book a hotel for me')
627+
assert.equal(qnaResult.get('main.qna').Sections[2].Questions[1], 'book a flight for me')
628+
assert.equal(qnaResult.get('main.qna').Sections[2].Questions[2], 'book a train ticket for me')
629+
630+
assert.equal(luResult.get('dia1.lu').Sections[3].Name, '_Interruption')
631+
assert.equal(luResult.get('dia1.lu').Sections[3].Body, `- book a flight for me${NEWLINE}- book a train ticket for me${NEWLINE}- user guide${NEWLINE}- tell joke`)
632+
633+
assert.equal(luResult.get('dia2.lu').Sections[2].Name, '_Interruption')
634+
assert.equal(luResult.get('dia2.lu').Sections[2].Body, `- book a hotel for me${NEWLINE}- book a hotel for {name}${NEWLINE}- user guide${NEWLINE}- tell joke`)
635+
})
544636
})

0 commit comments

Comments
 (0)