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

Commit 69d89b2

Browse files
authored
Adjust cross-train to use id as key-value instead of path in config (#1030)
* adjust cross-train to use id as config kv instead of path * remove configId
1 parent 4d90f4e commit 69d89b2

File tree

16 files changed

+339
-323
lines changed

16 files changed

+339
-323
lines changed

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

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
* Licensed under the MIT License.
44
*/
55

6-
const fs = require('fs-extra')
76
const path = require('path')
87
const file = require('../../utils/filehelper')
98
const fileExtEnum = require('../utils/helpers').FileExtTypeEnum
@@ -24,13 +23,37 @@ module.exports = {
2423
const qnaContents = await file.getFilesContent(input, fileExtEnum.QnAFile)
2524
const configContent = await file.getConfigContent(config)
2625

26+
let importResolver = async function (_, idsToFind) {
27+
let importedContents = []
28+
for (let idx = 0; idx < idsToFind.length; idx++) {
29+
let file = idsToFind[idx]
30+
if (path.isAbsolute(file.filePath)) {
31+
if (file.filePath.endsWith(fileExtEnum.LUFile)) {
32+
importedContents.push(...await file.getFilesContent(file.filePath, fileExtEnum.LUFile))
33+
} else if (file.filePath.endsWith(fileExtEnum.QnAFile)) {
34+
importedContents.push(...await file.getFilesContent(file.filePath, fileExtEnum.QnAFile))
35+
}
36+
} else {
37+
const fileName = path.basename(file.filePath)
38+
if (fileName.endsWith(fileExtEnum.LUFile)) {
39+
importedContents.push(...luContents.filter(luContent => luContent.id === path.basename(fileName, fileExtEnum.LUFile)))
40+
} else if (fileName.endsWith(fileExtEnum.QnAFile)) {
41+
importedContents.push(...qnaContents.filter(qnaContent => qnaContent.id === path.basename(fileName, fileExtEnum.QnAFile)))
42+
}
43+
}
44+
}
45+
46+
return importedContents
47+
}
48+
2749
const trainedResult = await crossTrainer.crossTrain(
2850
luContents,
2951
qnaContents,
3052
JSON.parse(configContent.content), {
3153
configId: configContent.id,
3254
intentName,
33-
verbose
55+
verbose,
56+
importResolver
3457
})
3558

3659
return trainedResult

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

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
* Licensed under the MIT License.
44
*/
55

6-
const helpers = require('../utils/helpers')
76
const fileExtEnum = require('../utils/helpers').FileExtTypeEnum
87
const luParser = require('../lufile/luParser')
98
const SectionOperator = require('../lufile/sectionOperator')
@@ -38,18 +37,17 @@ module.exports = {
3837

3938
const crossTrainConfig = fileHelper.getConfigObject(
4039
configObject,
41-
options.configId,
4240
options.intentName || '_Interruption',
4341
options.verbose || true)
4442

4543
let {luObjectArray, qnaObjectArray} = pretreatment(luContents, qnaContents)
4644
const {rootIds, triggerRules, intentName, verbose} = crossTrainConfig
4745

4846
// parse lu content to LUResource object
49-
let {fileIdToResourceMap: luFileIdToResourceMap, allEmpty: allLuEmpty} = await parseAndValidateContent(luObjectArray, verbose, importResolver)
47+
let {fileIdToResourceMap: luFileIdToResourceMap, allEmpty: allLuEmpty} = await parseAndValidateContent(luObjectArray, verbose, importResolver, fileExtEnum.LUFile)
5048

5149
// parse qna content to LUResource object
52-
let {fileIdToResourceMap: qnaFileIdToResourceMap, allEmpty: allQnAEmpty} = await parseAndValidateContent(qnaObjectArray, verbose, importResolver)
50+
let {fileIdToResourceMap: qnaFileIdToResourceMap, allEmpty: allQnAEmpty} = await parseAndValidateContent(qnaObjectArray, verbose, importResolver, fileExtEnum.QnAFile)
5351

5452
if (!allLuEmpty) {
5553
// construct resource tree to build the father-children relationship among lu files
@@ -181,8 +179,7 @@ const mergeRootInterruptionToLeaves = function (rootResource, result, qnaFileToR
181179
for (const child of rootResource.children) {
182180
let childResource = result.get(child.target)
183181
if (childResource && childResource.visited === undefined) {
184-
let rootQnaFileId = rootResource.id.toLowerCase().replace(new RegExp(helpers.FileExtTypeEnum.LUFile + '$'), helpers.FileExtTypeEnum.QnAFile)
185-
rootQnaFileId = Array.from(qnaFileToResourceMap.keys()).find(x => x.toLowerCase() === rootQnaFileId)
182+
const rootQnaFileId = Array.from(qnaFileToResourceMap.keys()).find(x => x.toLowerCase() === rootResource.id.toLowerCase())
186183
const rootQnaResource = qnaFileToResourceMap.get(rootQnaFileId)
187184
const newChildResource = mergeFatherInterruptionToChild(rootResource, rootQnaResource, childResource, intentName)
188185
result.set(child.target, newChildResource)
@@ -356,12 +353,11 @@ const extractIntentUtterances = function(resource, intentName) {
356353
const qnaCrossTrain = function (qnaFileIdToResourceMap, luFileIdToResourceMap, interruptionIntentName, allLuEmpty) {
357354
try {
358355
for (const qnaObjectId of Array.from(qnaFileIdToResourceMap.keys())) {
359-
let luObjectId = qnaObjectId.toLowerCase().replace(new RegExp(helpers.FileExtTypeEnum.QnAFile + '$'), helpers.FileExtTypeEnum.LUFile)
360356
let fileName = path.basename(qnaObjectId, path.extname(qnaObjectId))
361357
const culture = fileHelper.getCultureFromPath(qnaObjectId)
362358
fileName = culture ? fileName.substring(0, fileName.length - culture.length - 1) : fileName
363359

364-
luObjectId = Array.from(luFileIdToResourceMap.keys()).find(x => x.toLowerCase() === luObjectId)
360+
const luObjectId = Array.from(luFileIdToResourceMap.keys()).find(x => x.toLowerCase() === qnaObjectId.toLowerCase())
365361
if (luObjectId) {
366362
const { luResource, qnaResource } = qnaCrossTrainCore(luFileIdToResourceMap.get(luObjectId), qnaFileIdToResourceMap.get(qnaObjectId), fileName, interruptionIntentName, allLuEmpty)
367363
luFileIdToResourceMap.set(luObjectId, luResource)
@@ -506,16 +502,17 @@ const qnaAddMetaData = function (qnaResource, fileName) {
506502
* @param {luObject[]} objectArray the lu or qna object list to be parsed
507503
* @param {boolean} verbose indicate to enable log messages or not
508504
* @param {any} importResolver import Resolver when resolving import files
505+
* @param {any} fileExt file extension to indicate the file is .lu or .qna format
509506
* @returns {Map<string, LUResource>} map of file id and luResource
510507
* @throws {exception} throws errors
511508
*/
512-
const parseAndValidateContent = async function (objectArray, verbose, importResolver) {
509+
const parseAndValidateContent = async function (objectArray, verbose, importResolver, fileExt) {
513510
let fileIdToResourceMap = new Map()
514511
let allEmpty = true
515512
for (const object of objectArray) {
516513
let fileContent = object.content
517514
if (object.content && object.content !== '') {
518-
if (object.id.toLowerCase().endsWith(fileExtEnum.LUFile)) {
515+
if (fileExt === fileExtEnum.LUFile) {
519516
let result = await LuisBuilderVerbose.build([object], verbose, undefined, importResolver)
520517
let luisObj = new Luis(result)
521518
fileContent = luisObj.parseToLuContent()

packages/lu/src/utils/filehelper.ts

Lines changed: 20 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ export async function getFilesContent(input: string, extType: string) {
172172
if (fileStat.isFile()) {
173173
const filePath = path.resolve(input)
174174
const content = await getContentFromFile(input)
175-
return [{id: filePath, content}]
175+
return [{id: path.basename(filePath, extType), content}]
176176
}
177177

178178
if (!fileStat.isDirectory()) {
@@ -182,7 +182,7 @@ export async function getFilesContent(input: string, extType: string) {
182182
return Promise.all(paths.map(async (item: string) => {
183183
const itemPath = path.resolve(path.join(input, item))
184184
const content = await getContentFromFile(itemPath)
185-
return {id: itemPath, content}
185+
return {id: path.basename(itemPath, extType), content}
186186
}))
187187
}
188188

@@ -220,37 +220,34 @@ export function getParsedObjects(contents: {id: string, content: string}[]) {
220220
return parsedObjects
221221
}
222222

223-
export function getConfigObject(configObject: any, configId: string, intentName: string, verbose: boolean) {
224-
let finalLuConfigObj = Object.create(null)
225-
let rootLuFiles: string[] = []
226-
const configFileDir = configId && configId !== '' ? path.dirname(configId) : undefined
223+
export function getConfigObject(configObject: any, intentName: string, verbose: boolean) {
224+
let finalConfigObj = Object.create(null)
225+
let rootFileIds: string[] = []
227226
if (configObject) {
228227
try {
229-
for (const rootluFilePath of Object.keys(configObject)) {
230-
const rootLuFileFullPath = configFileDir ? path.resolve(configFileDir, rootluFilePath) : rootluFilePath
231-
const triggerObj = configObject[rootluFilePath]
228+
for (const rootFileId of Object.keys(configObject)) {
229+
const triggerObj = configObject[rootFileId]
232230
for (const triggerObjKey of Object.keys(triggerObj)) {
233231
if (triggerObjKey === 'rootDialog') {
234232
if (triggerObj[triggerObjKey]) {
235-
rootLuFiles.push(rootLuFileFullPath)
233+
rootFileIds.push(rootFileId)
236234
}
237235
} else if (triggerObjKey === 'triggers') {
238236
const triggers = triggerObj[triggerObjKey]
239237
for (const triggerKey of Object.keys(triggers)) {
240-
const destLuFiles = triggers[triggerKey] instanceof Array ? triggers[triggerKey] : [triggers[triggerKey]]
241-
for (const destLuFile of destLuFiles) {
242-
const destLuFileFullPath = configFileDir && destLuFile && destLuFile !== '' ? path.resolve(configFileDir, destLuFile) : destLuFile
243-
if (rootLuFileFullPath in finalLuConfigObj) {
244-
const finalIntentToDestLuFiles = finalLuConfigObj[rootLuFileFullPath]
245-
if (finalIntentToDestLuFiles[triggerKey]) {
246-
finalIntentToDestLuFiles[triggerKey].push(destLuFileFullPath)
238+
const destFileIds = triggers[triggerKey] instanceof Array ? triggers[triggerKey] : [triggers[triggerKey]]
239+
for (const destFileId of destFileIds) {
240+
if (rootFileId in finalConfigObj) {
241+
let finalIntentToDestFileIds = finalConfigObj[rootFileId]
242+
if (finalIntentToDestFileIds[triggerKey]) {
243+
finalIntentToDestFileIds[triggerKey].push(destFileId)
247244
} else {
248-
finalIntentToDestLuFiles[triggerKey] = [destLuFileFullPath]
245+
finalIntentToDestFileIds[triggerKey] = [destFileId]
249246
}
250247
} else {
251-
let finalIntentToDestLuFiles = Object.create(null)
252-
finalIntentToDestLuFiles[triggerKey] = [destLuFileFullPath]
253-
finalLuConfigObj[rootLuFileFullPath] = finalIntentToDestLuFiles
248+
let finalIntentToDestFileIds = Object.create(null)
249+
finalIntentToDestFileIds[triggerKey] = [destFileId]
250+
finalConfigObj[rootFileId] = finalIntentToDestFileIds
254251
}
255252
}
256253
}
@@ -263,8 +260,8 @@ export function getConfigObject(configObject: any, configId: string, intentName:
263260
}
264261

265262
let crossTrainConfig = {
266-
rootIds: rootLuFiles,
267-
triggerRules: finalLuConfigObj,
263+
rootIds: rootFileIds,
264+
triggerRules: finalConfigObj,
268265
intentName,
269266
verbose
270267
}

0 commit comments

Comments
 (0)