Skip to content
This repository was archived by the owner on Jan 15, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion packages/lu/src/parser/cross-train/crossTrainer.js
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,7 @@ const qnaCrossTrainCore = function (luResource, qnaResource, fileName, interrupt
let subDedupedUtterances = dedupedUtterances.splice(0, MAX_QUESTIONS_PER_ANSWER)
// construct new question content for qna resource
let utterancesContent = subDedupedUtterances.join(NEWLINE + '- ')
let utterancesToQuestion = `${NEWLINE}${crossTrainingComments}${NEWLINE}# ? ${utterancesContent}${NEWLINE}${NEWLINE}**Filters:**${NEWLINE}- dialogName=${fileName}${NEWLINE}${NEWLINE}\`\`\`${NEWLINE}intent=DeferToRecognizer_LUIS_${fileName}${NEWLINE}\`\`\``
let utterancesToQuestion = `${NEWLINE}${crossTrainingComments}${NEWLINE}> !# @qna.pair.source = crosstrained${NEWLINE}${NEWLINE}# ? ${utterancesContent}${NEWLINE}${NEWLINE}**Filters:**${NEWLINE}- dialogName=${fileName}${NEWLINE}${NEWLINE}\`\`\`${NEWLINE}intent=DeferToRecognizer_LUIS_${fileName}${NEWLINE}\`\`\``
trainedQnaResource = new SectionOperator(trainedQnaResource).addSection(utterancesToQuestion)
}

Expand Down
2 changes: 1 addition & 1 deletion packages/lu/src/parser/qna/qnamaker/kbCollate.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ const resolveMultiTurnReferences = function(qnaList) {
let qnaId = qnaList.find(x => x.id === prompt.qnaId || x.id === parseInt(prompt.qnaId));
if (!qnaId) {
// find by question match
qnaId = qnaList.find(x => x.questions.includes(prompt.qnaId) || x.questions.includes(prompt.qnaId.replace(/-/g, ' ').trim()))
qnaId = qnaList.find(x => x.source.trim() !== 'crosstrained' && (x.questions.includes(prompt.qnaId) || x.questions.includes(prompt.qnaId.replace(/-/g, ' ').trim())))
}
if (qnaId === undefined) {
throw (new exception(retCode.INVALID_INPUT, `[ERROR]: Cannot find follow up prompt definition for '- [${prompt.displayText}](#?${prompt.qnaId}).`));
Expand Down
47 changes: 26 additions & 21 deletions packages/lu/src/parser/qnabuild/builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ const qnaMakerBuilder = require('./../qna/qnamaker/qnaMakerBuilder')
const qnaOptions = require('./../lu/qnaOptions')
const Content = require('./../lu/qna')
const KB = require('./../qna/qnamaker/kb')
const NEWLINE = require('os').EOL
const recognizerType = require('./../utils/enums/recognizertypes')

export class Builder {
Expand All @@ -40,7 +39,8 @@ export class Builder {
let multiRecognizer: any
let settings: any
let recognizers = new Map<string, Recognizer>()
let qnaContents = new Map<string, string>()
let qnaContents = new Map<string, any>()
let qnaObjects = new Map<string, any[]>()

for (const file of files) {
let fileCulture: string
Expand All @@ -51,22 +51,7 @@ export class Builder {
fileCulture = culture
}

let fileContent = ''
let result
const qnaFiles = await fileHelper.getLuObjects(undefined, file, true, fileExtEnum.QnAFile)
try {
result = await qnaBuilderVerbose.build(qnaFiles, true)

// construct qna content without file and url references
fileContent = result.parseToQnAContent()
} catch (err) {
if (err.source) {
err.text = `Invalid QnA file ${err.source}: ${err.text}`
} else {
err.text = `Invalid QnA file ${file}: ${err.text}`
}
throw (new exception(retCode.errorCode.INVALID_INPUT_FILE, err.text))
}

this.handler(`${file} loaded\n`)

Expand Down Expand Up @@ -96,7 +81,7 @@ export class Builder {
settings = new Settings(settingsPath, settingsContent)
}

const content = new Content(fileContent, new qnaOptions(botName, true, fileCulture, file))
const content = new Content('', new qnaOptions(botName, true, fileCulture, file))

if (!recognizers.has(content.name)) {
const dialogFile = path.join(fileFolder, `${content.name}.dialog`)
Expand All @@ -113,14 +98,15 @@ export class Builder {
let recognizer = Recognizer.load(content.path, content.name, dialogFile, settings, existingDialogObj, schema)
recognizers.set(content.name, recognizer)
qnaContents.set(content.name, content)
qnaObjects.set(content.name, qnaFiles)
} else {
// merge contents of qna files with same name
let existingContent: any = qnaContents.get(content.name)
existingContent.content = `${existingContent.content}${NEWLINE}${NEWLINE}${content.content}`
qnaContents.set(content.name, existingContent)
qnaObjects.get(content.name)?.push(...qnaFiles)
}
}

await this.resolveMergedQnAContentIds(qnaContents, qnaObjects)

return {qnaContents: [...qnaContents.values()], recognizers, multiRecognizer, settings}
}

Expand Down Expand Up @@ -515,4 +501,23 @@ export class Builder {
}
}
}

async resolveMergedQnAContentIds(contents: Map<string, any>, objects: Map<string, any[]>) {
for (const [name, content] of contents) {
let qnaObjects = objects.get(name)
try {
let result = await qnaBuilderVerbose.build(qnaObjects, true)
let mergedContent = result.parseToQnAContent()
content.content = mergedContent
contents.set(name, content)
} catch (err) {
if (err.source) {
err.text = `Invalid QnA file ${err.source}: ${err.text}`
} else {
err.text = `Invalid QnA file ${content.path}: ${err.text}`
}
throw (new exception(retCode.errorCode.INVALID_INPUT_FILE, err.text))
}
}
}
}
34 changes: 34 additions & 0 deletions packages/lu/test/parser/qna/qnaMakerBuilder.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const QnAMakerBuilder = require('./../../../src/parser/qna/qnamaker/qnaMakerBuilder')
const QnA = require('./../../../src/parser/lu/qna')
const qnaOptions = require('./../../../src/parser/lu/qnaOptions')
var chai = require('chai');
var assert = chai.assert;

Expand All @@ -25,4 +26,37 @@ describe('QnAMakerBuilder', function() {
assert.equal(qnaMakerObject.kb.name, 'my test kb');
});

it('Build QnaMaker app from multiple instances that have prompts', async () => {
let qnaContent1 =
`> !# @qna.pair.source = crosstrained
# ? hi
\`\`\`markdown
hi from crosstrained
\`\`\``;

let qnaContent2 =
`# ? greeting
\`\`\`markdown
how to greeting
\`\`\`

**Prompts:**
- [hi greeting](#hi)`;

let qnaContent3 =
`# ? hi
\`\`\`markdown
say hi
\`\`\``;
const qna1 = new QnA(qnaContent1, new qnaOptions())
const qna2 = new QnA(qnaContent2, new qnaOptions())
const qna3 = new QnA(qnaContent3, new qnaOptions())
const qnaMakerObject = await QnAMakerBuilder.fromQna([qna1, qna2, qna3])

assert.equal(qnaMakerObject.kb.qnaList[0].id, 2);
assert.equal(qnaMakerObject.kb.qnaList[1].id, 3);
assert.equal(qnaMakerObject.kb.qnaList[2].id, 1);
assert.equal(qnaMakerObject.kb.qnaList[1].context.prompts[0].qnaId, 1);
});

});
2 changes: 2 additions & 0 deletions packages/luis/test/fixtures/verified/interruption/Main.qna
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ I can help book flight, book hotel and book train ticket
```

> Source: cross training. Please do not edit these directly!
> !# @qna.pair.source = crosstrained

# ? book a hotel for me
- book a flight for me
- book a train ticket for me
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ ha ha ha
```

