|
| 1 | +# Lubuild -> bf luis:build |
| 2 | + |
| 3 | +Lubuild is a preview CLI tool available in [botbuilder-tools repository][1]. As part of the migration of botbuilder-tools to BF-CLI, the **core** functionality of the existing lubuild tool will be brought forward to BF-CLI as |
| 4 | + |
| 5 | +- [P0] library that can be used by bot framework composer and/ or other tools that need such capability |
| 6 | +- [P0] exposed as a CLI command under the `luis:` command group as part of BF-CLI. |
| 7 | + |
| 8 | +## Functional requirements |
| 9 | +1. Given an .lu files that describes one luis application and a [luis-configuration](#LUIS-configuration), |
| 10 | + - (a) Find a matching LUIS application. |
| 11 | + - (b) If found uploads new model definition (as defined in .lu file) as new version. |
| 12 | + - (c) Else Create a new LUIS application with the model definition (as defined in .lu file. This is the functional equivalent of `import application` command. |
| 13 | + - (d) Train and publish the new application. |
| 14 | +2. Given a collection of .lu files that describe one luis application across one or more supported [luis locales][2] and a [luis-configuration](#LUIS-configuration), |
| 15 | + - For each locale, do 1.a - 1.d |
| 16 | +3. LUIS supports up to 5 concurrent authoring API calls and up to 5 calls per second to the service per authoring key. The library should leverage this capability as a performance optimization and parallelize calls up to 5 applications (each .lu content is an application). Note that for each .lu content, we might need to do either create/ import followed by train and then publish. We cannot parallelize calls within that workflow but can parallelize across applications. |
| 17 | + - Failures on any calls to LUIS should automatically initiate a wait-retry loop for up to 5 times. Repeat failures should be reported back with the actual error message from the service and the corresponding LU content (file name/ content itself). |
| 18 | +4. To determine if an application exists, we should use the following order of precedence. This is applicable for #1.a-c above to determine if an application exists already or we should create a new application - |
| 19 | + - (a) If the .lu file has a @app.name property, we should use that as the app name to find. **.OR.** |
| 20 | + - (b) Find an application with the following naming convention - \<BotName>(\<environment>)-\<luFileNameOrId>.\<locale>.lu |
| 21 | +5. To determine if a new version needs to be created, we will |
| 22 | + - (a) Get the latest published application version (to either PRODCUTION or STAGING) via call to [Get application info][3] |
| 23 | + - (b) export the version via call to [Export application version][4] |
| 24 | + - (c) [Transform][5] and perform a diff against the current LU JSON .vs. what's in latest version. Create a new version if the content is different or no content exists. |
| 25 | +6. If [luis-configuration](#LUIS-configuration) requests .dialog files be generated, then generate .dialog files with the newly created/ updated LUIS application information. See [dialog-files](#dialog-files) to learn more about the logic for creating .dialog and related files. |
| 26 | + |
| 27 | +## Locale naming conventions |
| 28 | +When the CLI route is attempting to infer the locale from the file name, we should expect the file names to be in this convention - |
| 29 | +\<fileName>.\<locale>.lu |
| 30 | + |
| 31 | +\<locale> must be one of the supported [luis locales][2]. |
| 32 | + |
| 33 | +## Version naming conventions |
| 34 | +- When creating a new application, version the application as `0.1` |
| 35 | +- When creating a new version, use the following order of precedence - |
| 36 | + - use @app.versionId if present in the LU content. |
| 37 | + - increment the application minor version by 1. So versions would be named as 0.1, 0.2, 0.3, 0.4, ... |
| 38 | + - If the prior version is not a number, then add -0.1, -0.2, -0.3 ... as a **suffix**. E.g. Initial version - `myversion` -> `myversion-0.1` -> `myversion-0.2` -> ... |
| 39 | + |
| 40 | +## LUIS configuration |
| 41 | +1. Location of the .lu file (absolute or relative path or file content via stdin for CLI) |
| 42 | +2. LUIS authoring key to use |
| 43 | +3. Bot name (text property that can be set to e.g. `WeatherBot`, `HRBot` etc). |
| 44 | +4. [Optional] Default language - identifies .lu file's base language when a lang code is not explicitly included. |
| 45 | +4. [Optional] LUIS authoring region to use. Defaults to `westus` |
| 46 | +5. [Optional] environment name (text property that can be set to e.g. `dev`, `staging`, `production`). Defaults to `development` |
| 47 | +6. [Optional] Output folder name to write out .dialog files generated. Defaults to `cwd()` |
| 48 | +7. [Optional] --dialog field to request that .dilog files be written out. Defaults to `false` |
| 49 | + |
| 50 | +## CLI Command |
| 51 | + |
| 52 | +`bf luis:build` |
| 53 | + |
| 54 | +| Parameters | Description | |
| 55 | +|-------------------|-------------------------------------------------------------------------------------------------------------------------| |
| 56 | +| --in | lu file or folder | |
| 57 | +| --force | [optional] force write | |
| 58 | +| --authoringkey | LUIS authoring key | |
| 59 | +| --botname | bot name | |
| 60 | +| --out | [Optional] output location | |
| 61 | +| --culture | [Optional] culture code for the content. Infer from .lu if available. Defaults to `en-us` | |
| 62 | +| --region | [Optional] LUIS authoring region | |
| 63 | +| --suffix | [Optional] environment name as a suffix identifier to include in LUIS app name | |
| 64 | +| --dialog | [Optional] write out .dialog files | |
| 65 | +| --fallbacklocale | [Optional] locale to be used at the fall back if no locale specific recognizer is found. Only valid if --dialog is set. | |
| 66 | + |
| 67 | + |
| 68 | +<a id="dialog-files"></a> |
| 69 | + |
| 70 | +## Writing out .dialog files |
| 71 | +All up:luis.settings.\<environmentname>.\<region>.json |
| 72 | +```json |
| 73 | +{ |
| 74 | + "luis": { |
| 75 | + "<lufilename>_<locale>_lu": "<LUIS app id>" |
| 76 | + } |
| 77 | +} |
| 78 | +``` |
| 79 | +For each LU file: |
| 80 | +\<lufilename>_\<locale>.dialog |
| 81 | +```json |
| 82 | +{ |
| 83 | + "$type": "Microsoft.LuisRecognizer", |
| 84 | + "applicationId": "{settings.luis.Main_en-us_lu}", |
| 85 | + "endpoint": "{settings.luis.endpoint}", |
| 86 | + "endpointKey": "{settings.luis.endpointKey}" |
| 87 | +} |
| 88 | +``` |
| 89 | + |
| 90 | +\<lufilename>.lu.dialog |
| 91 | +```json |
| 92 | +{ |
| 93 | + "$type": "Microsoft.MultiLanguageRecognizer", |
| 94 | + "recognizers": { |
| 95 | + "<locale>": "<lufilename>.<locale>.lu", |
| 96 | + "": "<lufilename>.<fallbacklocale>.lu" |
| 97 | + } |
| 98 | +} |
| 99 | +``` |
| 100 | + |
| 101 | +## Interfaces |
| 102 | + |
| 103 | +```ts |
| 104 | +export class LuBuild { |
| 105 | + public luConfig:LUISConfig; |
| 106 | + |
| 107 | + public static async CreateOrUpdateApplication(luConfig:LUISConfig, delegate:(ID:string) : Content) : Promise<List<LUISApps>> { |
| 108 | + return new Array<LuBuildResult>(); |
| 109 | + } |
| 110 | + |
| 111 | + public async GenerateDeclarativeAssets(LuisAppList:List<LUISApps>):Promise<Array<DialogFileContent>>; |
| 112 | +}; |
| 113 | + |
| 114 | +export class DialogFileContent { |
| 115 | + public LuisSettingsContent:string; |
| 116 | + public PerLUFileContent:Array<Content>; |
| 117 | +} |
| 118 | + |
| 119 | +export class LUISApps { |
| 120 | + public srcID:string; |
| 121 | + public LuisAppId:string; |
| 122 | + public LuisVersionId:string; |
| 123 | + public LuisLocale:string; |
| 124 | +} |
| 125 | + |
| 126 | +export class Content { |
| 127 | + public id:string; |
| 128 | + public content:string; |
| 129 | + public locale:string; |
| 130 | + public name:string; // defaults to "<id>.<locale>.lu" |
| 131 | +}; |
| 132 | + |
| 133 | +export class LUISConfig { |
| 134 | + public AuthoringKey:string; |
| 135 | + public BotName:string; |
| 136 | + public Culture:string = 'en-us'; |
| 137 | + public AuthoringRegion:string = 'westus'; |
| 138 | + public EnvironmentName:string = 'dev'; |
| 139 | + public GenerateDialogFileContent:boolean = false; |
| 140 | + public FallBackLocale:string = 'en-us'; |
| 141 | + public LuContent:Array<Content>; |
| 142 | +}; |
| 143 | +``` |
| 144 | + |
| 145 | +[1]:https://github.com/microsoft/botbuilder-tools/tree/V.Future/packages/lubuild |
| 146 | +[2]:https://docs.microsoft.com/en-us/azure/cognitive-services/luis/luis-language-support#languages-supported |
| 147 | +[3]:https://westus.dev.cognitive.microsoft.com/docs/services/5890b47c39e2bb17b84a55ff/operations/5890b47c39e2bb052c5b9c37 |
| 148 | +[4]:https://westus.dev.cognitive.microsoft.com/docs/services/5890b47c39e2bb17b84a55ff/operations/5890b47c39e2bb052c5b9c40 |
| 149 | +[5]:https://github.com/microsoft/botframework-cli/blob/787b11503cfaaaf40e254b7030db242cc1269729/packages/lu/src/parser/lufile/helpers.js#L156 |
0 commit comments