cleaned up help and options
This commit is contained in:
Родитель
3b6718eb84
Коммит
0908c356f6
|
@ -299,3 +299,9 @@ test/*.transcript
|
|||
/packages/LUISGen/LUISGenTestJS/src/Contoso_App.js
|
||||
/packages/LUISGen/LUISGenTestJS/src/Contoso_App.d.ts
|
||||
*.tgz
|
||||
|
||||
# lubuild
|
||||
**/lubuild/bin/**
|
||||
**/lubuild/lib/**
|
||||
**/lubuild/typings/**
|
||||
**/lubuild/models/**
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
//# sourceMappingURL=IBuildArgs.js.map
|
|
@ -1 +0,0 @@
|
|||
{"version":3,"file":"IBuildArgs.js","sourceRoot":"","sources":["../src/IBuildArgs.ts"],"names":[],"mappings":""}
|
|
@ -1,3 +0,0 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
//# sourceMappingURL=IConfig.js.map
|
|
@ -1 +0,0 @@
|
|||
{"version":3,"file":"IConfig.js","sourceRoot":"","sources":["../src/IConfig.ts"],"names":[],"mappings":""}
|
|
@ -1,90 +0,0 @@
|
|||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const fs = require("async-file");
|
||||
const path = require("path");
|
||||
const txtfile = require("read-text-file");
|
||||
const url_1 = require("url");
|
||||
class LuisRecognizer {
|
||||
constructor() {
|
||||
this['$type'] = 'Microsoft.LuisRecognizer';
|
||||
this.dialogPath = '';
|
||||
this.applicationId = null;
|
||||
this.endpoint = null;
|
||||
this.endpointKey = "{settings.luis.endpointKey}";
|
||||
}
|
||||
static load(dialogPath) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (yield fs.exists(dialogPath)) {
|
||||
let recognizer = new LuisRecognizer();
|
||||
recognizer.dialogPath = dialogPath;
|
||||
let json = yield txtfile.read(dialogPath);
|
||||
Object.assign(recognizer, JSON.parse(json));
|
||||
return recognizer;
|
||||
}
|
||||
var recognizer = new LuisRecognizer();
|
||||
recognizer.dialogPath = dialogPath;
|
||||
return recognizer;
|
||||
});
|
||||
}
|
||||
save() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
yield fs.writeTextFile(this.dialogPath, JSON.stringify(this, null, 4), 'utf8');
|
||||
});
|
||||
}
|
||||
getCloud() {
|
||||
if (this.endpoint) {
|
||||
let url = new url_1.URL(this.endpoint);
|
||||
return path.extname(url.hostname);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
getRegion() {
|
||||
if (this.endpoint) {
|
||||
let url = new url_1.URL(this.endpoint);
|
||||
return url.hostname.substring(0, url.hostname.indexOf('.'));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
getCulture() {
|
||||
let fn = path.basename(this.dialogPath, '.dialog');
|
||||
let lang = path.extname(fn).substring(1);
|
||||
switch (lang.toLowerCase()) {
|
||||
case 'en-us':
|
||||
case 'zh-cn':
|
||||
case 'nl-nl':
|
||||
case 'fr-fr':
|
||||
case 'fr-ca':
|
||||
case 'de-de':
|
||||
case 'it-it':
|
||||
case 'ja-jp':
|
||||
case 'ko-kr':
|
||||
case 'pt-br':
|
||||
case 'es-es':
|
||||
case 'es-mx':
|
||||
case 'tr-tr':
|
||||
return lang;
|
||||
default:
|
||||
return 'en-us';
|
||||
}
|
||||
}
|
||||
getFileName() {
|
||||
return path.basename(this.dialogPath);
|
||||
}
|
||||
getLuFile(files) {
|
||||
for (let file of files) {
|
||||
if (path.basename(file, '.lu') == path.basename(this.dialogPath, '.dialog'))
|
||||
return file;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
exports.LuisRecognizer = LuisRecognizer;
|
||||
//# sourceMappingURL=LuisRecognizer.js.map
|
|
@ -1 +0,0 @@
|
|||
{"version":3,"file":"LuisRecognizer.js","sourceRoot":"","sources":["../src/LuisRecognizer.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,iCAAiC;AACjC,6BAA6B;AAC7B,0CAA0C;AAC1C,6BAA0B;AAE1B,MAAa,cAAc;IAGvB;QACU,IAAK,CAAC,OAAO,CAAC,GAAG,0BAA0B,CAAC;QAClD,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC;QACrB,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;QAC1B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,IAAI,CAAC,WAAW,GAAG,6BAA6B,CAAC;IACrD,CAAC;IAED,MAAM,CAAO,IAAI,CAAC,UAAkB;;YAEhC,IAAI,MAAM,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE;gBAC7B,IAAI,UAAU,GAAG,IAAI,cAAc,EAAE,CAAC;gBACtC,UAAU,CAAC,UAAU,GAAG,UAAU,CAAC;gBACnC,IAAI,IAAI,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;gBAC1C,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;gBAC5C,OAAO,UAAU,CAAC;aACrB;YACD,IAAI,UAAU,GAAG,IAAI,cAAc,EAAE,CAAC;YACtC,UAAU,CAAC,UAAU,GAAG,UAAU,CAAC;YACnC,OAAO,UAAU,CAAC;QACtB,CAAC;KAAA;IAEK,IAAI;;YACN,MAAM,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;QACnF,CAAC;KAAA;IAED,QAAQ;QACJ,IAAI,IAAI,CAAC,QAAQ,EAAE;YACf,IAAI,GAAG,GAAG,IAAI,SAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACjC,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;SACrC;QACD,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,SAAS;QACL,IAAI,IAAI,CAAC,QAAQ,EAAE;YACf,IAAI,GAAG,GAAG,IAAI,SAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACjC,OAAO,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;SAC/D;QACD,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,UAAU;QACN,IAAI,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;QACnD,IAAI,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;QACzC,QAAQ,IAAI,CAAC,WAAW,EAAE,EAAE;YACxB,KAAK,OAAO,CAAC;YACb,KAAK,OAAO,CAAC;YACb,KAAK,OAAO,CAAC;YACb,KAAK,OAAO,CAAC;YACb,KAAK,OAAO,CAAC;YACb,KAAK,OAAO,CAAC;YACb,KAAK,OAAO,CAAC;YACb,KAAK,OAAO,CAAC;YACb,KAAK,OAAO,CAAC;YACb,KAAK,OAAO,CAAC;YACb,KAAK,OAAO,CAAC;YACb,KAAK,OAAO,CAAC;YACb,KAAK,OAAO;gBACR,OAAO,IAAI,CAAC;YAChB;gBACI,OAAO,OAAO,CAAC;SACtB;IACL,CAAC;IAED,WAAW;QACP,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC1C,CAAC;IAED,SAAS,CAAC,KAAe;QACrB,KAAI,IAAI,IAAI,IAAI,KAAK,EAAE;YACnB,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,EAAE,SAAS,CAAC;gBACvE,OAAO,IAAI,CAAC;SACnB;QACD,OAAO,IAAI,CAAC;IAChB,CAAC;CAKJ;AAnFD,wCAmFC"}
|
|
@ -1,229 +0,0 @@
|
|||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const msRest = require("@azure/ms-rest-js");
|
||||
const fs = require("async-file");
|
||||
const chalk = require("chalk");
|
||||
const latestVersion = require("latest-version");
|
||||
const luis_apis_1 = require("luis-apis");
|
||||
const path = require("path");
|
||||
const process = require("process");
|
||||
const txtfile = require("read-text-file");
|
||||
const semver = require("semver");
|
||||
const LuisRecognizer_1 = require("./LuisRecognizer");
|
||||
const utils_1 = require("./utils");
|
||||
const username = require('username');
|
||||
const pkg = require('../package.json');
|
||||
const minimist = require('minimist');
|
||||
const delay = require('await-delay');
|
||||
runProgram()
|
||||
.then(() => process.exit())
|
||||
.catch((err) => __awaiter(this, void 0, void 0, function* () {
|
||||
yield error(err.message);
|
||||
process.exit(1);
|
||||
}));
|
||||
/**
|
||||
* Entry for the app
|
||||
*
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
function runProgram() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let latest = yield latestVersion(pkg.name, { version: `>${pkg.version}` })
|
||||
.catch(_error => pkg.version);
|
||||
if (semver.gt(latest, pkg.version)) {
|
||||
process.stderr.write(chalk.default.white(`\n Update available `));
|
||||
process.stderr.write(chalk.default.grey(`${pkg.version}`));
|
||||
process.stderr.write(chalk.default.white(` -> `));
|
||||
process.stderr.write(chalk.default.greenBright(`${latest}\n`));
|
||||
process.stderr.write(chalk.default.white(` Run `));
|
||||
process.stderr.write(chalk.default.blueBright(`npm i -g ${pkg.name} `));
|
||||
process.stderr.write(chalk.default.white(`to update.\n\n`));
|
||||
}
|
||||
let argvFragment = process.argv.slice(2);
|
||||
let args = minimist(argvFragment, { string: ['versionId'] });
|
||||
if (args.help ||
|
||||
args.h ||
|
||||
args['!'] ||
|
||||
args._.includes('help')) {
|
||||
return help();
|
||||
}
|
||||
if (args.version || args.v) {
|
||||
return process.stdout.write(require(path.join(__dirname, '../package.json')).version + "\n");
|
||||
}
|
||||
if (!args.config) {
|
||||
args.config = './models.config';
|
||||
}
|
||||
if (!(yield fs.exists(args.config))) {
|
||||
return error(`missing models.config file or --config argument`);
|
||||
}
|
||||
if (!args.environment) {
|
||||
args.environment = yield username();
|
||||
}
|
||||
console.log(`Target Environment:${args.environment}`);
|
||||
let json = yield txtfile.read(args.config);
|
||||
let config = JSON.parse(json);
|
||||
console.log(JSON.stringify(config, null, 4));
|
||||
for (let path of config.models) {
|
||||
if (!(yield fs.exists(path))) {
|
||||
throw new Error(`config file ${path} does not exist`);
|
||||
}
|
||||
}
|
||||
delete args.config;
|
||||
Object.assign(config, args);
|
||||
if (!config.autodelete) {
|
||||
config.autodelete = true;
|
||||
}
|
||||
if (!config.authoringKey) {
|
||||
throw new Error('missing authoringkey');
|
||||
}
|
||||
if (!config.name) {
|
||||
throw new Error('missing name');
|
||||
}
|
||||
if (!config.region) {
|
||||
config.region = 'westus';
|
||||
}
|
||||
if (!config.folder) {
|
||||
config.folder = 'models';
|
||||
}
|
||||
yield runBuild(config);
|
||||
});
|
||||
}
|
||||
function help() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
process.stdout.write('LUIS Command Line Interface - © 2018 Microsoft Corporation\n\n');
|
||||
return;
|
||||
});
|
||||
}
|
||||
function error(message) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
process.stderr.write(chalk.default.red(message));
|
||||
yield help();
|
||||
return;
|
||||
});
|
||||
}
|
||||
function runBuild(config) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let credentials = new msRest.ApiKeyCredentials({ inHeader: { "Ocp-Apim-Subscription-Key": config.authoringKey } });
|
||||
const client = new luis_apis_1.LuisAuthoring(credentials);
|
||||
for (let modelPath of config.models) {
|
||||
yield processLuModelPath(client, config, modelPath);
|
||||
}
|
||||
});
|
||||
}
|
||||
function processLuModelPath(client, config, modelPath) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let rootFolder = path.dirname(modelPath);
|
||||
let rootFile = path.basename(modelPath, '.lu');
|
||||
// get all lu variations from same folder as the .lu file
|
||||
let dialogFiles = yield fs.readdir(rootFolder);
|
||||
let luFiles = [];
|
||||
dialogFiles.forEach(file => {
|
||||
if (path.extname(file) == '.lu' && file.startsWith(rootFile)) {
|
||||
luFiles.push(path.join(rootFolder, path.basename(file)));
|
||||
}
|
||||
});
|
||||
// get current .dialog definitions from the config.folder
|
||||
if (!(yield fs.exists(config.folder))) {
|
||||
yield fs.createDirectory(config.folder);
|
||||
}
|
||||
dialogFiles = yield fs.readdir(config.folder || '');
|
||||
// let recognizers: { [key: string]: LuisRecognizer } = {};
|
||||
for (var luFile of luFiles) {
|
||||
let dialogFile = path.join(config.folder, path.basename(luFile, '.lu') + '.dialog');
|
||||
let recognizer = yield LuisRecognizer_1.LuisRecognizer.load(dialogFile);
|
||||
if (recognizer.applicationId == null) {
|
||||
// create the application
|
||||
let culture = recognizer.getCulture();
|
||||
let name = `${config.name}-${config.environment}-${config.region}-${culture}-${rootFile}.lu`;
|
||||
console.log(`creating application: ${name}`);
|
||||
let response = yield client.apps.add(config.region, "com", {
|
||||
"name": name,
|
||||
"description": `Model for ${config.name} app, targetting ${config.environment} for ${rootFile}.lu file`,
|
||||
"culture": recognizer.getCulture(),
|
||||
"usageScenario": "",
|
||||
"domain": "",
|
||||
"initialVersionId": "0000000000"
|
||||
}, {});
|
||||
recognizer.applicationId = response.body;
|
||||
recognizer.endpoint = `https://${config.region}.api.cognitive.microsoft.com/`;
|
||||
yield recognizer.save();
|
||||
}
|
||||
else {
|
||||
yield updateModel(config, client, luFiles, recognizer);
|
||||
}
|
||||
}
|
||||
return;
|
||||
});
|
||||
}
|
||||
function updateModel(config, client, luFiles, recognizer) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
// get app info
|
||||
let appInfo = yield client.apps.get(config.region, "com", recognizer.applicationId || '');
|
||||
// get activeVersion
|
||||
//let activeVersion = await client.versions.exportMethod(<AzureRegions>config.region, <AzureClouds>"com", recognizer.applicationId || '', appInfo.activeVersion || '');
|
||||
var activeVersionInfo = yield client.versions.get(config.region, "com", recognizer.applicationId || '', appInfo.activeVersion || '');
|
||||
let luFile = recognizer.getLuFile(luFiles);
|
||||
var stats = yield fs.stat(luFile);
|
||||
// if different, then update
|
||||
if (activeVersionInfo && activeVersionInfo.lastModifiedDateTime < stats.mtime) {
|
||||
console.log(`${luFile} changed`);
|
||||
let outFile = luFile + ".json";
|
||||
// run ludown on file
|
||||
yield utils_1.runCommand(`ludown parse ToLuis --in ${luFile} --out ${outFile}`);
|
||||
let newJson = yield txtfile.read(outFile);
|
||||
// await fs.delete(outFile);
|
||||
let newVersion = JSON.parse(newJson);
|
||||
newVersion.name = appInfo.name;
|
||||
newVersion.desc = appInfo.description;
|
||||
newVersion.culture = appInfo.culture;
|
||||
// increment version
|
||||
let newVersionId = pad(parseInt(appInfo.activeVersion) + 1, 10);
|
||||
newVersion.versionId = newVersionId;
|
||||
// import new version
|
||||
console.log(`${luFile} creating new version=${newVersionId}`);
|
||||
yield client.versions.importMethod(config.region, "com", recognizer.applicationId, newVersion, { versionId: newVersionId });
|
||||
// console.log(JSON.stringify(importResult.body));
|
||||
// train the version
|
||||
console.log(`${luFile} training new version=${newVersionId}`);
|
||||
let trainResult = yield client.train.trainVersion(config.region, "com", recognizer.applicationId || '', newVersionId);
|
||||
if (trainResult.status == 'Queued') {
|
||||
let done = true;
|
||||
do {
|
||||
yield delay(1000);
|
||||
let trainingStatus = yield client.train.getStatus(config.region, "com", recognizer.applicationId || '', newVersionId);
|
||||
done = true;
|
||||
for (let status of trainingStatus) {
|
||||
if (status.details) {
|
||||
if (status.details.status == 'InProgress') {
|
||||
done = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (!done);
|
||||
}
|
||||
// publish the version
|
||||
console.log(`${luFile} publishing new version=${newVersionId}`);
|
||||
let publishResult = yield client.apps.publish(config.region, "com", recognizer.applicationId || '', {
|
||||
"versionId": newVersionId,
|
||||
"isStaging": false
|
||||
});
|
||||
console.log(JSON.stringify(publishResult));
|
||||
}
|
||||
else {
|
||||
console.log(`${luFile} no changes`);
|
||||
}
|
||||
});
|
||||
}
|
||||
function pad(num, size) {
|
||||
return ('000000000000000' + num).substr(-size);
|
||||
}
|
||||
//# sourceMappingURL=index.js.map
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -1,38 +0,0 @@
|
|||
"use strict";
|
||||
/**
|
||||
* Copyright(c) Microsoft Corporation.All rights reserved.
|
||||
* Licensed under the MIT License.
|
||||
*/
|
||||
// child_process.spawn isn't promise and is complicated in how to captures stream of stdout/sterr
|
||||
// export function spawnAsync(command: string, stdout?: (data: string) => void, stderr?: (data: string) => void): Promise<string> {
|
||||
// return new Promise<string>((resolve: (value?: string) => void, reject: (value?: string) => void): void => {
|
||||
// const parts: string[] = command.split(' ');
|
||||
// const p: child_process.ChildProcess = child_process.spawn(parts[0], parts.slice(1), {
|
||||
// shell: true, stdio: ['inherit', 'pipe', 'pipe']
|
||||
// });
|
||||
// let out: string = '';
|
||||
// let err: string = '';
|
||||
// p.stderr.on('data', (data: Buffer) => {
|
||||
// let str = data.toString('utf8');
|
||||
// err += str;
|
||||
// if (stderr) {
|
||||
// stderr(str);
|
||||
// }
|
||||
// });
|
||||
// p.stdout.on('data', (data: Buffer) => {
|
||||
// let str = data.toString('utf8');
|
||||
// out += str;
|
||||
// if (stdout) {
|
||||
// stdout(str);
|
||||
// }
|
||||
// });
|
||||
// p.on('close', (code: number) => {
|
||||
// if (code > 0) {
|
||||
// reject(`${command} exit code: ${code}\n${err}`);
|
||||
// } else {
|
||||
// resolve(out);
|
||||
// }
|
||||
// });
|
||||
// });
|
||||
// }
|
||||
//# sourceMappingURL=processUtils.js.map
|
|
@ -1 +0,0 @@
|
|||
{"version":3,"file":"processUtils.js","sourceRoot":"","sources":["../src/processUtils.ts"],"names":[],"mappings":";AAAA;;;GAGG;AAEH,iGAAiG;AACjG,mIAAmI;AACnI,kHAAkH;AAClH,sDAAsD;AACtD,gGAAgG;AAChG,8DAA8D;AAC9D,cAAc;AACd,gCAAgC;AAChC,gCAAgC;AAChC,kDAAkD;AAClD,+CAA+C;AAC/C,0BAA0B;AAC1B,4BAA4B;AAC5B,+BAA+B;AAC/B,gBAAgB;AAChB,cAAc;AAEd,kDAAkD;AAClD,+CAA+C;AAC/C,0BAA0B;AAC1B,4BAA4B;AAC5B,+BAA+B;AAC/B,gBAAgB;AAChB,cAAc;AAEd,4CAA4C;AAC5C,8BAA8B;AAC9B,mEAAmE;AACnE,uBAAuB;AACvB,gCAAgC;AAChC,gBAAgB;AAChB,cAAc;AACd,UAAU;AACV,IAAI"}
|
|
@ -1,27 +0,0 @@
|
|||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const child_process = require("child_process");
|
||||
const util = require("util");
|
||||
const exec = util.promisify(child_process.exec);
|
||||
function runCommand(command) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
console.log(command);
|
||||
let p = yield exec(command, { maxBuffer: 1024 * 2048 });
|
||||
try {
|
||||
return JSON.parse(p.stdout);
|
||||
}
|
||||
catch (err) {
|
||||
return p.stdout;
|
||||
}
|
||||
});
|
||||
}
|
||||
exports.runCommand = runCommand;
|
||||
//# sourceMappingURL=utils.js.map
|
|
@ -1 +0,0 @@
|
|||
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,+CAA+C;AAC/C,6BAA6B;AAC7B,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;AAEhD,SAAsB,UAAU,CAAC,OAAe;;QAC5C,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACrB,IAAI,CAAC,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,GAAG,IAAI,EAAE,CAAC,CAAC;QACxD,IAAI;YACA,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;SAC/B;QAAC,OAAO,GAAG,EAAE;YACV,OAAO,CAAC,CAAC,MAAM,CAAC;SACnB;IACL,CAAC;CAAA;AARD,gCAQC"}
|
|
@ -1,6 +1,7 @@
|
|||
{
|
||||
"name":"MyBot",
|
||||
"models":[
|
||||
"test/test.lu"
|
||||
"test/test.lu",
|
||||
"test/sample/x/Contoso.Foo.lu"
|
||||
]
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
{
|
||||
"$type": "Microsoft.LuisRecognizer",
|
||||
"dialogPath": "models\\test.de-de.dialog",
|
||||
"applicationId": "cba01414-634a-4298-8d55-be492341c966",
|
||||
"endpoint": "https://westus.api.cognitive.microsoft.com/",
|
||||
"endpointKey": "{settings.luis.endpointKey}"
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
{
|
||||
"$type": "Microsoft.LuisRecognizer",
|
||||
"dialogPath": "models\\test.dialog",
|
||||
"applicationId": "c527888c-30c9-4cd9-8c7e-bdbccb81fab1",
|
||||
"endpoint": "https://westus.api.cognitive.microsoft.com/",
|
||||
"endpointKey": "{settings.luis.endpointKey}"
|
||||
}
|
|
@ -225,11 +225,6 @@
|
|||
"delayed-stream": "~1.0.0"
|
||||
}
|
||||
},
|
||||
"compare-obj": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/compare-obj/-/compare-obj-1.0.0.tgz",
|
||||
"integrity": "sha1-gEsEXDhAjjAnBz8F9+ExIOqedkk="
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
|
|
|
@ -2,13 +2,25 @@
|
|||
"name": "lubuild",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"main": "./bin/index.js",
|
||||
"bin": {
|
||||
"lubuild": "./bin/index.js"
|
||||
},
|
||||
"types": "bin/index.d.ts",
|
||||
"author": "",
|
||||
"scripts": {
|
||||
"test": "cd test/ && mocha --opts mocha.opts",
|
||||
"clean": "erase /Q /s lib\\* && erase /Q /s typings\\*",
|
||||
"build": "tsc"
|
||||
},
|
||||
"directories": {
|
||||
"bin": "bin",
|
||||
"typings": "typings"
|
||||
},
|
||||
"files": [
|
||||
"bin/",
|
||||
"typings/"
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@azure/ms-rest-js": "1.7.0",
|
||||
|
|
|
@ -6,16 +6,16 @@ export interface IBuildArgs {
|
|||
name: string;
|
||||
|
||||
// target environment (username, production, etc.)
|
||||
environment: string | null;
|
||||
environment: string | undefined;
|
||||
|
||||
// cli override of authoringkey
|
||||
authoringKey: string | null;
|
||||
authoringKey: string | undefined;
|
||||
|
||||
// authoring region
|
||||
region: string|null;
|
||||
authoringRegion: string | undefined;
|
||||
|
||||
// alternate path to lubuild.config
|
||||
config: string | null;
|
||||
config: string | undefined;
|
||||
|
||||
// build all languages (default:true)
|
||||
multilingual: boolean;
|
||||
|
@ -23,9 +23,9 @@ export interface IBuildArgs {
|
|||
// delete old version after successfully creating version (default:True)
|
||||
autodelete: boolean;
|
||||
|
||||
// publish to production (default:true, it will publish to staging slot)
|
||||
production: boolean;
|
||||
|
||||
// output folder (default: models)
|
||||
folder: string | null;
|
||||
folder: string | undefined;
|
||||
|
||||
// force update of models
|
||||
force: boolean;
|
||||
}
|
||||
|
|
|
@ -4,32 +4,38 @@ import * as txtfile from 'read-text-file';
|
|||
import { URL } from 'url';
|
||||
|
||||
export class LuisRecognizer {
|
||||
private dialogPath: string;
|
||||
private dialogPath: string | undefined;
|
||||
private luFile: string;
|
||||
|
||||
constructor() {
|
||||
(<any>this)['$type'] = 'Microsoft.LuisRecognizer';
|
||||
this.dialogPath = '';
|
||||
this.applicationId = null;
|
||||
this.endpoint = null;
|
||||
constructor(luFile: string) {
|
||||
this.luFile = luFile;
|
||||
this.applicationId = undefined;
|
||||
this.versionId = '0000000000';
|
||||
this.endpoint = `{settings.luis.endpointRegion}`;
|
||||
this.endpointKey = "{settings.luis.endpointKey}";
|
||||
}
|
||||
|
||||
static async load(dialogPath: string): Promise<LuisRecognizer> {
|
||||
|
||||
static async load(luFile: string, dialogPath: string): Promise<LuisRecognizer> {
|
||||
if (await fs.exists(dialogPath)) {
|
||||
let recognizer = new LuisRecognizer();
|
||||
let recognizer = new LuisRecognizer(luFile);
|
||||
recognizer.dialogPath = dialogPath;
|
||||
let json = await txtfile.read(dialogPath);
|
||||
Object.assign(recognizer, JSON.parse(json));
|
||||
return recognizer;
|
||||
}
|
||||
var recognizer = new LuisRecognizer();
|
||||
var recognizer = new LuisRecognizer(luFile);
|
||||
recognizer.dialogPath = dialogPath;
|
||||
return recognizer;
|
||||
}
|
||||
|
||||
async save(): Promise<void> {
|
||||
await fs.writeTextFile(this.dialogPath, JSON.stringify(this, null, 4), 'utf8');
|
||||
let output = {
|
||||
"$type": 'Microsoft.LuisRecognizer',
|
||||
applicationId: this.applicationId,
|
||||
endpoint: this.endpoint,
|
||||
endpointKey: this.endpointKey
|
||||
}
|
||||
await fs.writeTextFile(<string>this.dialogPath, JSON.stringify(output, null, 4), 'utf8');
|
||||
}
|
||||
|
||||
getCloud() {
|
||||
|
@ -48,43 +54,17 @@ export class LuisRecognizer {
|
|||
return null;
|
||||
}
|
||||
|
||||
getCulture(): string {
|
||||
let fn = path.basename(this.dialogPath, '.dialog');
|
||||
let lang = path.extname(fn).substring(1);
|
||||
switch (lang.toLowerCase()) {
|
||||
case 'en-us':
|
||||
case 'zh-cn':
|
||||
case 'nl-nl':
|
||||
case 'fr-fr':
|
||||
case 'fr-ca':
|
||||
case 'de-de':
|
||||
case 'it-it':
|
||||
case 'ja-jp':
|
||||
case 'ko-kr':
|
||||
case 'pt-br':
|
||||
case 'es-es':
|
||||
case 'es-mx':
|
||||
case 'tr-tr':
|
||||
return lang;
|
||||
default:
|
||||
return 'en-us';
|
||||
}
|
||||
getFileName(): string {
|
||||
return path.basename(<string>this.dialogPath);
|
||||
}
|
||||
|
||||
getFileName() : string {
|
||||
return path.basename(this.dialogPath);
|
||||
getLuFile() {
|
||||
return this.luFile;
|
||||
}
|
||||
|
||||
getLuFile(files: string[]) {
|
||||
for(let file of files) {
|
||||
if (path.basename(file, '.lu') == path.basename(this.dialogPath, '.dialog'))
|
||||
return file;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
applicationId: string | null;
|
||||
endpoint: string | null;
|
||||
endpointKey: string | null;
|
||||
applicationId: string | undefined;
|
||||
versionId: string | undefined;
|
||||
endpoint: string | undefined;
|
||||
endpointKey: string | undefined;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
/**
|
||||
* Copyright(c) Microsoft Corporation.All rights reserved.
|
||||
* Licensed under the MIT License.
|
||||
*/
|
||||
import * as chalk from 'chalk';
|
||||
const Table = require('cli-table3');
|
||||
|
||||
const windowSize = require('window-size');
|
||||
|
||||
/**
|
||||
* Displays help content from the arguments.
|
||||
*
|
||||
* @param args The arguments input by the user
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
export async function help(output: NodeJS.WriteStream) {
|
||||
if (!output)
|
||||
output = process.stdout;
|
||||
|
||||
output.write('LUBUILD Command Line Interface - © 2018 Microsoft Corporation\n\n');
|
||||
const helpContents = getHelpContents();
|
||||
|
||||
let width = windowSize ? windowSize.width : 250;
|
||||
let leftColWidth = 0;
|
||||
for (let hc of helpContents) {
|
||||
if (hc.table && hc.table[0].length > 0) {
|
||||
for (let row in hc.table) {
|
||||
let len = hc.table[row][0].length;
|
||||
if (len > leftColWidth) {
|
||||
leftColWidth = Math.min(len, Math.floor(width / 3));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (let helpContent of helpContents) {
|
||||
output.write(chalk.default.white.bold(helpContent.head + '\n'));
|
||||
if (helpContent.table && helpContent.table[0].length > 0) {
|
||||
const rows = helpContent.table[0].length;
|
||||
let i = rows - 1;
|
||||
|
||||
let colWidthsFor2On = ((width * .85) - leftColWidth) / i;
|
||||
let colWidths = [leftColWidth];
|
||||
|
||||
while (i--) {
|
||||
colWidths.push(~~colWidthsFor2On);
|
||||
}
|
||||
|
||||
let table = new Table({
|
||||
// don't use lines for table
|
||||
"chars" : {
|
||||
'top': '', 'top-mid': '', 'top-left': '', 'top-right': '',
|
||||
'bottom': '', 'bottom-mid': '', 'bottom-left': '', 'bottom-right': '',
|
||||
'left': '', 'left-mid': '', 'right': '', 'right-mid': '',
|
||||
'mid': '', 'mid-mid': '', 'middle': ''
|
||||
},
|
||||
colWidths,
|
||||
style: { 'padding-left': 1, 'padding-right': 1 },
|
||||
wordWrap: true
|
||||
});
|
||||
table.push(...helpContent.table);
|
||||
output.write(table.toString());
|
||||
}
|
||||
output.write('\n\n');
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* General help contents
|
||||
*
|
||||
* @returns {*[]}
|
||||
*/
|
||||
function getHelpContents() {
|
||||
let sections = [];
|
||||
|
||||
sections.push({
|
||||
head: chalk.default.bold(`Configuration Settings:`),
|
||||
table: [
|
||||
[chalk.default.cyan.bold('--authoringKey [key]'), 'Specifies the LUIS authoring key (from luis.ai portal user settings page).'],
|
||||
[chalk.default.cyan.bold('--environment [name]'), '(OPTIONAL) sets the target environment (Default: useralias)'],
|
||||
[chalk.default.cyan.bold('--authoringRegion [westus|westeurope|australiaeast]'), '(OPTIONAL) overrides models.config with the authoring region for all requests. (Default:westus)'],
|
||||
[chalk.default.cyan.bold('--config [folder]'), '(OPTIONAL) specifies the models file (Default: ./models.config)'],
|
||||
[chalk.default.cyan.bold('--name [projectname]'), '(OPTIONAL) overrides config file with project name '],
|
||||
[chalk.default.cyan.bold('--folder [foldernmae]'), '(OPTIONAL) overrides config file with output folder name'],
|
||||
[chalk.default.cyan.bold('--force'), '(OPTIONAL) Force all models to be updated '],
|
||||
]
|
||||
});
|
||||
|
||||
sections.push({
|
||||
head: 'Global Arguments:',
|
||||
table: [
|
||||
[chalk.default.cyan.bold('--help, -h'), `Prints this help file. `],
|
||||
[chalk.default.cyan.bold('--version, -v'), 'Prints the version of this cli tool'],
|
||||
]
|
||||
});
|
||||
return sections;
|
||||
}
|
||||
|
|
@ -1,13 +1,15 @@
|
|||
#!/usr/bin/env node
|
||||
import * as msRest from '@azure/ms-rest-js';
|
||||
import * as fs from 'async-file';
|
||||
import * as chalk from 'chalk';
|
||||
import * as latestVersion from 'latest-version';
|
||||
import { LuisAuthoring } from 'luis-apis';
|
||||
import { AzureClouds, AzureRegions, LuisApp } from 'luis-apis/typings/lib/models';
|
||||
import { AppsAddResponse, AppsGetResponse, AzureClouds, AzureRegions, LuisApp } from 'luis-apis/typings/lib/models';
|
||||
import * as path from 'path';
|
||||
import * as process from 'process';
|
||||
import * as txtfile from 'read-text-file';
|
||||
import * as semver from 'semver';
|
||||
import { help } from './help';
|
||||
import { IConfig } from './IConfig';
|
||||
import { LuisRecognizer } from './LuisRecognizer';
|
||||
import { runCommand } from './utils';
|
||||
|
@ -50,7 +52,7 @@ async function runProgram() {
|
|||
args.h ||
|
||||
args['!'] ||
|
||||
args._.includes('help')) {
|
||||
return help();
|
||||
return help(process.stdout);
|
||||
}
|
||||
|
||||
if (args.version || args.v) {
|
||||
|
@ -68,11 +70,14 @@ async function runProgram() {
|
|||
if (!args.environment) {
|
||||
args.environment = await username();
|
||||
}
|
||||
console.log(`Target Environment:${args.environment}`);
|
||||
|
||||
let json = await txtfile.read(args.config);
|
||||
let config: IConfig = JSON.parse(json);
|
||||
console.log(JSON.stringify(config, null, 4));
|
||||
let config: IConfig;
|
||||
try {
|
||||
config = JSON.parse(json);
|
||||
} catch (err) {
|
||||
throw new Error(chalk.default.red(`Error parsing ${args.config}:\n${err}`));
|
||||
}
|
||||
|
||||
for (let path of config.models) {
|
||||
if (!await fs.exists(path)) {
|
||||
|
@ -95,26 +100,29 @@ async function runProgram() {
|
|||
throw new Error('missing name');
|
||||
}
|
||||
|
||||
if (!config.region) {
|
||||
config.region = 'westus';
|
||||
if (!config.authoringRegion) {
|
||||
config.authoringRegion = 'westus';
|
||||
} else {
|
||||
if (config.authoringRegion != 'westus' &&
|
||||
config.authoringRegion != 'westeurope' &&
|
||||
config.authoringRegion != 'australiaeast') {
|
||||
throw new Error(`${config.authoringRegion} is not a valid authoring region (westus|westeurope|australiaeast)`);
|
||||
}
|
||||
}
|
||||
|
||||
if (!config.folder) {
|
||||
config.folder = 'models';
|
||||
}
|
||||
console.log(JSON.stringify(config, null, 4));
|
||||
|
||||
console.log(`Building models for environment [${chalk.default.bold(<string>config.environment)}] targeting authoring region [${chalk.default.bold(config.authoringRegion)}] `);
|
||||
|
||||
await runBuild(config);
|
||||
}
|
||||
|
||||
async function help() {
|
||||
process.stdout.write('LUIS Command Line Interface - © 2018 Microsoft Corporation\n\n');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
async function error(message: string) {
|
||||
process.stderr.write(chalk.default.red(message));
|
||||
await help();
|
||||
process.stderr.write(chalk.default.redBright(message) + '\n');
|
||||
await help(process.stdout);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -123,12 +131,12 @@ async function runBuild(config: IConfig) {
|
|||
const client = new LuisAuthoring(<any>credentials);
|
||||
|
||||
for (let modelPath of config.models) {
|
||||
await processLuModelPath(client, config, modelPath);
|
||||
await processLuFile(client, config, modelPath);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async function processLuModelPath(client: LuisAuthoring, config: IConfig, modelPath: string): Promise<void> {
|
||||
async function processLuFile(client: LuisAuthoring, config: IConfig, modelPath: string): Promise<void> {
|
||||
let rootFolder = path.dirname(modelPath);
|
||||
let rootFile = path.basename(modelPath, '.lu');
|
||||
|
||||
|
@ -149,56 +157,96 @@ async function processLuModelPath(client: LuisAuthoring, config: IConfig, modelP
|
|||
dialogFiles = await fs.readdir(config.folder || '');
|
||||
|
||||
// let recognizers: { [key: string]: LuisRecognizer } = {};
|
||||
for (var luFile of luFiles) {
|
||||
let dialogFile = path.join(<string>config.folder, path.basename(luFile, '.lu') + '.dialog');
|
||||
let recognizer = await LuisRecognizer.load(dialogFile);
|
||||
if (recognizer.applicationId == null) {
|
||||
// create the application
|
||||
let culture = recognizer.getCulture();
|
||||
let name = `${config.name}-${config.environment}-${config.region}-${culture}-${rootFile}.lu`;
|
||||
console.log(`creating application: ${name}`)
|
||||
let response = await client.apps.add(<AzureRegions>config.region,
|
||||
<AzureClouds>"com", {
|
||||
"name": name,
|
||||
"description": `Model for ${config.name} app, targetting ${config.environment} for ${rootFile}.lu file`,
|
||||
"culture": recognizer.getCulture(),
|
||||
"usageScenario": "",
|
||||
"domain": "",
|
||||
"initialVersionId": "0000000000"
|
||||
}, {});
|
||||
recognizer.applicationId = response.body;
|
||||
recognizer.endpoint = `https://${config.region}.api.cognitive.microsoft.com/`;
|
||||
await recognizer.save();
|
||||
} else {
|
||||
await updateModel(config, client, luFiles, recognizer);
|
||||
}
|
||||
let environmentFolder = path.join(<string>config.folder, <string>config.environment);
|
||||
if (!await fs.exists(environmentFolder)) {
|
||||
await fs.createDirectory(environmentFolder);
|
||||
}
|
||||
|
||||
let recognizersToPublish: LuisRecognizer[] = [];
|
||||
let apps = await client.apps.list(<AzureRegions>config.authoringRegion, <AzureClouds>"com");
|
||||
|
||||
for (var luFile of luFiles) {
|
||||
let culture = getCultureFromPath(luFile);
|
||||
|
||||
let name = `${config.name}-${config.environment}-${config.authoringRegion}-${culture}-${rootFile}.lu`;
|
||||
let dialogFile = path.join(environmentFolder, path.basename(luFile) + '.dialog');
|
||||
let recognizer = await LuisRecognizer.load(luFile, dialogFile);
|
||||
|
||||
if (recognizer.applicationId == null) {
|
||||
for (let app of apps) {
|
||||
if (app.name == name) {
|
||||
recognizer.applicationId = <string>app.id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let appInfo: AppsGetResponse;
|
||||
try {
|
||||
// get app info
|
||||
appInfo = await client.apps.get(<AzureRegions>config.authoringRegion, <AzureClouds>"com", <string>recognizer.applicationId);
|
||||
} catch (err) {
|
||||
// create the application
|
||||
await createApplication(name, client, config, rootFile, culture, recognizer);
|
||||
|
||||
appInfo = await client.apps.get(<AzureRegions>config.authoringRegion, <AzureClouds>"com", <string>recognizer.applicationId );
|
||||
}
|
||||
|
||||
recognizer.versionId = appInfo.activeVersion;
|
||||
|
||||
let training = await updateModel(config, client, recognizer, appInfo);
|
||||
if (training) {
|
||||
recognizersToPublish.push(recognizer);
|
||||
}
|
||||
await recognizer.save();
|
||||
}
|
||||
|
||||
// wait for training to complete and publish
|
||||
for (let recognizer of recognizersToPublish) {
|
||||
await publishModel(config, client, recognizer);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
async function updateModel(config: IConfig, client: LuisAuthoring, luFiles: string[], recognizer: LuisRecognizer) {
|
||||
async function createApplication(name: string, client: LuisAuthoring, config: IConfig, rootFile: string, culture: string, recognizer: LuisRecognizer): Promise<AppsAddResponse> {
|
||||
console.log(`${name} creating version:0000000000`);
|
||||
let response = await client.apps.add(<AzureRegions>config.authoringRegion, <AzureClouds>"com", {
|
||||
"name": name,
|
||||
"description": `Model for ${config.name} app, targetting ${config.environment} for ${rootFile}.lu file`,
|
||||
"culture": culture,
|
||||
"usageScenario": "",
|
||||
"domain": "",
|
||||
"initialVersionId": "0000000000"
|
||||
}, {});
|
||||
recognizer.applicationId = response.body;
|
||||
await recognizer.save();
|
||||
await delay(1000);
|
||||
return response;
|
||||
}
|
||||
|
||||
// get app info
|
||||
let appInfo = await client.apps.get(<AzureRegions>config.region, <AzureClouds>"com", recognizer.applicationId || '');
|
||||
// returns true if it needs to be trained and published
|
||||
async function updateModel(config: IConfig, client: LuisAuthoring, recognizer: LuisRecognizer, appInfo: AppsGetResponse): Promise<boolean> {
|
||||
|
||||
// get activeVersion
|
||||
//let activeVersion = await client.versions.exportMethod(<AzureRegions>config.region, <AzureClouds>"com", recognizer.applicationId || '', appInfo.activeVersion || '');
|
||||
var activeVersionInfo = await client.versions.get(<AzureRegions>config.region, <AzureClouds>"com", recognizer.applicationId || '', appInfo.activeVersion || '');
|
||||
var activeVersionInfo = await client.versions.get(<AzureRegions>config.authoringRegion, <AzureClouds>"com", recognizer.applicationId || '', appInfo.activeVersion || '');
|
||||
await delay(1000);
|
||||
|
||||
let luFile = recognizer.getLuFile(luFiles);
|
||||
let luFile = recognizer.getLuFile();
|
||||
|
||||
var stats = await fs.stat(<string>luFile);
|
||||
|
||||
// if different, then update
|
||||
if (activeVersionInfo && <Date>activeVersionInfo.lastModifiedDateTime < stats.mtime) {
|
||||
console.log(`${luFile} changed`);
|
||||
if (config.force || recognizer.versionId == "0000000000" ||
|
||||
(activeVersionInfo && <Date>activeVersionInfo.lastModifiedDateTime < stats.mtime)) {
|
||||
console.log(`${luFile} updating`);
|
||||
let outFile = luFile + ".json";
|
||||
|
||||
// run ludown on file
|
||||
await runCommand(`ludown parse ToLuis --in ${luFile} --out ${outFile}`);
|
||||
let newJson = await txtfile.read(outFile);
|
||||
// await fs.delete(outFile);
|
||||
await fs.delete(outFile);
|
||||
|
||||
let newVersion = <LuisApp>JSON.parse(newJson);
|
||||
newVersion.name = appInfo.name;
|
||||
|
@ -208,47 +256,83 @@ async function updateModel(config: IConfig, client: LuisAuthoring, luFiles: stri
|
|||
// increment version
|
||||
let newVersionId = pad(parseInt(<string>appInfo.activeVersion) + 1, 10);
|
||||
newVersion.versionId = newVersionId;
|
||||
recognizer.versionId = newVersionId;
|
||||
|
||||
// import new version
|
||||
console.log(`${luFile} creating new version=${newVersionId}`);
|
||||
await client.versions.importMethod(<AzureRegions>config.region, <AzureClouds>"com", <string>recognizer.applicationId, newVersion, { versionId: newVersionId });
|
||||
console.log(`${luFile} creating version=${newVersionId}`);
|
||||
await client.versions.importMethod(<AzureRegions>config.authoringRegion, <AzureClouds>"com", <string>recognizer.applicationId, newVersion, { versionId: newVersionId });
|
||||
// console.log(JSON.stringify(importResult.body));
|
||||
await delay(1000);
|
||||
|
||||
// train the version
|
||||
console.log(`${luFile} training new version=${newVersionId}`);
|
||||
let trainResult = await client.train.trainVersion(<AzureRegions>config.region, <AzureClouds>"com", recognizer.applicationId || '', newVersionId);
|
||||
console.log(`${luFile} training version=${newVersionId}`);
|
||||
await client.train.trainVersion(<AzureRegions>config.authoringRegion, <AzureClouds>"com", recognizer.applicationId || '', newVersionId);
|
||||
|
||||
if (trainResult.status == 'Queued') {
|
||||
let done = true;
|
||||
do {
|
||||
await delay(1000);
|
||||
let trainingStatus = await client.train.getStatus(<AzureRegions>config.region, <AzureClouds>"com", recognizer.applicationId || '', newVersionId);
|
||||
recognizer.save();
|
||||
|
||||
done = true;
|
||||
for (let status of trainingStatus) {
|
||||
if (status.details) {
|
||||
if (status.details.status == 'InProgress') {
|
||||
done = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (!done);
|
||||
}
|
||||
|
||||
// publish the version
|
||||
console.log(`${luFile} publishing new version=${newVersionId}`);
|
||||
let publishResult = await client.apps.publish(<AzureRegions>config.region, <AzureClouds>"com", recognizer.applicationId || '',
|
||||
{
|
||||
"versionId": newVersionId,
|
||||
"isStaging": false
|
||||
});
|
||||
console.log(JSON.stringify(publishResult));
|
||||
await delay(1000);
|
||||
return true;
|
||||
} else {
|
||||
console.log(`${luFile} no changes`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
async function publishModel(config: IConfig, client: LuisAuthoring, recognizer: LuisRecognizer): Promise<void> {
|
||||
process.stdout.write(`${recognizer.getLuFile()} waiting for training for version=${recognizer.versionId}...`);
|
||||
let done = true;
|
||||
do {
|
||||
await delay(5000);
|
||||
await process.stdout.write('.');
|
||||
let trainingStatus = await client.train.getStatus(<AzureRegions>config.authoringRegion, <AzureClouds>"com", recognizer.applicationId || '', <string>recognizer.versionId);
|
||||
|
||||
done = true;
|
||||
for (let status of trainingStatus) {
|
||||
if (status.details) {
|
||||
if (status.details.status == 'InProgress') {
|
||||
done = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (!done);
|
||||
process.stdout.write('done\n');
|
||||
|
||||
// publish the version
|
||||
console.log(`${recognizer.getLuFile()} publishing version=${recognizer.versionId}`);
|
||||
await client.apps.publish(<AzureRegions>config.authoringRegion, <AzureClouds>"com", recognizer.applicationId || '',
|
||||
{
|
||||
"versionId": <string>recognizer.versionId,
|
||||
"isStaging": false
|
||||
});
|
||||
|
||||
console.log(`${recognizer.getLuFile()} finished`);
|
||||
}
|
||||
|
||||
function getCultureFromPath(file: string): string {
|
||||
let fn = path.basename(file, '.lu');
|
||||
let lang = path.extname(fn).substring(1);
|
||||
switch (lang.toLowerCase()) {
|
||||
case 'en-us':
|
||||
case 'zh-cn':
|
||||
case 'nl-nl':
|
||||
case 'fr-fr':
|
||||
case 'fr-ca':
|
||||
case 'de-de':
|
||||
case 'it-it':
|
||||
case 'ja-jp':
|
||||
case 'ko-kr':
|
||||
case 'pt-br':
|
||||
case 'es-es':
|
||||
case 'es-mx':
|
||||
case 'tr-tr':
|
||||
return lang;
|
||||
default:
|
||||
return 'en-us';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function pad(num: number, size: number) {
|
||||
return ('000000000000000' + num).substr(-size);
|
||||
}
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
> Intent and entity definitions for book table scenario
|
||||
> Check out https://github.com/Microsoft/botbuilder-tools/tree/master/packages/Ludown to learn more about .lu files and Ludown.
|
||||
|
||||
# Book Table
|
||||
- book a table
|
||||
- i would like to book a table
|
||||
- book a table for 3
|
||||
- book a table for 2 in redmond store for next thursday at 3pm
|
||||
- book a table for 3 guests in seattle
|
||||
- book a table for next thursday at 3pm please
|
||||
- book a table for 3 guests near microsoft for next thursday at 3pm
|
||||
- can you book a table for 3 guests?
|
||||
- get me a table for next wednesday
|
||||
- book a table at seatac
|
||||
- can you please book a table for 2 guests for this weekend?
|
||||
- get a table for next thursday
|
||||
- reserve a table for 4 at SEA
|
||||
- can you get me a table
|
||||
- please help reserve a table for 5
|
||||
- can i get a table for this sunday at seattle?
|
||||
- need a table in redmond
|
||||
- I need to reserve a table
|
||||
- I need to make a reservation
|
||||
- I need to reserve a table for 2 in Seattle
|
||||
- book a table for 2 in seattle
|
||||
|
Двоичные данные
packages/lubuild/test/deleted/index
Двоичные данные
packages/lubuild/test/deleted/index
Двоичный файл не отображается.
|
@ -0,0 +1,4 @@
|
|||
# YoCarlos
|
||||
- buenos dias carlos!
|
||||
- buenos noches carlos!
|
||||
- buenos tardes carlos!
|
|
@ -0,0 +1,2 @@
|
|||
# YoCarlos
|
||||
- bon jour carlos!
|
|
@ -0,0 +1,3 @@
|
|||
# YoCarlos
|
||||
- hey carlos!
|
||||
- yo carlos!
|
|
@ -1,128 +0,0 @@
|
|||
{
|
||||
"intents": [
|
||||
{
|
||||
"name": "Book Table"
|
||||
}
|
||||
],
|
||||
"entities": [],
|
||||
"composites": [],
|
||||
"closedLists": [],
|
||||
"regex_entities": [],
|
||||
"model_features": [],
|
||||
"regex_features": [],
|
||||
"utterances": [
|
||||
{
|
||||
"text": "Einen Tisch reservieren",
|
||||
"intent": "Book Table",
|
||||
"entities": []
|
||||
},
|
||||
{
|
||||
"text": "Ich möchte einen Tisch reservieren",
|
||||
"intent": "Book Table",
|
||||
"entities": []
|
||||
},
|
||||
{
|
||||
"text": "Buchen Sie einen Tisch für 3",
|
||||
"intent": "Book Table",
|
||||
"entities": []
|
||||
},
|
||||
{
|
||||
"text": "Buchen Sie einen Tisch für 2 Personen im Redmond-Geschäft für den nächsten Donnerstag um 15 Uhr",
|
||||
"intent": "Book Table",
|
||||
"entities": []
|
||||
},
|
||||
{
|
||||
"text": "Buchen Sie einen Tisch für 3 Gäste in Seattle",
|
||||
"intent": "Book Table",
|
||||
"entities": []
|
||||
},
|
||||
{
|
||||
"text": "Buchen Sie einen Tisch für den nächsten Donnerstag um 15 Uhr",
|
||||
"intent": "Book Table",
|
||||
"entities": []
|
||||
},
|
||||
{
|
||||
"text": "Buchen Sie einen Tisch für 3 Gäste in der Nähe von microsoft für den nächsten Donnerstag um 15 Uhr",
|
||||
"intent": "Book Table",
|
||||
"entities": []
|
||||
},
|
||||
{
|
||||
"text": "Können Sie einen Tisch für 3 Gäste buchen?",
|
||||
"intent": "Book Table",
|
||||
"entities": []
|
||||
},
|
||||
{
|
||||
"text": "Mich einen Tisch für den nächsten Mittwoch",
|
||||
"intent": "Book Table",
|
||||
"entities": []
|
||||
},
|
||||
{
|
||||
"text": "Buchen Sie einen Tisch im seatac",
|
||||
"intent": "Book Table",
|
||||
"entities": []
|
||||
},
|
||||
{
|
||||
"text": "Können Sie bitte einen Tisch für 2 Gäste für dieses Wochenende buchen?",
|
||||
"intent": "Book Table",
|
||||
"entities": []
|
||||
},
|
||||
{
|
||||
"text": "Einen Tisch für den nächsten Donnerstag",
|
||||
"intent": "Book Table",
|
||||
"entities": []
|
||||
},
|
||||
{
|
||||
"text": "Reservieren Sie einen Tisch für 4 bei SEA",
|
||||
"intent": "Book Table",
|
||||
"entities": []
|
||||
},
|
||||
{
|
||||
"text": "Können Sie mir einen Tisch besortigen",
|
||||
"intent": "Book Table",
|
||||
"entities": []
|
||||
},
|
||||
{
|
||||
"text": "Bitte helfen Sie, einen Tisch für 5 zu reservieren",
|
||||
"intent": "Book Table",
|
||||
"entities": []
|
||||
},
|
||||
{
|
||||
"text": "Kann ich einen Tisch für diesen Sonntag in der Seefattle bekommen?",
|
||||
"intent": "Book Table",
|
||||
"entities": []
|
||||
},
|
||||
{
|
||||
"text": "Brauchen Sie einen Tisch in redmond",
|
||||
"intent": "Book Table",
|
||||
"entities": []
|
||||
},
|
||||
{
|
||||
"text": "Ich muss einen Tisch reservieren",
|
||||
"intent": "Book Table",
|
||||
"entities": []
|
||||
},
|
||||
{
|
||||
"text": "Ich muss reservieren",
|
||||
"intent": "Book Table",
|
||||
"entities": []
|
||||
},
|
||||
{
|
||||
"text": "Ich muss einen Tisch für 2 in Seattle reservieren",
|
||||
"intent": "Book Table",
|
||||
"entities": []
|
||||
},
|
||||
{
|
||||
"text": "Buchen Sie einen Tisch für 2 in Seattle",
|
||||
"intent": "Book Table",
|
||||
"entities": []
|
||||
}
|
||||
],
|
||||
"patterns": [],
|
||||
"patternAnyEntities": [],
|
||||
"prebuiltEntities": [],
|
||||
"luis_schema_version": "3.0.0",
|
||||
"versionId": "0.1",
|
||||
"name": "test",
|
||||
"desc": "",
|
||||
"culture": "en-us"
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
> Intent and entity definitions for book table scenario
|
||||
> Check out https://github.com/Microsoft/botbuilder-tools/tree/master/packages/Ludown to learn more about .lu files and Ludown.
|
||||
|
||||
# Book Table
|
||||
- Einen Tisch reservieren
|
||||
- Ich möchte einen Tisch reservieren
|
||||
- Buchen Sie einen Tisch für 3
|
||||
- Buchen Sie einen Tisch für 2 Personen im Redmond-Geschäft für den nächsten Donnerstag um 15 Uhr
|
||||
- Buchen Sie einen Tisch für 3 Gäste in Seattle
|
||||
- Buchen Sie einen Tisch für den nächsten Donnerstag um 15 Uhr
|
||||
- Buchen Sie einen Tisch für 3 Gäste in der Nähe von microsoft für den nächsten Donnerstag um 15 Uhr
|
||||
- Können Sie einen Tisch für 3 Gäste buchen?
|
||||
- Mich einen Tisch für den nächsten Mittwoch
|
||||
- Buchen Sie einen Tisch im seatac
|
||||
- Können Sie bitte einen Tisch für 2 Gäste für dieses Wochenende buchen?
|
||||
- Einen Tisch für den nächsten Donnerstag
|
||||
- Reservieren Sie einen Tisch für 4 bei SEA
|
||||
- Können Sie mir einen Tisch besortigen
|
||||
- Bitte helfen Sie, einen Tisch für 5 zu reservieren
|
||||
- Kann ich einen Tisch für diesen Sonntag in der Seefattle bekommen?
|
||||
- Brauchen Sie einen Tisch in redmond
|
||||
- Ich muss einen Tisch reservieren
|
||||
- Ich muss reservieren
|
||||
- Ich muss einen Tisch für 2 in Seattle reservieren
|
||||
- Buchen Sie einen Tisch für 2 in Seattle
|
||||
|
||||
|
|
@ -2,25 +2,4 @@
|
|||
> Check out https://github.com/Microsoft/botbuilder-tools/tree/master/packages/Ludown to learn more about .lu files and Ludown.
|
||||
|
||||
# Book Table
|
||||
- book a table
|
||||
- i would like to book a table
|
||||
- book a table for 3
|
||||
- book a table for 2 in redmond store for next thursday at 3pm
|
||||
- book a table for 3 guests in seattle
|
||||
- book a table for next thursday at 3pm please
|
||||
- book a table for 3 guests near microsoft for next thursday at 3pm
|
||||
- can you book a table for 3 guests?
|
||||
- get me a table for next wednesday
|
||||
- book a table at seatac
|
||||
- can you please book a table for 2 guests for this weekend?
|
||||
- get a table for next thursday
|
||||
- reserve a table for 4 at SEA
|
||||
- can you get me a table
|
||||
- please help reserve a table for 5
|
||||
- can i get a table for this sunday at seattle?
|
||||
- need a table in redmond
|
||||
- I need to reserve a table
|
||||
- I need to make a reservation
|
||||
- I need to reserve a table for 2 in Seattle
|
||||
- book a table for 2 in seattle
|
||||
- book a book a book a table
|
||||
- Book a table
|
||||
|
|
|
@ -1,133 +0,0 @@
|
|||
{
|
||||
"intents": [
|
||||
{
|
||||
"name": "Book Table"
|
||||
}
|
||||
],
|
||||
"entities": [],
|
||||
"composites": [],
|
||||
"closedLists": [],
|
||||
"regex_entities": [],
|
||||
"model_features": [],
|
||||
"regex_features": [],
|
||||
"utterances": [
|
||||
{
|
||||
"text": "book a table",
|
||||
"intent": "Book Table",
|
||||
"entities": []
|
||||
},
|
||||
{
|
||||
"text": "i would like to book a table",
|
||||
"intent": "Book Table",
|
||||
"entities": []
|
||||
},
|
||||
{
|
||||
"text": "book a table for 3",
|
||||
"intent": "Book Table",
|
||||
"entities": []
|
||||
},
|
||||
{
|
||||
"text": "book a table for 2 in redmond store for next thursday at 3pm",
|
||||
"intent": "Book Table",
|
||||
"entities": []
|
||||
},
|
||||
{
|
||||
"text": "book a table for 3 guests in seattle",
|
||||
"intent": "Book Table",
|
||||
"entities": []
|
||||
},
|
||||
{
|
||||
"text": "book a table for next thursday at 3pm please",
|
||||
"intent": "Book Table",
|
||||
"entities": []
|
||||
},
|
||||
{
|
||||
"text": "book a table for 3 guests near microsoft for next thursday at 3pm",
|
||||
"intent": "Book Table",
|
||||
"entities": []
|
||||
},
|
||||
{
|
||||
"text": "can you book a table for 3 guests?",
|
||||
"intent": "Book Table",
|
||||
"entities": []
|
||||
},
|
||||
{
|
||||
"text": "get me a table for next wednesday",
|
||||
"intent": "Book Table",
|
||||
"entities": []
|
||||
},
|
||||
{
|
||||
"text": "book a table at seatac",
|
||||
"intent": "Book Table",
|
||||
"entities": []
|
||||
},
|
||||
{
|
||||
"text": "can you please book a table for 2 guests for this weekend?",
|
||||
"intent": "Book Table",
|
||||
"entities": []
|
||||
},
|
||||
{
|
||||
"text": "get a table for next thursday",
|
||||
"intent": "Book Table",
|
||||
"entities": []
|
||||
},
|
||||
{
|
||||
"text": "reserve a table for 4 at SEA",
|
||||
"intent": "Book Table",
|
||||
"entities": []
|
||||
},
|
||||
{
|
||||
"text": "can you get me a table",
|
||||
"intent": "Book Table",
|
||||
"entities": []
|
||||
},
|
||||
{
|
||||
"text": "please help reserve a table for 5",
|
||||
"intent": "Book Table",
|
||||
"entities": []
|
||||
},
|
||||
{
|
||||
"text": "can i get a table for this sunday at seattle?",
|
||||
"intent": "Book Table",
|
||||
"entities": []
|
||||
},
|
||||
{
|
||||
"text": "need a table in redmond",
|
||||
"intent": "Book Table",
|
||||
"entities": []
|
||||
},
|
||||
{
|
||||
"text": "I need to reserve a table",
|
||||
"intent": "Book Table",
|
||||
"entities": []
|
||||
},
|
||||
{
|
||||
"text": "I need to make a reservation",
|
||||
"intent": "Book Table",
|
||||
"entities": []
|
||||
},
|
||||
{
|
||||
"text": "I need to reserve a table for 2 in Seattle",
|
||||
"intent": "Book Table",
|
||||
"entities": []
|
||||
},
|
||||
{
|
||||
"text": "book a table for 2 in seattle",
|
||||
"intent": "Book Table",
|
||||
"entities": []
|
||||
},
|
||||
{
|
||||
"text": "book a book a book a table",
|
||||
"intent": "Book Table",
|
||||
"entities": []
|
||||
}
|
||||
],
|
||||
"patterns": [],
|
||||
"patternAnyEntities": [],
|
||||
"prebuiltEntities": [],
|
||||
"luis_schema_version": "3.0.0",
|
||||
"versionId": "0.1",
|
||||
"name": "test",
|
||||
"desc": "",
|
||||
"culture": "en-us"
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"rootDir": "./src", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
|
||||
"alwaysStrict": true,
|
||||
"noImplicitAny": true,
|
||||
"preserveConstEnums": true,
|
||||
|
@ -15,7 +16,7 @@
|
|||
"strict": true,
|
||||
"strictNullChecks": true,
|
||||
"module": "commonjs",
|
||||
"outDir": "./lib",
|
||||
"outDir": "./bin",
|
||||
"declaration": true,
|
||||
"declarationDir": "./typings/lib",
|
||||
"lib": [ "dom", "dom.iterable", "es5", "es6", "es7", "esnext", "esnext.asynciterable", "es2015.iterable"]
|
||||
|
@ -25,6 +26,6 @@
|
|||
"node_modules"
|
||||
],
|
||||
"include": [
|
||||
"./src/**/*.ts"
|
||||
"./src/**/*.ts", "bin/help.ts"
|
||||
]
|
||||
}
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
export interface IBuildArgs {
|
||||
help: boolean;
|
||||
name: string;
|
||||
environment: string | null;
|
||||
authoringKey: string | null;
|
||||
region: string | null;
|
||||
config: string | null;
|
||||
environment: string | undefined;
|
||||
authoringKey: string | undefined;
|
||||
authoringRegion: string | undefined;
|
||||
config: string | undefined;
|
||||
multilingual: boolean;
|
||||
autodelete: boolean;
|
||||
production: boolean;
|
||||
folder: string | null;
|
||||
folder: string | undefined;
|
||||
force: boolean;
|
||||
}
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
export declare class LuisRecognizer {
|
||||
private dialogPath;
|
||||
constructor();
|
||||
static load(dialogPath: string): Promise<LuisRecognizer>;
|
||||
private luFile;
|
||||
constructor(luFile: string);
|
||||
static load(luFile: string, dialogPath: string): Promise<LuisRecognizer>;
|
||||
save(): Promise<void>;
|
||||
getCloud(): string | null;
|
||||
getRegion(): string | null;
|
||||
getCulture(): string;
|
||||
getFileName(): string;
|
||||
getLuFile(files: string[]): string | null;
|
||||
applicationId: string | null;
|
||||
endpoint: string | null;
|
||||
endpointKey: string | null;
|
||||
getLuFile(): string;
|
||||
applicationId: string | undefined;
|
||||
versionId: string | undefined;
|
||||
endpoint: string | undefined;
|
||||
endpointKey: string | undefined;
|
||||
}
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
#!/usr/bin/env node
|
||||
export {};
|
||||
|
|
Загрузка…
Ссылка в новой задаче