> Source: cross training. Please do not edit these directly!
> !# @qna.pair.source = crosstrained

# ? 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
Expand Down
2 changes: 2 additions & 0 deletions packages/luis/test/fixtures/verified/interruption/dia1.qna
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ I can help book flight, book hotel and book train ticket
```

> Source: cross training. Please do not edit these directly!
> !# @qna.pair.source = crosstrained

# ? I need a four star hotel
- book a flight for me
- book a train ticket for me
Expand Down
2 changes: 2 additions & 0 deletions packages/luis/test/fixtures/verified/interruption/dia2.qna
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ ha ha ha
```

> Source: cross training. Please do not edit these directly!
> !# @qna.pair.source = crosstrained

# ? book a flight from Seattle to Beijing
- book a train ticket from Seattle to Portland
- book a hotel for me
Expand Down
2 changes: 2 additions & 0 deletions packages/luis/test/fixtures/verified/interruption/dia3.qna
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@

> Source: cross training. Please do not edit these directly!
> !# @qna.pair.source = crosstrained

# ? book a flight to Beijing
- book a train ticket from Seattle to Portland
- book a hotel for me
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ Voici le [guide de l'utilisateur] (http://contoso.com/userguide.pdf)
```

> Source: cross training. Please do not edit these directly!
> !# @qna.pair.source = crosstrained

# ? réserver un hôtel

**Filters:**
Expand Down
4 changes: 4 additions & 0 deletions packages/luis/test/fixtures/verified/interruption5/dia1.qna
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ ha ha ha
```

> Source: cross training. Please do not edit these directly!
> !# @qna.pair.source = crosstrained

# ? can I book a hotel near space needle
- user guide
- Can I add multiple items?
Expand Down Expand Up @@ -1017,6 +1019,8 @@ intent=DeferToRecognizer_LUIS_dia1
```

> Source: cross training. Please do not edit these directly!
> !# @qna.pair.source = crosstrained

# ? Feeling chipper?
- Somebody's cheerful.
- Feeling cheerful?
Expand Down
2 changes: 2 additions & 0 deletions packages/luis/test/fixtures/verified/interruption5/main.qna
Original file line number Diff line number Diff line change
Expand Up @@ -1038,6 +1038,8 @@ Thank you
```

> Source: cross training. Please do not edit these directly!
> !# @qna.pair.source = crosstrained

# ? book a hotel for me

**Filters:**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ ha ha ha
```

> Source: cross training. Please do not edit these directly!
> !# @qna.pair.source = crosstrained

# ? 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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ I can book flight for you
```

> Source: cross training. Please do not edit these directly!
> !# @qna.pair.source = crosstrained

# ? I need a four star hotel
- book a flight for me
- book a train ticket for me
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ ha ha ha
```

> Source: cross training. Please do not edit these directly!
> !# @qna.pair.source = crosstrained

# ? book a flight from Seattle to Beijing
- book a train ticket from Seattle to Portland
- book a hotel for me
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@

> Source: cross training. Please do not edit these directly!
> !# @qna.pair.source = crosstrained

# ? book a flight to Beijing
- book a train ticket from Seattle to Portland
- book a hotel for me
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ Voici le [guide de l'utilisateur] (http://contoso.com/userguide.pdf)
```

> Source: cross training. Please do not edit these directly!
> !# @qna.pair.source = crosstrained

# ? réserver un hôtel

**Filters:**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ Tell a funny joke
```

> Source: cross training. Please do not edit these directly!
> !# @qna.pair.source = crosstrained

# ? book a hotel for me
- book a flight for me
- book a train ticket for me
Expand Down