async build()

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
  }