Name
global.NLUStudioService
Description
Single point helper for all the methods which get invoked from the REST
Script
var NLUStudioService = Class.create();
(function() {
var constants = NLUConstants.constants;
var tables = NLUConstants.tables;
var stateTypes = NLUConstants.MODEL_STATE_TYPES;
var STATUS = {
ERROR: 'error',
WARNING: 'warning',
SUCCESS: 'success'
};
var PLAIN_TEXT = 'plain_text';
var HTML = 'html';
var MODEL_TYPE = {
UNGROUPED: 'ungrouped',
PRIMARY: 'primary',
SECONDARY: 'secondary'
};
var PRIMARY_MODEL_FLD = NLUImportUtil.FIELDS_DATA[tables.SYS_NLU_MODEL].primaryField;
var _getMlSolutionGR = function() {
var mlSolutionGr = new GlideRecord(tables.ML_SOLUTION);
mlSolutionGr.addQuery('active', true);
mlSolutionGr.addQuery('capability', 'nlu_trainer');
mlSolutionGr.query();
return mlSolutionGr;
};
var _getPrimaryModel = function(modelName) {
var gr = new GlideRecord(tables.SYS_NLU_MODEL);
if (gr.get('name', modelName))
return gr.getValue(PRIMARY_MODEL_FLD) || gr.getUniqueValue();
return null;
};
var _getPrimaryModelById = function(modelId) {
var gr = new GlideRecord(tables.SYS_NLU_MODEL);
if (gr.get(modelId))
return gr.getValue(PRIMARY_MODEL_FLD) || modelId;
return null;
};
var _getModelType = function(gr) {
var primaryId = gr.getValue(PRIMARY_MODEL_FLD);
if (primaryId) return MODEL_TYPE.SECONDARY;
var priGr = new GlideRecord(tables.SYS_NLU_MODEL);
return priGr.get(PRIMARY_MODEL_FLD, gr.getUniqueValue()) ? MODEL_TYPE.PRIMARY : MODEL_TYPE.UNGROUPED;
};
var _getModelData = function(gr) {
if (gs.nil(gr)) {
return {
id: null
};
}
var modelData = {
id: gr.getUniqueValue(),
name: gr.getValue('name'),
displayName: gr.getValue('display_name'),
language: NLUModel.getLanguage(gr),
scope: gr.getValue('sys_scope'),
type: _getModelType(gr),
category: gr.getValue('category'),
readOnly: gr.getValue('sys_policy') === "read" ? true : false
};
if (gr.getValue(PRIMARY_MODEL_FLD)) {
modelData.primaryId = gr.getValue(PRIMARY_MODEL_FLD);
modelData.primaryName = gr[PRIMARY_MODEL_FLD].name.getValue();
}
var solution = NLUParloIntegrator.getSolution(gr.getValue('name'));
if (solution) {
var modelStatus = NLUParloIntegrator.getStatusFromSolution(solution);
delete modelStatus.status;
NLUHelper.extend(modelData, modelStatus);
}
return modelData;
};
var _getGroupModelData = function(gr) {
var modelsArray = [];
while (gr.next()) {
modelsArray.push(_getModelData(gr));
}
return modelsArray;
};
var _getModelGroupByPrimary = function(primaryModelId) {
if (!primaryModelId) return [];
var gr = new GlideRecord(tables.SYS_NLU_MODEL);
var grOR = gr.addQuery('sys_id', primaryModelId);
grOR.addOrCondition(PRIMARY_MODEL_FLD, primaryModelId);
gr.query();
return _getGroupModelData(gr);
};
/*
publishStatus: [error | warning | success]
publishMessage: {
type: [plain_text | html]
text: <>,
}
*/
var pluginInstalled = GlidePluginManager.isActive('com.snc.nlu.workbench.advanced');
var _publishStatusResp = function(status, messageType, message) {
return {
publishStatus: status,
publishMessage: {
type: messageType,
text: message
}
};
};
var _getMessageWithLink = function(message, link, linkText) {
return '<p>' + message + '</p><br/><a href=\'' + link + '\' target=\'_blank\'/>' + linkText + '</a>';
};
var _getPublishStatus = function(modelData, includeWarnings) {
/*** ERRORS ***/
// Check if model is dirty and needs to be trained
if (modelData.isModelDirty === "1")
return _publishStatusResp(STATUS.ERROR, PLAIN_TEXT, gs.getMessage('Model should be trained'));
// Check if model exists:
if (!modelData || !modelData.id)
return _publishStatusResp(STATUS.ERROR, PLAIN_TEXT, gs.getMessage('Model does not exist.'));
// Role check:
if (!gs.hasRole(constants.NLU_ADMIN_ROLE))
return _publishStatusResp(STATUS.ERROR, PLAIN_TEXT, gs.getMessage('User is not authorized to publish.'));
if (pluginInstalled && includeWarnings) {
var testInfo = sn_nlu_workbench.NLUBatchTestExecution.getReportInfo(modelData.id, false, modelData.trainedVersion);
// If batch testing is in progress
if (testInfo.status === 'inprogress') {
return _publishStatusResp(STATUS.WARNING, PLAIN_TEXT, gs.getMessage('Batch testing for this NLU model is currently in progress. Are you sure you want to publish the topic?'));
}
// Latest text execution was not successful/no batch testing results available
if (!testInfo || !testInfo.executionId) {
return _publishStatusResp(STATUS.WARNING, HTML, _getMessageWithLink(
gs.getMessage('Before publishing, we recommend that you test the model. Testing the model gets you insights into how the model is correctly and incorrectly predicting intents.'),
'nav_to.do?uri=/$nlu-studio.do#/model-overview/' + modelData.id,
gs.getMessage('Test this model in NLU Workbench')
));
}
}
// Model is never trained
if (!modelData.trainedVersion || modelData.trainedVersion <= 0)
return _publishStatusResp(STATUS.ERROR, PLAIN_TEXT, gs.getMessage('The model is never trained.'));
// Last trained model is already published
if (modelData.trainedVersion <= modelData.publishedVersion)
return _publishStatusResp(STATUS.ERROR, PLAIN_TEXT, gs.getMessage('The latest version is already published.'));
// If Training is in progress
if (modelData.status === stateTypes.training)
return _publishStatusResp(STATUS.ERROR, PLAIN_TEXT, gs.getMessage('The model training is in progress.'));
/*** SUCCESS ***/
return _publishStatusResp(STATUS.SUCCESS, PLAIN_TEXT, gs.getMessage('This model can be published'));
};
var _getModelStatusByName = function(modelName, addPublishStatus) {
var modelData = {};
var modelGr = NLUModel.getGRByName(modelName);
if (!gs.nil(modelGr)) {
modelData = _getModelData(modelGr);
var modelStatusGr = NLUModel.getModelStatusGr(modelGr.getUniqueValue());
if (modelStatusGr) {
modelData.lastUpdatedOn = modelStatusGr.getValue('model_updated_on');
} else {
var lastUpdatedOn = NLUModel.getLastUpdatedOn(modelGr.getUniqueValue());
modelData.lastUpdatedOn = lastUpdatedOn && lastUpdatedOn.getValue();
}
}
modelData.isModelDirty = modelStatusGr.getValue('dirty');
if (addPublishStatus) {
NLUHelper.extend(modelData, _getPublishStatus(modelData, true));
}
return modelData;
};
NLUStudioService.publishModels = function(modelNames) {
var result = {};
var modelGr = new GlideRecord(tables.SYS_NLU_MODEL);
modelGr.addQuery('name', 'IN', modelNames);
modelGr.query();
while (modelGr.next()) {
var modelData = _getModelData(modelGr);
var canPublish = _getPublishStatus(modelData, false);
if (canPublish.publishStatus === STATUS.SUCCESS) {
var publishResult = NLUStudioPublisher.publishModel(modelGr.getUniqueValue());
if (publishResult.status === 'success') {
result[modelGr.getValue('name')] = {
publishStatus: STATUS.SUCCESS,
publishedVersion: publishResult.publishedVersion
};
} else {
result[modelGr.getValue('name')] = _publishStatusResp(STATUS.ERROR, PLAIN_TEXT, publishResult.message);
}
} else {
result[modelGr.getValue('name')] = canPublish;
}
}
return result;
};
NLUStudioService.getAllModels = function(category, primary, includeLastUpdated) {
var result = [];
var gr = new GlideRecord(tables.SYS_NLU_MODEL);
if (category) gr.addQuery('category', category);
if (primary) gr.addNullQuery(PRIMARY_MODEL_FLD);
gr.query();
while (gr.next()) {
if (includeLastUpdated) result.push(NLUStudioService.getModelStatusByName(gr.name));
else result.push(_getModelData(gr));
}
return result;
};
NLUStudioService.getModelGroup = function(modelName) {
return _getModelGroupByPrimary(_getPrimaryModel(modelName));
};
NLUStudioService.getModelGroupById = function(modelId) {
return _getModelGroupByPrimary(_getPrimaryModelById(modelId));
};
NLUStudioService.getTrainedModels = function(category, primary) {
var solutionNames;
var aggr = new GlideAggregate(tables.ML_SOLUTION);
aggr.addQuery('capability', 'nlu_trainer');
aggr.addQuery('state', 'solution_complete');
aggr.groupBy('solution_name');
aggr.query();
while (aggr.next()) {
var solName = aggr.getValue('solution_name');
solutionNames = (solutionNames ? solutionNames + ',' : '') + solName + ',' + solName.substring(3);
}
var gr = new GlideRecord(tables.SYS_NLU_MODEL);
gr.addQuery('name', 'IN', solutionNames);
gr.addQuery('category', category);
if (primary) gr.addNullQuery(PRIMARY_MODEL_FLD);
gr.query();
return _getGroupModelData(gr);
};
NLUStudioService.getModelStatusByName = function(modelName, addPublishStatus) {
if (Array.isArray(modelName)) {
var result = [];
modelName.forEach(function(name) {
result.push(_getModelStatusByName(name, addPublishStatus));
});
return result;
}
return _getModelStatusByName(modelName, addPublishStatus);
};
NLUStudioService.getLastTrainedVersion = function(modelName) {
var solution = NLUParloIntegrator.getSolution(modelName);
return NLUParloIntegrator.getLastTrainedVersion(solution);
};
NLUStudioService.getPublishedVersion = function(modelName) {
var solution = NLUParloIntegrator.getSolution(modelName);
return solution && solution.getActiveVersion();
};
NLUStudioService.getLastTrainedVersionById = function(modelId) {
var modelGr = NLUModel.getGRById(modelId);
return modelGr && NLUStudioService.getLastTrainedVersion(modelGr.getValue('name'));
};
NLUStudioService.getPublishedVersionById = function(modelId) {
var modelGr = NLUModel.getGRById(modelId);
return modelGr && NLUStudioService.getPublishedVersion(modelGr.getValue('name'));
};
NLUStudioService.getAllPublishedModels = function(category) {
var modelsArray = [],
id, nluModelRec;
var modelObj, name, modelNames = '';
var solutionVersion = 0,
modelsObj = {}; //<name>: {model object}
try {
var mlSolutionGr = _getMlSolutionGR();
while (mlSolutionGr.next()) {
name = mlSolutionGr.getValue('solution_name');
// From Quebec, the model name and solution name will be same
modelNames = name + ',' + name.substring(3);
nluModelRec = NLUModel.getGRByName(modelNames);
solutionVersion = mlSolutionGr.getValue('version');
modelObj = {};
if (nluModelRec) {
if (modelsObj[name]) {
if (solutionVersion > modelsObj[name].publishedVersion) {
modelsObj[name].publishedVersion = solutionVersion;
}
continue;
}
modelObj = NLUSystemUtil.getObjectFromGR(nluModelRec, {
name: 'name',
displayName: 'display_name',
id: 'sys_id',
language: 'language',
scope: 'sys_scope',
category: 'category'
});
if (category && category != modelObj.category) continue;
modelObj.language = modelObj.language || constants.MODEL_DEFAULT_LANG;
modelObj.publishedVersion = solutionVersion;
modelsObj[name] = modelObj;
}
}
} catch (e) {}
for (var property in modelsObj) {
modelsArray.push(modelsObj[property]);
}
return modelsArray;
};
NLUStudioService.getIntentsByModel = function(modelName, includeTrained, options) {
var model = NLUModel.getGRByName(modelName);
return NLUStudioService.getIntentsByModelId(model && model.getValue('sys_id'), includeTrained, options);
};
NLUStudioService.getEntitiesByModel = function(modelName, includeTrained, options) {
var model = NLUModel.getGRByName(modelName);
return NLUStudioService.getEntitiesByModelId(model && model.getValue('sys_id'), includeTrained, options);
};
NLUStudioService.getSystemEntitiesByModel = function(modelName) {
var model = NLUModel.getGRByName(modelName);
return NLUStudioService.getSystemEntitiesByModelId(model && model.getValue('sys_id'));
};
NLUStudioService.getEntitiesByIntent = function(intentName, modelName) {
var model = NLUModel.getGRByName(modelName);
if (model) {
var modelId = model.getValue('sys_id');
var nluModel = new NLUModel(modelId);
var intent = nluModel.getIntents('name=' + intentName);
return NLUStudioService.getEntitiesByIntentId(intent && intent.getValue('sys_id'));
}
return [];
};
NLUStudioService.getIntentsByModelId = function(modelId, includeTrained, options) {
if (modelId) {
var nluModel = new NLUModel(modelId);
var filterQuery = constants.ENABLED_INTENTS_QUERY;
if (options && options.includeDisabled) filterQuery = '';
if (options && options.includeDraft) return NLUIntent.getDataFromGR(nluModel.getIntents(filterQuery));
var maxTimeStamp = includeTrained ? nluModel.getLastTrainedTimestamp() : nluModel.getPublishedTimestamp();
if (!gs.nil(maxTimeStamp)) {
filterQuery = 'sys_created_on' + '<=' + maxTimeStamp + '^' + filterQuery;
return NLUIntent.getDataFromGR(nluModel.getIntents(filterQuery));
}
}
return [];
};
NLUStudioService.getEntitiesByModelId = function(modelId, includeTrained, options) {
if (modelId) {
var nluModel = new NLUModel(modelId);
if (options && options.includeDraft) return NLUEntity.getDataFromGR(nluModel.getEntities('', true));
var maxTimeStamp = includeTrained ? nluModel.getLastTrainedTimestamp() : nluModel.getPublishedTimestamp();
if (!gs.nil(maxTimeStamp)) {
var entityRec = nluModel.getEntities('sys_created_on' + '<=' + maxTimeStamp, true);
return NLUEntity.getDataFromGR(entityRec);
}
}
return [];
};
NLUStudioService.getSystemEntitiesByModelId = function(modelId) {
if (modelId) {
var nluModel = new NLUModel(modelId);
return nluModel.getSystemEntities();
}
return [];
};
NLUStudioService.getEntitiesByIntentId = function(intentId) {
if (intentId) {
var nluIntent = new NLUIntent(intentId);
var entityRec = nluIntent.getEntities();
return NLUEntity.getDataFromGR(entityRec);
}
return [];
};
NLUStudioService.getEntities = function(modelId, intentId, includeTrained) {
var result = [];
if (modelId) {
var nluModel = new NLUModel(modelId);
var maxTimeStamp = includeTrained ? nluModel.getLastTrainedTimestamp() : nluModel.getPublishedTimestamp();
var entityRec;
if (!gs.nil(maxTimeStamp)) {
if (intentId) {
// If intentId is also passed, then get only model level entities:
entityRec = nluModel.getModelEntities('sys_created_on' + '<=' + maxTimeStamp);
} else {
entityRec = nluModel.getEntities('sys_created_on' + '<=' + maxTimeStamp, true);
}
result = result.concat(NLUEntity.getDataFromGR(entityRec));
// System entities:
result = result.concat(nluModel.getSystemEntities());
}
}
if (intentId) {
result = result.concat(NLUStudioService.getEntitiesByIntentId(intentId));
}
return result;
};
NLUStudioService.getModelStatus = function(modelId) {
var nluModel = new NLUModel(modelId);
return nluModel.syncStatus();
};
NLUStudioService.createIntent = function(modelProps, intentName) {
try {
if (NLUHelper.isEmpty(modelProps)) throw new Error(gs.getMessage("modelProps are missing"));
var name = modelProps.name || "";
if (name.length < 3) throw new Error(gs.getMessage("Model name must be at least 3 characters long"));
if (name.length > 40) throw new Error(gs.getMessage("Model name cannot be more than 40 characters"));
var result = {};
var priModelId = "";
var modelIds = [];
var modelGr = null;
var category = modelProps.category || constants.MODEL_CAT_SEARCH;
var primaryLanguage = modelProps.primaryLanguage || constants.MODEL_DEFAULT_LANG;
var supportedLanguages = NLUParloIntegrator.getSupportedLanguageCodesByCategory(modelProps.category);
var secondaryLanguages = modelProps.secondaryLanguages && modelProps.secondaryLanguages.filter(function(language) {
return supportedLanguages.indexOf(language) !== -1;
});
modelProps.secondaryLanguages = secondaryLanguages;
if (!modelProps.sys_id) {
if (supportedLanguages.indexOf(primaryLanguage) === -1) throw new Error(gs.getMessage('Primary language is not in one of the supported languages'));
priModelId = NLUModelGroup.createModelGroup(modelProps, supportedLanguages);
modelGr = NLUModel.getGRById(priModelId);
} else if (modelProps.sys_id) {
modelGr = NLUModel.getGRById(modelProps.sys_id);
if (!modelGr) {
throw new Error(gs.getMessage('Model does not exist'));
}
priModelId = _getPrimaryModelById(modelProps.sys_id);
new NLUModelGroup(priModelId).createSecondaryModels(modelProps, supportedLanguages);
}
var languages = modelProps.secondaryLanguages || [];
languages.push(modelGr.getValue('language'));
var nluModelGroup = new NLUModelGroup(priModelId);
new NLUModel(priModelId).createIntent(intentName);
nluModelGroup.enableIntents(intentName, languages);
modelIds = nluModelGroup.getModelIds(modelProps.secondaryLanguages);
modelIds.forEach(function(modelId) {
var _result = {};
var nluModel = new NLUModel(modelId).getGR();
_result.name = nluModel.getValue('name');
_result.displayName = nluModel.getValue('display_name');
_result.primary = !nluModel.primary_model ? true : false;
result[nluModel.getValue('language')] = _result;
});
return result;
} catch (e) {
return {
status: 'failure',
message: e.message
};
}
};
NLUStudioService.isIntentInSolutionMappedtoVATopic = function(solution) {
var modelName = solution.ml_capability_definition.solution_label + '';
var gr = NLUModel.getGRByName(modelName);
var modelId = gr.getUniqueValue();
return new NLUInterfaceHelper().getMappedIntentsCountInModel(modelId) > 0;
};
NLUStudioService.prototype = {
initialize: function() {},
type: 'NLUStudioService'
};
})();
Sys ID
73ee854c07951010220b0a701ad300df