Name

global.NLUModel

Description

All methods related to NLU Models.

Script

var NLUModel = Class.create();

(function() {

  var constants = NLUConstants.constants;
  var tables = NLUConstants.tables;
  var stateTypes = NLUConstants.MODEL_STATE_TYPES;
  var primaryField = NLUImportUtil.FIELDS_DATA[tables.SYS_NLU_MODEL].primaryField;

  NLUModel.isInCloning = function(modelId) {
      var statusGr = NLUModel.getModelStatusGr(modelId);
      if (statusGr) {
          var modelState = statusGr.getValue('state');
          if (modelState === stateTypes.cloning) {
              return true;
          }
      }
      return false;
  };

  NLUModel.isInCloneOrTranslation = function(modelId) {
      var statusGr = NLUModel.getModelStatusGr(modelId);
      if (statusGr) {
          var modelState = statusGr.getValue('state');
          if (modelState === stateTypes.cloning || modelState === stateTypes.translating) {
              return true;
          }
      }
      return false;
  };

  NLUModel.deleteModel = function(modelId) {
      var gr = new GlideRecord(tables.SYS_NLU_MODEL);
      gr.addQuery('sys_id', modelId);
      gr.query();
      if (gr.next())
          gr.deleteRecord();
  };

  NLUModel.getModelsGr = function(modelId, languages) {
      var gr = new GlideRecord(tables.SYS_NLU_MODEL);
      var query = 'sys_id=' + modelId;
      if (!NLUHelper.isEmpty(languages)) {
          query += '^ORprimary_model.sys_id=' + modelId + '^languageIN' + languages.join(',');
          if (languages.indexOf('en') !== -1) query += '^ORlanguageISEMPTY';
      }
      gr.addEncodedQuery(query);
      gr.query();
      return gr;
  };

  NLUModel.getModelStatusGr = function(modelId) {
      var gr = new GlideRecord(tables.SYS_NLU_MODEL_STATUS);
      return gr.get('model', modelId) && gr;
  };

  NLUModel.getGRByName = function(modelNames) {
      var gr = new GlideRecord(tables.SYS_NLU_MODEL);
      gr.addQuery('name', 'IN', modelNames);
      gr.query();
      if (gr.next())
          return gr;
      return null;
  };

  NLUModel.getGRById = function(modelId) {
      var gr = new GlideRecord(tables.SYS_NLU_MODEL);
      if (gr.get(modelId)) return gr;

      return null;
  };

  NLUModel.getByScope = function(sysScope, filter) {
      var gr = new GlideRecord(tables.SYS_NLU_MODEL);
      gr.addQuery('sys_scope', sysScope);
      if (filter) gr.addEncodedQuery(filter);
      gr.query();

      return gr;
  };

  NLUModel.getReferenceTableKey = function(tableName) {
      switch (tableName) {
          case tables.SYS_NLU_MODEL:
              return 'sys_id';
          case tables.SYS_NLU_UTTERANCE:
          case tables.M2M_SYS_NLU_INTENT_ENTITY:
              return 'intent.model';
          case tables.M2M_SYS_NLU_UTTERANCE_ENTITY:
              return 'utterance.intent.model';
          default:
              return 'model';
      }
  };

  NLUModel.getLastUpdatedOn = function(modelId) {
      var modelTables = [tables.SYS_NLU_MODEL, tables.SYS_NLU_INTENT, tables.SYS_NLU_ENTITY, tables.SYS_NLU_VOCABULARY, tables.SYS_NLU_UTTERANCE, tables.M2M_SYS_NLU_UTTERANCE_ENTITY, tables.M2M_SYS_NLU_MODEL_SYS_ENTITY];
      var overallUpdatedOn = null;
      modelTables.forEach(function(eachTable) {
          var key = NLUModel.getReferenceTableKey(eachTable);
          var modelUpdatedOn = NLUSystemUtil.getLastUpdatedOn(eachTable, key + '=' + modelId);
          gs.info("NLUModel.getLastUpdatedOn: " + eachTable + " (" + key + "=" + modelId + ") " + modelUpdatedOn);
          overallUpdatedOn = NLUHelper.getLatestDate(overallUpdatedOn, modelUpdatedOn);
      });
      return overallUpdatedOn;
  };

  NLUModel.isAssignedToMe = function(modelId) {
      if (!modelId) return false;
      var modelStatusGr = NLUModel.getModelStatusGr(modelId);
      if (modelStatusGr) {
          var userIds = modelStatusGr.getValue('author') || '';
          userIds = userIds.split(',');
          var loggedInUser = gs.getUserID();
          return userIds.indexOf(loggedInUser) != -1;
      }
      return false;
  };

  NLUModel.updateModelStatus = function(modelId, state) {
      return NLUSystemUtil.updateOrInsert(tables.SYS_NLU_MODEL_STATUS,
          'model', modelId, {
              'state': state
          });
  };

  NLUModel.updateSecondaryModelStatus = function(modelId, langSysId, status) {
      var langCode = NLUSystemUtil.getLanguageCode(langSysId);
      if (langCode) {
          var nluModel = new NLUModel(modelId);
          var secModelGr = nluModel.getTranslatedModels(langCode);
          if (secModelGr.next()) {
              return NLUModel.updateModelStatus(secModelGr.getUniqueValue(), status);
          }
      }
      return null;
  };

  NLUModel.deriveModelStatus = function(modelId) {
      var gr = NLUModel.getModelStatusGr(modelId);
      if (gr) {
          var updatedOn = gr.getValue('model_updated_on');
          var trainedOn = gr.getValue('last_trained_on');
          var publishedOn = gr.getValue('last_published_on');
          updatedOn = updatedOn ? updatedOn.getNumericValue() : 0;
          trainedOn = trainedOn ? trainedOn.getNumericValue() : 0;
          publishedOn = publishedOn ? publishedOn.getNumericValue() : 0;
          var newState = stateTypes.draft;
          if (trainedOn > publishedOn) {
              newState = stateTypes.trained;
          } else if (publishedOn !== 0) {
              newState = stateTypes.published;
          }
          if (gr.getValue('state') !== newState) {
              gr.setValue('state', newState);
              gr.update();
          }
      }
  };

  NLUModel.getLanguage = function(modelGr) {
      return modelGr.getValue('language') || constants.MODEL_DEFAULT_LANG;
  };

  NLUModel.prototype = {

      type: 'NLUModel',

      initialize: function(modelId, modelGr) {
          this.modelId = modelId;
          this.modelGr = modelGr;
      },

      createIntent: function(name) {
          if (!name || name.length === 0) throw new Error(gs.getMessage("Please provide a valid intent name"));
          if (name.length > 100) throw new Error(gs.getMessage("Intent name cannot be more than 100 characters"));
          if (this.getPolicy() === 'read') throw new Error(gs.getMessage('Intent cannot be added to read only model {0}', this.getModelDisplayName()));
          var intentGr = this.getIntents('name=' + name);
          if (intentGr.next()) throw new Error(gs.getMessage('Intent with same name already exists'));
          var gr = new GlideRecord(tables.SYS_NLU_INTENT);
          gr.initialize();
          gr.name = name;
          gr.model = this.modelId;
          return gr.insert();
      },

      getGR: function() {
          if (!this.modelGr) this.modelGr = NLUModel.getGRById(this.modelId);
          return this.modelGr;
      },

      getScope: function() {
          if (!this.modelGr) this.getGR();
          return this.modelGr.getValue('sys_scope');
      },

      getModelDisplayName: function() {
          return this.getGR().getValue('display_name');
      },

      getPolicy: function() {
          return this.getGR().getValue('sys_policy');
      },

      getVersion: function() {
          if (!this.parloIntegrator) this.parloIntegrator = new NLUParloIntegrator(this.getGR());
          return this.parloIntegrator.getModelVersion();
      },

      getStatus: function() {
          return NLUModel.getModelStatusGr(this.modelId);
      },

      syncStatus: function() {
          var lastPublishedOrTrained, statusGr, modelUpdatedOn, dirty;
          var data = {
              state: 'draft'
          };

          if (!this.parloIntegrator) this.parloIntegrator = new NLUParloIntegrator(this.getGR());
          var result = this.parloIntegrator.getModelStatus();
          if (result && result.status === 'success') {
              data = {
                  trained_version: result.trainedVersion,
                  published_version: result.publishedVersion
              };
              if (result.lastPublishedOn) {
                  data['last_published_on'] = result.lastPublishedOn;
                  lastPublishedOrTrained = new GlideDateTime(result.lastPublishedOn);
              }
              if (result.lastTrainedOn) {
                  data['last_trained_on'] = result.lastTrainedOn;
                  lastPublishedOrTrained = NLUHelper.getLatestDate(lastPublishedOrTrained, new GlideDateTime(result.lastTrainedOn));
              }
              statusGr = this.getStatus();
              var oldState = statusGr && statusGr.getValue('state');
              var newState = result.state;
              if (!statusGr) {
                  // In case, the model_status does not exists:
                  modelUpdatedOn = NLUModel.getLastUpdatedOn(this.modelId);
                  data['model_updated_on'] = modelUpdatedOn;
              } else {
                  if (oldState === stateTypes.training || newState === stateTypes.trained || newState === stateTypes.published) {
                      modelUpdatedOn = new GlideDateTime(statusGr.getValue('model_updated_on'));
                  }
              }
              if (modelUpdatedOn) {
                  dirty = !lastPublishedOrTrained || (modelUpdatedOn.getNumericValue() > lastPublishedOrTrained.getNumericValue());
                  data['dirty'] = dirty;
              }

              if ([stateTypes.training, stateTypes.trained, stateTypes.published, stateTypes.draft].indexOf(oldState) !== -1) {
                  data.state = result.state;
              }
          }
          this.updateStatus(data);
          return result;
      },

      getPublishedTimestamp: function() {
          var modelStatus = this.syncStatus();
          return !gs.nil(modelStatus) && !gs.nil(modelStatus.lastPublishedOn) ?
              new GlideDateTime(modelStatus.lastPublishedOn).getValue() : null;
      },

      getLastTrainedTimestamp: function() {
          var modelStatus = this.syncStatus();
          return !gs.nil(modelStatus) && !gs.nil(modelStatus.lastTrainedOn) ?
              new GlideDateTime(modelStatus.lastTrainedOn).getValue() : null;
      },

      getIntents: function(filter) {
          var gr = new GlideRecord(tables.SYS_NLU_INTENT);
          gr.addQuery('model', this.modelId);
          if (filter) gr.addEncodedQuery(filter);
          gr.query();

          return gr;
      },

      getIntentIds: function(filter) {
          var intentIds = [];
          var gr = new GlideRecord(tables.SYS_NLU_INTENT);
          gr.addQuery('model', this.modelId);
          if (filter) gr.addEncodedQuery(filter);
          gr.query();
          while (gr.next()) {
              intentIds.push(gr.getUniqueValue());
          }
          return intentIds;
      },

      getUtterances: function(filter) {
          var gr = new GlideRecord(tables.SYS_NLU_UTTERANCE);
          gr.addQuery('intent.model', this.modelId);
          if (filter) gr.addEncodedQuery(filter);
          gr.query();

          return gr;
      },

      getEntities: function(filter, enabled) {
          var gr = new GlideRecord(tables.SYS_NLU_ENTITY);
          var joinQuery = gr.addJoinQuery(tables.M2M_SYS_NLU_INTENT_ENTITY, 'sys_id', 'entity');
          if (enabled) {
              joinQuery.addCondition('intent.enable', true).addOrCondition('intent.enable', 'NULL');
          }
          joinQuery.addCondition('intent.model', this.modelId);
          gr.addEncodedQuery('^NQmodel=' + this.modelId);
          if (filter) gr.addEncodedQuery(filter);
          gr.query();

          return gr;
      },

      getModelEntities: function(filter) {
          var gr = new GlideRecord(tables.SYS_NLU_ENTITY);
          gr.addQuery('model', this.modelId);
          if (filter) gr.addEncodedQuery(filter);
          gr.query();

          return gr;
      },

      getSystemEntities: function() {
          var gr = new GlideRecord(tables.M2M_SYS_NLU_MODEL_SYS_ENTITY);
          gr.addQuery('model', this.modelId);
          gr.addQuery('active', true);
          gr.query();

          var sysEntities = [];
          while (gr.next()) {
              var entity = gr.getValue('entity');
              if (gs.nil(entity)) entity = gr.sys_entity.getRefRecord().getValue('name');
              sysEntities.push({
                  id: gr.getUniqueValue(),
                  name: entity,
                  createdOnTimestamp: global.NLUHelper.toTimezoneAdjustedTimestamp(
                      new GlideDateTime(gr.getValue('sys_created_on'))),
              });
          }
          return sysEntities;
      },

      getVocabulary: function(filter) {
          var gr = new GlideRecord(tables.SYS_NLU_VOCABULARY);
          gr.addQuery('model', this.modelId);
          if (filter) gr.addEncodedQuery(filter);
          gr.query();

          return gr;
      },

      getDefaultTestsetGR: function(filter) {
          var gr = new GlideRecord(tables.BATCH_TEST_SET);
          gr.addQuery('model', this.modelId);
          if (filter) gr.addEncodedQuery(filter);
          gr.query();

          return gr;
      },

      getDefaultTestsetUtterancesGR: function(filter) {
          gr = new GlideRecord(tables.BATCH_TEST_SET_UTTERANCES);
          gr.addEncodedQuery('test_set.model=' + this.modelId);
          if (filter) gr.addEncodedQuery(filter);
          gr.query();

          return gr;
      },

      getLookupIds: function() {
          var lookupIds = [];
          var lookupGr = new GlideRecord(tables.SYS_NLU_VOCABULARY);
          lookupGr.addEncodedQuery('type=lookup^ORtype=static_lookup');
          lookupGr.query();
          var queryCondition = "utteranceLIKEjavascript:' @{0} '^ORutteranceSTARTSWITHjavascript:'@{0} '^ORutteranceENDSWITHjavascript:' @{0}'^ORutterance=javascript:'@{0}'";
          while (lookupGr.next()) {
              var utteranceGr = this.getUtterances(queryCondition.replaceAll("{0}", lookupGr.getValue('name')));
              if (utteranceGr.next() || this.getEntities('lookup=' + lookupGr.getUniqueValue() + '^type=list').next()) {
                  lookupIds.push(lookupGr.getUniqueValue());
              }
          }
          return lookupIds;
      },

      getLookups: function() {
          var gr = new GlideRecord(tables.SYS_NLU_VOCABULARY);
          gr.addQuery('sys_id', 'IN', this.getLookupIds());
          gr.query();
          return gr;
      },

      getState: function() {
          var result = this.syncStatus();
          switch (result.state) {
              case 'trained':
                  return gs.getMessage('Trained');
              case 'published':
                  return gs.getMessage('Published');
              default:
                  return gs.getMessage('Draft');
          }
      },

      updateStatus: function(data) {
          NLUSystemUtil.updateOrInsert(tables.SYS_NLU_MODEL_STATUS,
              'model', this.modelId, data);
      },

      setDirty: function() {
          this.updateStatus({
              dirty: true,
              model_updated_on: (new GlideDateTime())
          });
      },

      enableSysEntity: function(entity) {
          var entityRec = new GlideRecord(tables.M2M_SYS_NLU_MODEL_SYS_ENTITY);
          entityRec.setValue('model', this.modelId);
          entityRec.setValue('entity', entity);
          entityRec.setValue('active', true);
          return entityRec.insert();
      },

      getTranslatedModels: function(language) {
          var gr = new GlideRecord(tables.SYS_NLU_MODEL);
          gr.addQuery(primaryField, this.modelId);
          if (language) gr.addQuery('language', language);
          gr.query();
          return gr;
      },
  };

})();

Sys ID

4f4538b207011010220b0a701ad30036

Offical Documentation

Official Docs: