Skip to content
This repository was archived by the owner on Jan 15, 2025. It is now read-only.

Commit 91881c3

Browse files
author
Chris McConnell
authored
Initial check-in of dialog generation. (#353)
* Intermediate check-in before inverting template/prop loops. * Working generator with incomplete templates. * Basic .lu files working. * Update to generate single .lu file. * Fix cli issues. * Fix CLI issues with template resources. * Clean up lint warnings. * Fix lint errors. * Generate composite .lu * Add dialog and multi-language support. * shortcut to debug * Add per-locale .lg file. * Update debug config to use temp directory. Generate multilingual .lg file. * Update to include schema prefix on names. * Fix bugs in .lg genertion. * try help * help and cancel * Copy schema to output directory. * help and cancel version 1 * separate help.lu * several fixes * remove help enum * reset launch.json * remove empty line * Add the ability to copy library dialog files. * Add ability to specify schema and multiple templates. * Rename resources. Support multiple templates. Add *PROPN** pattern. * Fix bug in striingify call. * Generate schema.main.dialog and update config. * Update templates to newest format. * Update templates to match names. * add .dialogs for several basic rules * Update templates to use $ and add begindialog as a hack to work around ada ptive issue. * add .dialogs for several basic rules * fix comments * merge from origin * small changes * Add formCopy cmd file. * Adjust for bug in templates. * fix path * Version 1 of contact.form.dialog * Same info is modeled for both Home and Work. * List of state abbreviations and their spelled-out names are specified in the separate state.en-us.lu, and used in the $mappings specifications. * Latitude and Longitude should be auto-filled if the corresponding address are filled. * Validation patterns are specified for zip codes and phone numbers. * Fixed contact.form.dialog and added activity.form.dialog * contact.form.dialog - Fixed spelling - Use phonenumber prebuilt entity type * activity.form.dialog: the second scenario from Darren "An employee working for a customer wants to add a quick update to a customer record after a call. This update will then be available for other people working with that customer to see". * Added opportunity.form.dialog For Darren's scenario "An employee working with a customer has had a meeting and needs to create a new opportunity." * change names * Revert "change names" This reverts commit 64ffaff. * change names * basic work done for ask, set and help * cancel confirmation * cancel confirmation done, unexpected property set confirmation in progress * improve unexpected property test * Version 1 of contact.form.dialog * Same info is modeled for both Home and Work. * List of state abbreviations and their spelled-out names are specified in the separate state.en-us.lu, and used in the $mappings specifications. * Latitude and Longitude should be auto-filled if the corresponding address are filled. * Validation patterns are specified for zip codes and phone numbers. * Fixed contact.form.dialog and added activity.form.dialog * contact.form.dialog - Fixed spelling - Use phonenumber prebuilt entity type * activity.form.dialog: the second scenario from Darren "An employee working for a customer wants to add a quick update to a customer record after a call. This update will then be available for other people working with that customer to see". * Added opportunity.form.dialog For Darren's scenario "An employee working with a customer has had a meeting and needs to create a new opportunity." * rename state.lu * prebuilt lu templates * remove choose entity we only have chooseProperty and clarifyEntity * Switch to event expected. * Update templates for latest runtime and add ask for multiple properties. * Add **NAMES/**NAME** and generate property names. * fix unexpected property confirmation usage * change unexpected property action from ask to sendactivity * all done confirmation * Update names to support chooseProperty. * Check-in bread value hack. * Fix template bug around clarify. * Update templates to use names and start numbers. * complete the new forms * contextual help * activity schema working fine * add meta info to opportunity schema * opportunity semi-working cannot use phonenumber; properties not in required also got asked; in stringset, default value is not expression, cannot get the value for @email * three schemas working sandwich, activity, opportunity * contact schema working Adding welcome message in beginDialog, Add help message for non-enum properties, All three CDS schemas working * Sync changes for demo. * Before adding mapping templates * Getting close to E2e. * Largely working with some template debugging. * Update the readme. * Update to latest expression and lg packages. Support app schema. * Update standard schema. * Finish merge. * Show metaschema. * Fix readme typo. * several changes (#299) * several changes (1) remove unused old files; (2) change incorrect file names; (3) add string ask templates; (4) remove meta properties from schemas; (5) fix an error in calculating optional properties * fix help property bug * Add string templates. * a few changes (#318) (1) fix the cancel.lu bug (2) add datetime.lu (2) stringSetdatetime.dialog.lg * Add template for not understood. * Connect to bf cli. * Add basic role support. * Nigao/newtemplate (#321) * a few changes (1) fix the cancel.lu bug (2) add datetime.lu (2) stringSetdatetime.dialog.lg * autohelp for new templates * Update to use @{} everywhere and remove auto-help since it required post-ask action. * Nigao/newtemplate (#323) * a few changes (1) fix the cancel.lu bug (2) add datetime.lu (2) stringSetdatetime.dialog.lg * autohelp for new templates * add $requires, and datetime entity sets * add all stringSet for prebuilt entities explicitly * change prebuilt-entity.lu.lg files * Switch to using a triggerIntent instead of none for entities. Cleanup filename expressions. * Fix bug in status. * Switch from dialog:form to dialog:generate * Add top-level documentation. * Update tests to use dialog:generate. * Rename tests to generator. * Fixing linting errors * Generate confirmation card. * Fix reference regex ot not match structured lg.
1 parent be9700a commit 91881c3

File tree

106 files changed

+4889
-2089
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

106 files changed

+4889
-2089
lines changed

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,3 +76,10 @@ tsconfig.tsbuildinfo
7676
packages/dialog/test/commands/dialog/projects/obj/Debug/netcoreapp2.1/LUISGen.csproj.CoreCompileInputs.cache
7777
packages/dialog/test/commands/dialog/projects/obj/Debug/netcoreapp2.1/LUISGen.AssemblyInfo.cs
7878
packages/dialog/test/commands/dialog/projects/obj/Debug/netcoreapp2.1/LUISGen.AssemblyInfoInputs.cache
79+
80+
#generated antlr files
81+
.antlr
82+
packages/dialog/tsconfig.tsbuildinfo
83+
84+
# BuildInfo
85+
tsconfig.tsbuildinfo

packages/cli/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
"dependencies": {
1111
"@microsoft/bf-chatdown": "1.0.0",
1212
"@microsoft/bf-cli-config": "1.0.0",
13+
"@microsoft/bf-dialog": "1.0.0",
1314
"@microsoft/bf-lu": "1.0.0",
1415
"@microsoft/bf-qnamaker": "1.0.0",
1516
"@oclif/command": "~1.5.13",
@@ -62,6 +63,7 @@
6263
"@oclif/plugin-help",
6364
"@microsoft/bf-chatdown",
6465
"@microsoft/bf-cli-config",
66+
"@microsoft/bf-dialog",
6567
"@microsoft/bf-qnamaker",
6668
"@microsoft/bf-lu"
6769
],

packages/dialog/.vscode/launch.json

Lines changed: 110 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,20 @@
44
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
55
"version": "0.2.0",
66
"configurations": [
7+
{
8+
"type": "antlr-debug",
9+
"request": "launch",
10+
"name": "Debug Current Grammar",
11+
"input": "test/commands/dialog/forms/input.txt",
12+
"startRule": "doc",
13+
"visualParseTree": true
14+
},
715
{
816
"type": "node",
917
"request": "launch",
1018
"name": "Dialog Merge Tests",
1119
"program": "${workspaceFolder}/node_modules/mocha/bin/_mocha",
12-
"cwd":"${workspaceFolder}",
20+
"cwd": "${workspaceFolder}",
1321
"args": [
1422
"-u",
1523
"tdd",
@@ -25,7 +33,7 @@
2533
"request": "launch",
2634
"name": "Dialog Verify Tests",
2735
"program": "${workspaceFolder}/node_modules/mocha/bin/_mocha",
28-
"cwd":"${workspaceFolder}",
36+
"cwd": "${workspaceFolder}",
2937
"sourceMaps": false,
3038
"args": [
3139
"-u",
@@ -37,6 +45,22 @@
3745
],
3846
"internalConsoleOptions": "openOnSessionStart"
3947
},
48+
{
49+
"type": "node",
50+
"request": "launch",
51+
"name": "Dialog Generator Tests",
52+
"program": "${workspaceFolder}/node_modules/mocha/bin/_mocha",
53+
"preLaunchTask": "tsc: build - tsconfig.json",
54+
"args": [
55+
"-u",
56+
"tdd",
57+
"--timeout",
58+
"999999",
59+
"--colors",
60+
"${workspaceFolder}/test/commands/dialog/generator.test.ts"
61+
],
62+
"internalConsoleOptions": "openOnSessionStart"
63+
},
4064
{
4165
"type": "node",
4266
"request": "launch",
@@ -51,6 +75,90 @@
5175
"-f",
5276
"c:/source/github/botbuilder-dotnet/**/*.schema"
5377
]
78+
},
79+
{
80+
"type": "node",
81+
"request": "launch",
82+
"name": "Generate Sandwich Form",
83+
"program": "${workspaceFolder}/bin/run",
84+
"preLaunchTask": "tsc: build - tsconfig.json",
85+
"outFiles": [
86+
"${workspaceFolder}/lib/**/*.js"
87+
],
88+
"args": [
89+
"dialog:generate",
90+
"${workspaceFolder}/test/commands/dialog/forms/sandwich.form.dialog",
91+
"-o",
92+
"${env:TEMP}/sandwich.out",
93+
"--force",
94+
"--verbose",
95+
"--schema",
96+
"https://raw.githubusercontent.com/microsoft/botbuilder-dotnet/chrimc/map/schemas/sdk.schema"
97+
],
98+
"internalConsoleOptions": "openOnSessionStart"
99+
},
100+
{
101+
"type": "node",
102+
"request": "launch",
103+
"name": "Generate Activity Form",
104+
"program": "${workspaceFolder}/bin/run",
105+
"preLaunchTask": "tsc: build - tsconfig.json",
106+
"outFiles": [
107+
"${workspaceFolder}/lib/**/*.js"
108+
],
109+
"args": [
110+
"dialog:form",
111+
"${workspaceFolder}/test/commands/dialog/forms/activity.form.dialog",
112+
"-o",
113+
"${env:TEMP}/activity.out",
114+
"--force",
115+
"--verbose",
116+
"--schema",
117+
"https://raw.githubusercontent.com/microsoft/botbuilder-dotnet/chrimc/map/schemas/sdk.schema"
118+
],
119+
"internalConsoleOptions": "openOnSessionStart"
120+
},
121+
{
122+
"type": "node",
123+
"request": "launch",
124+
"name": "Generate Contact Form",
125+
"program": "${workspaceFolder}/bin/run",
126+
"preLaunchTask": "tsc: build - tsconfig.json",
127+
"outFiles": [
128+
"${workspaceFolder}/lib/**/*.js"
129+
],
130+
"args": [
131+
"dialog:form",
132+
"${workspaceFolder}/test/commands/dialog/forms/contact.form.dialog",
133+
"-o",
134+
"${env:TEMP}/contact.out",
135+
"--force",
136+
"--verbose",
137+
"--schema",
138+
"https://raw.githubusercontent.com/microsoft/botbuilder-dotnet/chrimc/map/schemas/sdk.schema"
139+
],
140+
"internalConsoleOptions": "openOnSessionStart"
141+
},
142+
{
143+
"type": "node",
144+
"request": "launch",
145+
"name": "Generate Opportunity Form",
146+
"program": "${workspaceFolder}/bin/run",
147+
"preLaunchTask": "tsc: build - tsconfig.json",
148+
"outFiles": [
149+
"${workspaceFolder}/lib/**/*.js"
150+
],
151+
"args": [
152+
"dialog:form",
153+
"${workspaceFolder}/test/commands/dialog/forms/opportunity.form.dialog",
154+
"-o",
155+
"${env:TEMP}/opportunity.out",
156+
"--force",
157+
"--verbose",
158+
"--schema",
159+
"https://raw.githubusercontent.com/microsoft/botbuilder-dotnet/chrimc/map/schemas/sdk.schema"
160+
],
161+
"internalConsoleOptions": "openOnSessionStart"
54162
}
55163
]
56164
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
undefined

