in parsers/LU/JS/packages/lu/src/parser/lubuild/builder.ts [154:285]
async build(
luContents: any[],
recognizers: Map<string, Recognizer>,
authoringKey: string,
endpoint: string,
botName: string,
suffix: string,
fallbackLocale: string,
deleteOldVersion: boolean,
isStaging: boolean,
multiRecognizers?: Map<string, MultiLanguageRecognizer>,
settings?: Settings,
crosstrainedRecognizers?: Map<string, CrossTrainedRecognizer>,
dialogType?: string,
luisAPITPS?: number,
timeBucketOfRequests?: number,
retryCount?: number,
retryDuration?: number) {
// luis api TPS which means 5 concurrent transactions to luis api in 1 second
// can set to other value if switched to a higher TPS(transaction per second) key
let luisApiTps = luisAPITPS || 5
// set luis call delay duration to 1100 millisecond because 1000 can hit corner case of rate limit
let timeBucket = timeBucketOfRequests || 1100
// set retry count for rate limit luis API failure
let countForRetry = retryCount || 1
// set retry duration for rate limit luis API failure
let durationForRetry = retryDuration || 1000
//default returned recognizer values
let recognizerValues: Recognizer[] = []
let multiRecognizerValues: MultiLanguageRecognizer[] = []
let settingsValue: any
let crosstrainedRecognizerValues: CrossTrainedRecognizer[] = []
// filter if all lu contents are emtty
let isAllLuEmpty = fileHelper.isAllFilesSectionEmpty(luContents)
if (!isAllLuEmpty) {
const luBuildCore = new LuBuildCore(authoringKey, endpoint, countForRetry, durationForRetry)
const apps = await luBuildCore.getApplicationList()
// here we do a while loop to make full use of luis tps capacity
while (luContents.length > 0) {
// get a number(set by luisApiTps) of contents for each loop
const subLuContents = luContents.splice(0, luisApiTps)
// concurrently handle applications
await Promise.all(subLuContents.map(async content => {
// init current application object from lu content
let currentApp = await this.initApplicationFromLuContent(content, botName, suffix)
// get recognizer
let recognizer = recognizers.get(content.name) as Recognizer
// find if there is a matched name with current app under current authoring key
if (!recognizer.getAppId()) {
for (let app of apps) {
if (app.name === currentApp.name) {
recognizer.setAppId(app.id)
break
}
}
}
let needTrainAndPublish = false
// compare models to update the model if a match found
// otherwise create a new application
if (recognizer.getAppId() && recognizer.getAppId() !== '') {
// To see if need update the model
needTrainAndPublish = await this.updateApplication(currentApp, luBuildCore, recognizer, timeBucket, deleteOldVersion)
} else {
// create a new application
needTrainAndPublish = await this.createApplication(currentApp, luBuildCore, recognizer, timeBucket)
}
if (needTrainAndPublish) {
// train and publish application
await this.trainAndPublishApplication(luBuildCore, recognizer, timeBucket, isStaging)
}
// update multiLanguageRecognizer asset
if (multiRecognizers && multiRecognizers.has(content.id)) {
let multiRecognizer = multiRecognizers.get(content.id) as MultiLanguageRecognizer
multiRecognizer.recognizers[currentApp.culture] = path.basename(recognizer.getDialogPath(), '.dialog')
if (currentApp.culture.toLowerCase() === fallbackLocale.toLowerCase()) {
multiRecognizer.recognizers[''] = path.basename(recognizer.getDialogPath(), '.dialog')
}
}
if (crosstrainedRecognizers && crosstrainedRecognizers.has(content.id)) {
let crosstrainedRecognizer = crosstrainedRecognizers.get(content.id) as CrossTrainedRecognizer
if (!crosstrainedRecognizer.recognizers.includes(content.id + '.lu')) {
crosstrainedRecognizer.recognizers.push(content.id + '.lu')
}
}
// update settings asset
if (settings) {
settings.luis[content.name.split('.').join('_').replace(/-/g, '_')] = recognizer.getAppId()
}
}))
}
// write dialog assets
if (recognizers) {
recognizerValues = Array.from(recognizers.values())
}
if (multiRecognizers) {
multiRecognizerValues = Array.from(multiRecognizers.values())
}
if (settings) {
settingsValue = settings as Settings
}
}
if (dialogType === recognizerType.CROSSTRAINED && crosstrainedRecognizers) {
crosstrainedRecognizerValues = Array.from(crosstrainedRecognizers.values())
}
const dialogContents = this.generateDeclarativeAssets(recognizerValues, multiRecognizerValues, settingsValue, crosstrainedRecognizerValues)
return dialogContents
}