packages/dialog/package.json

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,22 @@
55
"bugs": "https://github.com/microsoft/botframework-cli/issues",
66
"dependencies": {
77
"@microsoft/bf-cli-command": "~1.0.0",
8+
"@types/lru-cache": "^5.1.0",
89
"@types/semver": "^6.0.1",
910
"@types/xml2js": "^0.4.4",
1011
"ajv": "^6.9.1",
12+
"botframework-expressions": "https://botbuilder.myget.org/F/botbuilder-declarative/npm/botframework-expressions/-/4.7.0-preview0.tgz",
13+
"botbuilder-lg": "https://botbuilder.myget.org/F/botbuilder-declarative/npm/botbuilder-lg/-/4.7.0-preview0.tgz",
1114
"chalk": "^2.4.2",
15+
"clone": "^2.1.2",
1216
"fs-extra": "^8.1.0",
1317
"get-json": "^1.0.1",
1418
"globby": "^9.2.0",
1519
"json-schema-merge-allof": "^0.6.0",
1620
"json-schema-ref-parser": "^7.1.0",
17-
"tslib": "^1.10.0",
18-
"clone": "^2.1.2",
21+
"path": "^0.12.7",
1922
"semver": "^5.7.0",
23+
"tslib": "^1.10.0",
2024
"xml2js": "^0.4.19"
2125
},
2226
"devDependencies": {
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*!
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License.
4+
*/
5+
6+
import { Command, flags } from '@microsoft/bf-cli-command';
7+
import * as gen from '../../library/dialogGenerator'
8+
import * as ppath from 'path'
9+
10+
export default class GenerateDialog extends Command {
11+
static description = '[PREVIEW] Generate localized .lu, .lg, .qna and .dialog assets to define a bot based on a schema using templates.'
12+
13+
static examples = [`
14+
$ bf dialog:generate sandwich.schema --output c:/tmp
15+
`]
16+
17+
static args = [
18+
{ name: 'schema', required: true, description: 'JSON Schema file used to drive generation.' }
19+
]
20+
21+
static flags: flags.Input<any> = {
22+
force: flags.boolean({ char: 'f', description: 'Force overwriting generated files.' }),
23+
help: flags.help({ char: 'h' }),
24+
locale: flags.string({ char: 'l', description: 'Locales to generate. [default: en-us]', multiple: true }),
25+
output: flags.string({ char: 'o', description: 'Output path for where to put generated .lu, .lg, .qna and .dialog files. [default: ./<form>-resources]', default: '.', required: false }),
26+
schema: flags.string({ char: 's', description: 'Path to your app.schema file.', required: false }),
27+
templates: flags.string({ char: 't', description: 'Directory with templates to use for generating form assets.', multiple: true }),
28+
verbose: flags.boolean({ description: 'Output verbose logging of files as they are processed', default: false }),
29+
}
30+
31+
async run() {
32+
const { args, flags } = this.parse(GenerateDialog)
33+
try {
34+
let formName = ppath.basename(args.schema, '.schema.dialog')
35+
let outDir = flags.output
36+
if (!outDir) {
37+
outDir = ppath.join(formName + '-resources')
38+
}
39+
await gen.generate(args.schema, outDir, flags.schema, flags.locale, flags.templates, flags.force,
40+
(type, msg) => {
41+
if (type === gen.FeedbackType.message
42+
|| type === gen.FeedbackType.error
43+
|| (type === gen.FeedbackType.info && flags.verbose)) {
44+
this.progress(msg)
45+
}
46+
})
47+
return true;
48+
} catch (e) {
49+
this.thrownError(e)
50+
}
51+
}
52+
53+
thrownError(err: Error): void {
54+
this.error(err.message)
55+
}
56+
57+
progress(msg: string): void {
58+
this.error(msg)
59+
}
60+
}

packages/dialog/src/commands/dialog/merge.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@
66
import { Command, flags } from '@microsoft/bf-cli-command';
77
import * as Validator from 'ajv';
88
import * as fs from 'fs-extra';
9-
import * as getJson from 'get-json';
109
import * as glob from 'globby';
1110
import * as os from 'os';
1211
import * as ppath from 'path';
1312
import * as semver from 'semver';
1413
import * as xp from 'xml2js';
1514
let allof: any = require('json-schema-merge-allof')
1615
let clone = require('clone')
16+
let getJson = require('get-json')
1717
let parser: any = require('json-schema-ref-parser')
1818
let util: any = require('util')
1919
let exec: any = util.promisify(require('child_process').exec)
@@ -40,7 +40,7 @@ export default class DialogMerge extends Command {
4040
verbose: flags.boolean({ description: 'output verbose logging of files as they are processed', default: false }),
4141
}
4242

43-
private verbose = false
43+
private verbose? = false
4444
private failed = false
4545
private missingTypes = new Set()
4646
private currentFile = ''
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# Dialog Commands
2+
3+
# Merge
4+
5+
# Verify
6+
7+
# Form
8+
The form command generates .lu, .lg, .qna and .dialog assets from a schema defined using JSON Schema. The parameters to the command are:
9+
* **--force, -f** Force overwriting generated files.
10+
* **--help, -h** Generate help.
11+
* **--locale, -l** Locales to generate. By default en-us.
12+
* **--output, -o** Output directory.
13+
* **--schema, -s** Path to your app.schema file. By default is the standard SDK app.schema.
14+
* **--templates, -t** Directories with templates to use for generating form assets.
15+
* **--verbose, -v** Verbose logging of generated files.
16+
17+
## Schema
18+
Schemas are specified using JSON Schema. You can use the normal JSON Schema mechanisms including $ref and allOf which will be resolved into a single schema. In addition there are a few extra keywords including:
19+
* **$mappings** List of entity names that can map to a property. The order of the entities also defines the precedence to use when resolving entities. By default the mappings are based on the type:
20+
* **enum**
21+
* **number**, **string**
22+
* **$templates** The template names to use for generating assets. $templates can be defined at the top-level in a schema or per-property which by default are based on the type:
23+
* **enum**
24+
* **number**, **string**
25+
* **\$expectedOnly** A list of properties that are only possible if they are expected.
26+
* **\$requires** A list of JSON Schema to use for internal mechanisms. You can use either actual paths or just the name of the schema to use if found in one of the template directories. The standard schema is `standard.schema.dialog`. The form schema and all of the required schemas will have the top-level `properties`, `definitions`, `required`, `$expectedOnly` and `$templates` merged.
27+
* **\$triggerIntent** Name of the trigger intent or by default the name of the form.
28+
29+
`<form>.form.dialog` will be generated with the form schema in it. `<form>.schema.dialog` will have the whole schema defined.
30+
31+
## Templates
32+
Each entity or property can have associated .lu, .lg, .qna and .dialog files that are generated by
33+
copying or instantiating templates found in the template directories. If a template name matches exactly it is
34+
just copied. If the template ends with .lg then it is analyzed to see if it has a template named 'template' and optionally one named 'filename'. If 'filename' is specified, then the filename will be the result of generating generated file is the result of evaluating that template, otherwise it defaults to `<formName>-<templateName>[.<locale>].<extension>`. When evaluating templates there are a number of variables defined in the scope including:
35+
* **formName** The name of the form being generated.
36+
* **appSchema** The path to the app.schema to use.
37+
* **form** The JSON Schema defining the form.
38+
* **schema** The JSON Schema of the form + internal properties.
39+
* **locales** The list of all locales being generated.
40+
* **properties** All of the form property names.
41+
* **entities** All of the types of schema entities being used.
42+
* **triggerIntent** $triggerIntent or the form name by default.
43+
* **locale** The locale being generated or empty if no locale.
44+
* **property** For per-property templates this the property name being generated.
45+
* **templates** Object with generated templates per lu, lg, qna, json and dialog. The object contains:
46+
* **name** Base name of the template without final extension.
47+
* **fullName** The name of the template including the extension.
48+
* **relative** Path relative to the output directory of where template is.
49+
50+
Templates are generated in the following order:
51+
* Generate per-locale language resources
52+
* Per-entity generate .lg, .lu, .qna files
53+
* Per-property
54+
* Per-template in `<property>.$templates` generate .lg, .lu, .qna files.
55+
* Per-template in `$templates` generate .lg, .lu, .qna files.
56+
* Generate non language resources
57+
* Per-property
58+
* Per-template in `<property>.$templates` generate .dialog and .json files.
59+
* Per-template in `$templates` generate .dialog and .json files.

packages/dialog/src/commands/dialog/verify.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export default class DialogVerify extends Command {
2828
verbose: flags.boolean({ description: 'Show verbose output', default: false }),
2929
}
3030

31-
private currentFile: string
31+
private currentFile = ''
3232
private files = 0
3333
private errors = 0
3434
private warnings = 0

0 commit comments

Comments
 (0)