theprogrammablemind 8.0.0 → 8.1.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client.js +590 -934
- package/index.js +3 -2
- package/package.json +13 -13
- package/src/config.js +285 -259
- package/src/configHelpers.js +455 -0
- package/src/generators.js +8 -8
- package/src/helpers.js +34 -1
- package/src/project.js +1 -1
- package/src/semantics.js +63 -69
package/client.js
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
const { Semantics, Semantic } = require('./src/semantics')
|
2
2
|
const { Generators, Generator } = require('./src/generators')
|
3
|
+
const { Config } = require('./src/config')
|
4
|
+
const { loadInstance, ErrorReason, listable, setupArgs, gs, processContext, getObjects, setupProcessB, processContextsB } = require('./src/configHelpers')
|
3
5
|
const DigraphInternal = require('./src/digraph_internal')
|
4
6
|
const Digraph = require('./src/digraph')
|
5
7
|
const { project } = require('./src/project')
|
@@ -10,36 +12,10 @@ const _ = require('lodash')
|
|
10
12
|
const stringify = require('json-stable-stringify')
|
11
13
|
const Lines = require('./lines')
|
12
14
|
const flattens = require('./src/flatten')
|
13
|
-
const { appendNoDups, InitCalls, updateQueries, safeNoDups, stableId } = require('./src/helpers')
|
15
|
+
const { appendNoDups, InitCalls, updateQueries, safeNoDups, stableId, where } = require('./src/helpers')
|
14
16
|
const runtime = require('./runtime')
|
15
17
|
const sortJson = runtime.sortJson
|
16
18
|
|
17
|
-
function where (goUp = 2) {
|
18
|
-
const e = new Error()
|
19
|
-
const regexForm1 = /\((.*):(\d+):(\d+)\)$/
|
20
|
-
const regexForm2 = /at (.*):(\d+):(\d+)$/
|
21
|
-
const lines = e.stack.split('\n')
|
22
|
-
let line
|
23
|
-
let match
|
24
|
-
for (line of lines.slice(1)) {
|
25
|
-
// if (!(line.includes('config.js:') || line.includes('client.js:') || line.includes('<anonymous>'))) {
|
26
|
-
if (!(line.includes('config.js:') || line.includes('client.js:'))) {
|
27
|
-
match = regexForm1.exec(line) || regexForm2.exec(line)
|
28
|
-
if (!match) {
|
29
|
-
continue
|
30
|
-
}
|
31
|
-
break
|
32
|
-
}
|
33
|
-
}
|
34
|
-
// const line = e.stack.split("\n")[goUp];
|
35
|
-
// const match = regexForm1.exec(line) || regexForm2.exec(line)
|
36
|
-
if (match) {
|
37
|
-
return `${match[1]}:${match[2]}`
|
38
|
-
} else {
|
39
|
-
return 'running in browser'
|
40
|
-
}
|
41
|
-
}
|
42
|
-
|
43
19
|
const getConfig_getObjectsCheck = (config, testConfig) => {
|
44
20
|
let testConfigName = config.name
|
45
21
|
if (testConfig.testModuleName) {
|
@@ -47,7 +23,13 @@ const getConfig_getObjectsCheck = (config, testConfig) => {
|
|
47
23
|
}
|
48
24
|
const checks = (testConfig.checks && testConfig.checks.objects) || []
|
49
25
|
if (Array.isArray(checks)) {
|
50
|
-
|
26
|
+
const kmToChecks = { [testConfigName]: checks.filter( (check) => !check.km ) }
|
27
|
+
for (const check of checks) {
|
28
|
+
if (check.km) {
|
29
|
+
kmToChecks[check.km] = config.km(check.km).testConfig.checks.objects
|
30
|
+
}
|
31
|
+
}
|
32
|
+
return kmToChecks
|
51
33
|
} else {
|
52
34
|
return checks
|
53
35
|
}
|
@@ -102,164 +84,6 @@ const vimdiff = (actualJSON, expectedJSON, title) => {
|
|
102
84
|
}
|
103
85
|
}
|
104
86
|
|
105
|
-
const listable = (hierarchy) => (c, type) => {
|
106
|
-
if (!c) {
|
107
|
-
return false
|
108
|
-
}
|
109
|
-
if (hierarchy.isA(c.marker, type)) {
|
110
|
-
return true
|
111
|
-
}
|
112
|
-
if (c.marker === 'list') {
|
113
|
-
for (const t of c.types) {
|
114
|
-
if (hierarchy.isA(t, type)) {
|
115
|
-
return true
|
116
|
-
}
|
117
|
-
}
|
118
|
-
}
|
119
|
-
return false
|
120
|
-
}
|
121
|
-
|
122
|
-
const isA = (hierarchy) => (child, parent) => {
|
123
|
-
if (!child || !parent) {
|
124
|
-
return false
|
125
|
-
}
|
126
|
-
if (child.marker) {
|
127
|
-
child = child.marker
|
128
|
-
}
|
129
|
-
if (parent.marker) {
|
130
|
-
parent = parent.marker
|
131
|
-
}
|
132
|
-
return hierarchy.isA(child, parent)
|
133
|
-
}
|
134
|
-
|
135
|
-
const asList = (context) => {
|
136
|
-
if (context.marker === 'list') {
|
137
|
-
return context
|
138
|
-
}
|
139
|
-
return {
|
140
|
-
marker: 'list',
|
141
|
-
types: [context.marker],
|
142
|
-
value: [context]
|
143
|
-
}
|
144
|
-
}
|
145
|
-
|
146
|
-
class ErrorReason extends Error {
|
147
|
-
constructor (context) {
|
148
|
-
super(JSON.stringify(context))
|
149
|
-
this.reason = context
|
150
|
-
}
|
151
|
-
}
|
152
|
-
|
153
|
-
const setupArgs = (args, config, logs, hierarchy, uuidForScoping) => {
|
154
|
-
|
155
|
-
// callId
|
156
|
-
args.calls = new InitCalls(args.isInstance ? `${args.isInstance}#${config.name}` : config.name)
|
157
|
-
if (global.theprogrammablemind && global.theprogrammablemind.loadForTesting) {
|
158
|
-
args.calls = new InitCalls(Object.keys(global.theprogrammablemind.loadForTesting)[0])
|
159
|
-
}
|
160
|
-
args.km = (name) => config.getConfig(name)
|
161
|
-
args.api = (name) => config.getConfig(name).api
|
162
|
-
args.error = (context) => {
|
163
|
-
throw new ErrorReason(context)
|
164
|
-
}
|
165
|
-
args.kms = config.getConfigs()
|
166
|
-
args.config = config
|
167
|
-
args.hierarchy = hierarchy
|
168
|
-
args.isA = isA(hierarchy)
|
169
|
-
args.listable = listable(hierarchy)
|
170
|
-
args.asList = asList
|
171
|
-
args.retry = () => { throw new RetryError() }
|
172
|
-
args.fragments = (query) => config.fragment(query)
|
173
|
-
args.breakOnSemantics = false
|
174
|
-
args.theDebugger = {
|
175
|
-
breakOnSemantics: (value) => args.breakOnSemantics = value
|
176
|
-
}
|
177
|
-
if (!logs) {
|
178
|
-
}
|
179
|
-
args.log = (message) => logs.push(message)
|
180
|
-
|
181
|
-
args.addAssumedScoped = (args, assumed) => {
|
182
|
-
const addAssumed = (args, ...moreAssumed) => {
|
183
|
-
return { ...args, assumed: Object.assign({}, assumed, (args.assumed || {}), ...moreAssumed) }
|
184
|
-
}
|
185
|
-
|
186
|
-
args.s = (c) => config.getSemantics(logs).apply(args, c)
|
187
|
-
args.g = (c, a = {}) => {
|
188
|
-
return config.getGenerators(logs).apply(addAssumed(args, a), c, a)
|
189
|
-
}
|
190
|
-
args.gp = (c, a = {}) => {
|
191
|
-
return config.getGenerators(logs).apply(addAssumed(args, a, { paraphrase: true, isResponse: false, response: false }), c, { paraphrase: true, isResponse: false, response: false })
|
192
|
-
}
|
193
|
-
args.gr = (c, a = {}) => {
|
194
|
-
return config.getGenerators(logs).apply(addAssumed(args, a, { paraphrase: false, isResponse: true }), { ...c, paraphrase: false, isResponse: true })
|
195
|
-
}
|
196
|
-
args.e = (c) => {
|
197
|
-
return config.getEvaluator(args.s, args.calls, logs, c)
|
198
|
-
}
|
199
|
-
args.gs = gs(args.g)
|
200
|
-
args.gsp = gs(args.gp)
|
201
|
-
args.gsr = gs(args.gr)
|
202
|
-
}
|
203
|
-
// for semantics
|
204
|
-
args.addAssumedScoped(args, {})
|
205
|
-
|
206
|
-
const getAPI = (uuid) => {
|
207
|
-
if (config && config.getAPI) {
|
208
|
-
return config.getAPI(uuid)
|
209
|
-
}
|
210
|
-
}
|
211
|
-
const getAPIs = (uuid) => {
|
212
|
-
if (config && config.getAPIs) {
|
213
|
-
return config.getAPIs(uuid)
|
214
|
-
}
|
215
|
-
}
|
216
|
-
args.getUUIDScoped = (uuid) => {
|
217
|
-
return {
|
218
|
-
api: getAPI(uuid),
|
219
|
-
apis: getAPIs(uuid)
|
220
|
-
}
|
221
|
-
}
|
222
|
-
config.getAddedArgs(args)
|
223
|
-
|
224
|
-
Object.assign(args, args.getUUIDScoped(uuidForScoping || config.uuid))
|
225
|
-
/*
|
226
|
-
if (uuidForScoping) {
|
227
|
-
Object.assign(args, args.getUUIDScoped(uuidForScoping))
|
228
|
-
}
|
229
|
-
*/
|
230
|
-
// sets args for all the API. that make a copy so the args must be fully setup by here except for scoped
|
231
|
-
config.setArgs(args)
|
232
|
-
}
|
233
|
-
|
234
|
-
const gs = (g) => (contexts, separator, lastSeparator) => {
|
235
|
-
if (!Array.isArray(contexts)) {
|
236
|
-
debugger
|
237
|
-
throw new Error('Expected a list')
|
238
|
-
}
|
239
|
-
|
240
|
-
let s = ''
|
241
|
-
if (!separator) {
|
242
|
-
separator = ' '
|
243
|
-
}
|
244
|
-
if (!lastSeparator) {
|
245
|
-
lastSeparator = separator
|
246
|
-
}
|
247
|
-
let nextSeparator = ''
|
248
|
-
for (let i = 0; i < contexts.length; ++i) {
|
249
|
-
const context = contexts[i]
|
250
|
-
const value = g(context)
|
251
|
-
if (i > 0) {
|
252
|
-
if (i === contexts.length - 1) {
|
253
|
-
nextSeparator = lastSeparator
|
254
|
-
} else {
|
255
|
-
nextSeparator = separator
|
256
|
-
}
|
257
|
-
}
|
258
|
-
s += nextSeparator + value
|
259
|
-
}
|
260
|
-
return s
|
261
|
-
}
|
262
|
-
|
263
87
|
const matching = (actual, expected) => {
|
264
88
|
if (!deepEqual(stringify(sortJson(actual, { depth: 25 })), stringify(sortJson(expected, { depth: 25 })))) {
|
265
89
|
return false
|
@@ -284,56 +108,18 @@ const analyzeMetaData = (right, wrong) => {
|
|
284
108
|
return []
|
285
109
|
}
|
286
110
|
|
287
|
-
const processContexts = (contexts, params) => {
|
111
|
+
const processContexts = async (contexts, params) => {
|
288
112
|
const contextsPrime = []
|
289
113
|
const generated = []
|
290
114
|
const logs = []
|
291
115
|
for (const context of contexts) {
|
292
|
-
const result = processContext(context, Object.assign({}, params, { logs }))
|
116
|
+
const result = await processContext(context, Object.assign({}, params, { logs }))
|
293
117
|
contextsPrime.push(result.context)
|
294
118
|
generated.push(result.generated)
|
295
119
|
}
|
296
120
|
return { contexts: contextsPrime, generated, logs }
|
297
121
|
}
|
298
122
|
|
299
|
-
const getObjects = (objects) => {
|
300
|
-
return (uuid) => {
|
301
|
-
if (objects && objects.namespaced) {
|
302
|
-
return objects.namespaced[uuid]
|
303
|
-
}
|
304
|
-
return objects
|
305
|
-
}
|
306
|
-
}
|
307
|
-
|
308
|
-
const processContext = (context, { objects = {}, config, logs = [] }) => {
|
309
|
-
const generators = config.getGenerators(logs)
|
310
|
-
const semantics = config.getSemantics(logs)
|
311
|
-
|
312
|
-
// map to hash
|
313
|
-
config = config || {}
|
314
|
-
if (config.config) {
|
315
|
-
config = config
|
316
|
-
}
|
317
|
-
|
318
|
-
const response = {} // NA but passed in
|
319
|
-
// generators = new Generators(generators.map((g) => new Generator(normalizeGenerator(g))))
|
320
|
-
// semantics = new Semantics(semantics.map((g) => new Semantic(normalizeSemantic(g))))
|
321
|
-
const hierarchy = new DigraphInternal((config.config || {}).hierarchy || [])
|
322
|
-
|
323
|
-
const args = { objects, response, getObjects: getObjects(objects) }
|
324
|
-
setupArgs(args, config, logs, hierarchy)
|
325
|
-
|
326
|
-
context = semantics.apply(args, context)
|
327
|
-
const generated = generators.apply(args, context)
|
328
|
-
const assumed = { paraphrase: true, response: false, isResponse: false }
|
329
|
-
const paraphrases = generators.apply({ ...args, assumed }, context, { paraphrase: true, response: false, isResponse: false })
|
330
|
-
let responses = []
|
331
|
-
if (context.isResponse) {
|
332
|
-
responses = generated
|
333
|
-
}
|
334
|
-
return { context, generated, paraphrases, responses }
|
335
|
-
}
|
336
|
-
|
337
123
|
const convertToStable = (objects) => {
|
338
124
|
if (true) {
|
339
125
|
return objects
|
@@ -425,136 +211,6 @@ const overlaps = (r1, context) => {
|
|
425
211
|
return false
|
426
212
|
}
|
427
213
|
|
428
|
-
const setupContexts = (rawContexts) => {
|
429
|
-
let first = true
|
430
|
-
const contexts = []
|
431
|
-
contexts.push({ marker: 'controlStart', controlRemove: true })
|
432
|
-
for (const context of rawContexts) {
|
433
|
-
if (first) {
|
434
|
-
first = false
|
435
|
-
} else {
|
436
|
-
contexts.push({ marker: 'controlBetween', controlRemove: true })
|
437
|
-
}
|
438
|
-
contexts.push(context)
|
439
|
-
}
|
440
|
-
contexts.push({ marker: 'controlEnd', controlRemove: true })
|
441
|
-
return contexts
|
442
|
-
}
|
443
|
-
|
444
|
-
const processContextsB = ({ config, hierarchy, semantics, generators, json, isTest, isInstance, instance, query, data, retries, url, commandLineArgs }) => {
|
445
|
-
// TODO fix this name to contextsPrime
|
446
|
-
const contextsPrime = []
|
447
|
-
const generatedPrime = []
|
448
|
-
const paraphrasesPrime = []
|
449
|
-
const paraphrasesParenthesizedPrime = []
|
450
|
-
const generatedParenthesizedPrime = []
|
451
|
-
const responsesPrime = []
|
452
|
-
const contexts = setupContexts(json.contexts)
|
453
|
-
|
454
|
-
const objects = config.get('objects')
|
455
|
-
const args = { objects, isResponse: true, response: json, isTest, isInstance, getObjects: getObjects(objects), instance }
|
456
|
-
if (!json.logs) {
|
457
|
-
json.logs = []
|
458
|
-
}
|
459
|
-
setupArgs(args, config, json.logs, hierarchy)
|
460
|
-
const toDo = [...contexts]
|
461
|
-
args.insert = (context) => toDo.unshift(context)
|
462
|
-
let overlap, lastRange
|
463
|
-
config.debugLoops = commandLineArgs && commandLineArgs.debugLoops
|
464
|
-
while (toDo.length > 0) {
|
465
|
-
const context = toDo.shift()
|
466
|
-
args.calls.next()
|
467
|
-
let contextPrime = context
|
468
|
-
context.topLevel = true
|
469
|
-
try {
|
470
|
-
if (json.has_errors) {
|
471
|
-
throw new Error('There are errors in the logs. Run with the -d flag and grep for Error')
|
472
|
-
}
|
473
|
-
const generateParenthesized = isTest || (commandLineArgs && commandLineArgs.save)
|
474
|
-
if (!config.get('skipSemantics')) {
|
475
|
-
const semantics = config.getSemantics(json.logs)
|
476
|
-
try {
|
477
|
-
contextPrime = semantics.apply(args, context)
|
478
|
-
} catch (e) {
|
479
|
-
if (e.message == 'Maximum call stack size exceeded') {
|
480
|
-
const mostCalled = semantics.getMostCalled()
|
481
|
-
e.message += `\nThe most called semantic was:\nnotes: ${mostCalled.notes}\nmatch: ${mostCalled.matcher.toString()}\napply: ${mostCalled._apply.toString()}\n`
|
482
|
-
}
|
483
|
-
// contextPrime = semantics.apply(args, { marker: 'error', context, error: e })
|
484
|
-
if (isInstance) {
|
485
|
-
console.log('error', e.error)
|
486
|
-
}
|
487
|
-
contextPrime = semantics.apply(args, {
|
488
|
-
marker: 'error',
|
489
|
-
context,
|
490
|
-
text: e ? e.toString() : 'not available',
|
491
|
-
reason: e.reason,
|
492
|
-
error: e.stack || e.error
|
493
|
-
})
|
494
|
-
}
|
495
|
-
}
|
496
|
-
if (contextPrime.controlRemove) {
|
497
|
-
continue
|
498
|
-
}
|
499
|
-
let assumed = { isResponse: true }
|
500
|
-
const generated = contextPrime.isResponse ? config.getGenerators(json.logs).apply({ ...args, assumed }, contextPrime, assumed) : ''
|
501
|
-
let generatedParenthesized = []
|
502
|
-
if (generateParenthesized) {
|
503
|
-
config.parenthesized = true
|
504
|
-
generatedParenthesized = contextPrime.isResponse ? config.getGenerators(json.logs).apply({ ...args, assumed }, contextPrime, assumed) : ''
|
505
|
-
config.parenthesized = false
|
506
|
-
}
|
507
|
-
// assumed = { paraphrase: true, response: false };
|
508
|
-
assumed = { paraphrase: true, isResponse: false, response: false }
|
509
|
-
if (generateParenthesized) {
|
510
|
-
config.parenthesized = false
|
511
|
-
}
|
512
|
-
const paraphrases = config.getGenerators(json.logs).apply({ ...args, assumed }, contextPrime, assumed)
|
513
|
-
let paraphrasesParenthesized = []
|
514
|
-
if (generateParenthesized) {
|
515
|
-
config.parenthesized = true
|
516
|
-
paraphrasesParenthesized = config.getGenerators(json.logs).apply({ ...args, assumed }, contextPrime, assumed)
|
517
|
-
config.parenthesized = false
|
518
|
-
}
|
519
|
-
contextsPrime.push(contextPrime)
|
520
|
-
generatedPrime.push(generated)
|
521
|
-
paraphrasesPrime.push(paraphrases)
|
522
|
-
if (generateParenthesized) {
|
523
|
-
paraphrasesParenthesizedPrime.push(paraphrasesParenthesized)
|
524
|
-
generatedParenthesizedPrime.push(generatedParenthesized)
|
525
|
-
}
|
526
|
-
if (contextPrime.isResponse) {
|
527
|
-
responsesPrime.push(generated)
|
528
|
-
} else {
|
529
|
-
responsesPrime.push('')
|
530
|
-
}
|
531
|
-
|
532
|
-
// add results to processed list
|
533
|
-
config.config.objects.processed = config.config.objects.processed || []
|
534
|
-
config.config.objects.processed = config.config.objects.processed.slice(0, 5)
|
535
|
-
config.config.objects.processed.unshift({ context: contextPrime, paraphrases: paraphrases, paraphrasesParenthesized, generatedParenthesized, responses: responsesPrime })
|
536
|
-
} catch (e) {
|
537
|
-
if (Array.isArray(e)) {
|
538
|
-
e = {
|
539
|
-
errors: e
|
540
|
-
}
|
541
|
-
}
|
542
|
-
e.context = contextPrime
|
543
|
-
if (e.logs) {
|
544
|
-
e.logs = e.logs.concat(json.logs)
|
545
|
-
} else {
|
546
|
-
e.logs = json.logs
|
547
|
-
}
|
548
|
-
e.metadata = json.metadata
|
549
|
-
if (json.trace) {
|
550
|
-
e.trace = json.trace
|
551
|
-
}
|
552
|
-
throw e
|
553
|
-
}
|
554
|
-
}
|
555
|
-
return { contextsPrime, generatedPrime, paraphrasesPrime, paraphrasesParenthesizedPrime, generatedParenthesizedPrime, responsesPrime }
|
556
|
-
}
|
557
|
-
|
558
214
|
const doWithRetries = async (n, url, queryParams, data) => {
|
559
215
|
if (!queryParams) {
|
560
216
|
queryParams = ''
|
@@ -589,93 +245,6 @@ const doWithRetries = async (n, url, queryParams, data) => {
|
|
589
245
|
}
|
590
246
|
}
|
591
247
|
|
592
|
-
const setupProcessB = ({ config, initializer, allowDelta = false } = {}) => {
|
593
|
-
const key = config._key
|
594
|
-
|
595
|
-
const data = Object.assign({ key, version: '3' }, { uuid: config._uuid })
|
596
|
-
if (allowDelta && config.allowDelta && config.hasDelta()) {
|
597
|
-
// console.log('config', config)
|
598
|
-
data.delta = config.delta()
|
599
|
-
} else {
|
600
|
-
config.toData(data)
|
601
|
-
// Object.assign(data, config.config)
|
602
|
-
}
|
603
|
-
|
604
|
-
// config.toServer(data)
|
605
|
-
|
606
|
-
if (data.namespaces) {
|
607
|
-
for (const uuid of Object.keys(data.namespaces)) {
|
608
|
-
const km = config.configs.find((km) => km.uuid === uuid)
|
609
|
-
data.namespaces[uuid].name = km.name
|
610
|
-
}
|
611
|
-
}
|
612
|
-
|
613
|
-
// const generators = new Generators((data.generators || []).map((g) => new Generator(normalizeGenerator(g))))
|
614
|
-
delete data.generators
|
615
|
-
// const semantics = new Semantics((data.semantics || []).map((g) => new Semantic(normalizeSemantic(g))))
|
616
|
-
delete data.semantics
|
617
|
-
const hierarchy = new DigraphInternal((config.config || {}).hierarchy || [])
|
618
|
-
|
619
|
-
return {
|
620
|
-
data,
|
621
|
-
// generators,
|
622
|
-
// semantics,
|
623
|
-
hierarchy
|
624
|
-
}
|
625
|
-
}
|
626
|
-
|
627
|
-
// instance template loadTemplate
|
628
|
-
const loadInstance = (config, instance) => {
|
629
|
-
const transitoryMode = global.transitoryMode
|
630
|
-
global.transitoryMode = false
|
631
|
-
|
632
|
-
if (instance && (instance.associations || instance.learned_contextual_priorities)) {
|
633
|
-
if (!config.config.retrain) {
|
634
|
-
if (instance.associations) {
|
635
|
-
config.addAssociations(instance.associations)
|
636
|
-
}
|
637
|
-
if (instance.learned_contextual_priorities && instance.learned_contextual_priorities.length > 0) {
|
638
|
-
config.addPriorities(instance.learned_contextual_priorities)
|
639
|
-
}
|
640
|
-
}
|
641
|
-
}
|
642
|
-
|
643
|
-
const { /* data, generators, semantics, */ hierarchy } = setupProcessB({ config })
|
644
|
-
// for (const results of (instance.resultss || [])) {
|
645
|
-
for (const i in (instance.resultss || [])) {
|
646
|
-
const results = instance.resultss[i]
|
647
|
-
if (results.extraConfig) {
|
648
|
-
// config.addInternal(results, useOldVersion = true, skipObjects = false, includeNamespaces = true, allowNameToBeNull = false)
|
649
|
-
const uuid = config.nameToUUID(instance.name)
|
650
|
-
// used to do a CLONE
|
651
|
-
config.addInternal(instance.template.configs[i], { uuid, addFirst: true, handleCalculatedProps: true })
|
652
|
-
} else if (results.apply) {
|
653
|
-
const objects = config.get('objects')
|
654
|
-
const args = { objects, getObjects: getObjects(objects) }
|
655
|
-
if (instance.configs) {
|
656
|
-
args.isInstance = `instance${i}`
|
657
|
-
args.instance = instance.configs[i]
|
658
|
-
}
|
659
|
-
|
660
|
-
const uuid = config.nameToUUID(instance.name)
|
661
|
-
setupArgs(args, config, config.logs, hierarchy, uuid)
|
662
|
-
results.apply(args)
|
663
|
-
} else {
|
664
|
-
if (results.skipSemantics) {
|
665
|
-
config.config.skipSemantics = results.skipSemantics
|
666
|
-
}
|
667
|
-
const args = { config, hierarchy, json: results, commandLineArgs: {} }
|
668
|
-
args.isInstance = `instance${i}`
|
669
|
-
args.instance = ''
|
670
|
-
processContextsB(args)
|
671
|
-
if (results.skipSemantics) {
|
672
|
-
config.config.skipSemantics = null
|
673
|
-
}
|
674
|
-
}
|
675
|
-
}
|
676
|
-
global.transitoryMode = transitoryMode
|
677
|
-
}
|
678
|
-
|
679
248
|
const throwErrorHandler = (error) => {
|
680
249
|
throw error
|
681
250
|
}
|
@@ -692,7 +261,7 @@ const _process = async (config, query, { initializer, commandLineArgs, credentia
|
|
692
261
|
// ensure same start state
|
693
262
|
try {
|
694
263
|
if (writeTests) {
|
695
|
-
config.rebuild()
|
264
|
+
await config.rebuild()
|
696
265
|
const objects = getObjects(config.config.objects)(config.uuid)
|
697
266
|
}
|
698
267
|
} catch (error) {
|
@@ -728,12 +297,14 @@ const _process = async (config, query, { initializer, commandLineArgs, credentia
|
|
728
297
|
associations: []
|
729
298
|
}
|
730
299
|
|
300
|
+
let startCounter = 0
|
731
301
|
while (true) {
|
732
302
|
if (queries.length === 0) {
|
733
303
|
break
|
734
304
|
}
|
735
305
|
|
736
306
|
data.utterance = queries[0]
|
307
|
+
data.start_counter = startCounter
|
737
308
|
let json = await doWithRetries(retries, url, queryParams, data)
|
738
309
|
let resetData = false
|
739
310
|
if (json.code == 'NOT_IN_CACHE') {
|
@@ -755,6 +326,7 @@ const _process = async (config, query, { initializer, commandLineArgs, credentia
|
|
755
326
|
}
|
756
327
|
}
|
757
328
|
json.contexts = json.results
|
329
|
+
startCounter= json.end_counter + 1
|
758
330
|
delete json.results
|
759
331
|
if (json.status !== 200) {
|
760
332
|
throw json
|
@@ -764,7 +336,7 @@ const _process = async (config, query, { initializer, commandLineArgs, credentia
|
|
764
336
|
start = runtime.performance.performance.now()
|
765
337
|
}
|
766
338
|
const { contextsPrime, generatedPrime, paraphrasesPrime, paraphrasesParenthesizedPrime, generatedParenthesizedPrime, responsesPrime } =
|
767
|
-
processContextsB({ isTest, config, hierarchy, json, commandLineArgs /*, generators, semantics */ })
|
339
|
+
await processContextsB({ isTest, rebuildingTemplate, config, hierarchy, json, commandLineArgs /*, generators, semantics */ })
|
768
340
|
if (isTest) {
|
769
341
|
end = runtime.performance.performance.now()
|
770
342
|
clientSideTime = end - start
|
@@ -792,6 +364,7 @@ const _process = async (config, query, { initializer, commandLineArgs, credentia
|
|
792
364
|
response.generatedParenthesized = response.generatedParenthesized.concat(generatedParenthesizedPrime)
|
793
365
|
response.responses = response.responses.concat(responsesPrime)
|
794
366
|
queries = queries.slice(1)
|
367
|
+
|
795
368
|
}
|
796
369
|
}
|
797
370
|
|
@@ -819,7 +392,6 @@ const getConfigForTest = (config, testConfig) => {
|
|
819
392
|
}
|
820
393
|
const configForTest = {}
|
821
394
|
for (const key of Object.keys(includes)) {
|
822
|
-
// configForTest[key] = config.config[key]
|
823
395
|
if (key === 'words') {
|
824
396
|
const words = config.config.words
|
825
397
|
configForTest.words = {
|
@@ -829,7 +401,14 @@ const getConfigForTest = (config, testConfig) => {
|
|
829
401
|
}
|
830
402
|
|
831
403
|
const literals = config.config.words.literals
|
404
|
+
let includesWord = (word) => true
|
405
|
+
if (Array.isArray(includes.words)) {
|
406
|
+
includesWord = (word) => includes.words.includes(word)
|
407
|
+
}
|
832
408
|
for (const key in literals) {
|
409
|
+
if (!includesWord(key)) {
|
410
|
+
continue
|
411
|
+
}
|
833
412
|
const defs = []
|
834
413
|
for (const def of literals[key]) {
|
835
414
|
// TODO handle thie uuids the right way
|
@@ -838,15 +417,23 @@ const getConfigForTest = (config, testConfig) => {
|
|
838
417
|
configForTest.words.literals[key] = defs
|
839
418
|
}
|
840
419
|
|
841
|
-
const patterns = config.config.words.patterns
|
420
|
+
const patterns = config.config.words.patterns || []
|
842
421
|
configForTest.words.patterns = patterns.map((pattern) => Object.assign({}, pattern, { uuid: undefined }))
|
843
422
|
|
844
|
-
const hierarchy = config.config.words.hierarchy
|
423
|
+
const hierarchy = config.config.words.hierarchy || []
|
845
424
|
configForTest.words.hierarchy = hierarchy.map((hierarchy) => Object.assign({}, hierarchy, { uuid: undefined }))
|
846
425
|
} else if (key === 'operators') {
|
847
|
-
|
426
|
+
let include = (operator) => true
|
427
|
+
if (Array.isArray(includes.operators)) {
|
428
|
+
include = (operator) => includes.operators.includes(operator.pattern)
|
429
|
+
}
|
430
|
+
configForTest.operators = config.config.operators.filter( include ).map((operator) => Object.assign({}, operator, { uuid: undefined }))
|
848
431
|
} else if (key === 'bridges') {
|
849
|
-
|
432
|
+
let include = (operator) => true
|
433
|
+
if (Array.isArray(includes.bridges)) {
|
434
|
+
include = (bridge) => includes.bridges.includes(bridge.id)
|
435
|
+
}
|
436
|
+
configForTest.bridges = config.config.bridges.filter(include).map((bridge) => Object.assign({}, bridge, { uuid: undefined }))
|
850
437
|
} else {
|
851
438
|
configForTest[key] = config.config[key]
|
852
439
|
}
|
@@ -854,10 +441,14 @@ const getConfigForTest = (config, testConfig) => {
|
|
854
441
|
return configForTest
|
855
442
|
}
|
856
443
|
|
857
|
-
const runTest = async (config, expected, { args, verbose, testConfig, debug }) => {
|
444
|
+
const runTest = async (config, expected, { args, verbose, testConfig, debug, timings={ server: 0, client: 0 } }) => {
|
858
445
|
const test = expected.query
|
446
|
+
if (args.query && args.query != test) {
|
447
|
+
// no run this
|
448
|
+
return
|
449
|
+
}
|
859
450
|
// initialize in between test so state is not preserved since the test was adding without state
|
860
|
-
config.rebuild()
|
451
|
+
await config.rebuild()
|
861
452
|
const errorHandler = (error) => {
|
862
453
|
if (error.metadata) {
|
863
454
|
const priorities = analyzeMetaData(expected.metadata, error.metadata)
|
@@ -881,6 +472,8 @@ const runTest = async (config, expected, { args, verbose, testConfig, debug }) =
|
|
881
472
|
const lines = new Lines(widths)
|
882
473
|
lines.setElement(0, 0, test)
|
883
474
|
lines.setElement(0, 1, `time on server: ${result.times.toFixed(2)} client: ${(result.clientSideTimes / 1000).toFixed(2)}`)
|
475
|
+
timings.server += result.times
|
476
|
+
timings.client += result.clientSideTimes / 1000
|
884
477
|
lines.log()
|
885
478
|
}
|
886
479
|
const expected_objects = sortJson(convertToStable(expected.objects), { depth: 25 })
|
@@ -1003,7 +596,7 @@ const runTests = async (config, testFile, juicyBits) => {
|
|
1003
596
|
}
|
1004
597
|
|
1005
598
|
const saveTest = async (testFile, config, test, expected, testConfig, saveDeveloper) => {
|
1006
|
-
config.rebuild()
|
599
|
+
await config.rebuild()
|
1007
600
|
const objects = getObjects(config.config.objects)(config.uuid)
|
1008
601
|
console.log(test)
|
1009
602
|
const result = await _process(config, test, { isTest: true })
|
@@ -1024,11 +617,11 @@ const saveTestsHelper = async (testFile, config, tests, todo, testConfig, saveDe
|
|
1024
617
|
return
|
1025
618
|
}
|
1026
619
|
const test = todo.pop()
|
1027
|
-
config.rebuild()
|
620
|
+
await config.rebuild()
|
1028
621
|
const result = await saveTest(testFile, config, test, tests[test], testConfig, saveDeveloper)
|
1029
622
|
// initialize in between test so state is not preserved since the test was adding without state
|
1030
623
|
// config.initialize({force: true})
|
1031
|
-
config.rebuild()
|
624
|
+
await config.rebuild()
|
1032
625
|
return saveTestsHelper(testFile, config, tests, todo, testConfig, saveDeveloper)
|
1033
626
|
}
|
1034
627
|
|
@@ -1193,7 +786,7 @@ const defaultInnerProcess = (config, errorHandler, responses) => {
|
|
1193
786
|
responses.errors.forEach((error) => console.log(` ${error}`))
|
1194
787
|
}
|
1195
788
|
console.log("KM's loaded (ordered)", config.configs.map((c) => c.name))
|
1196
|
-
console.log('This is the global objects from running semantics:\n', config.objects)
|
789
|
+
// console.log('This is the global objects from running semantics:\n', config.objects)
|
1197
790
|
if (!_.isEmpty(responses.learned_contextual_priorities)) {
|
1198
791
|
console.log('\nThe learned contextual priorties are :\n')
|
1199
792
|
for (const lcp of responses.learned_contextual_priorities) {
|
@@ -1210,10 +803,12 @@ const defaultInnerProcess = (config, errorHandler, responses) => {
|
|
1210
803
|
}
|
1211
804
|
console.log(responses.trace)
|
1212
805
|
|
1213
|
-
if (
|
1214
|
-
|
1215
|
-
|
1216
|
-
|
806
|
+
if (false) {
|
807
|
+
if (global.beforeObjects) {
|
808
|
+
console.log('objects', runtime.jsonDiff.diffString(global.beforeObjects, config.get('objects')))
|
809
|
+
} else {
|
810
|
+
console.log('objects', runtime.util.inspect(config.get('objects'), { depth: Infinity, sorted: true }))
|
811
|
+
}
|
1217
812
|
}
|
1218
813
|
|
1219
814
|
const pickEm = () => {
|
@@ -1315,6 +910,7 @@ const rebuildTemplate = async ({ config, target, previousResultss, startOfChange
|
|
1315
910
|
associations: [],
|
1316
911
|
learned_contextual_priorities: []
|
1317
912
|
}
|
913
|
+
config.fragmentsBeingBuilt = []
|
1318
914
|
const looper = async (configs) => {
|
1319
915
|
if (configs.length === 0) {
|
1320
916
|
finish()
|
@@ -1322,14 +918,15 @@ const rebuildTemplate = async ({ config, target, previousResultss, startOfChange
|
|
1322
918
|
}
|
1323
919
|
const { property, hierarchy, query: queryOrExtraConfig, previousResults, initializer, skipSemantics } = configs.shift()
|
1324
920
|
// queries are strings or { query: "blah", development: true/false }
|
1325
|
-
if (typeof queryOrExtraConfig === 'string' || queryOrExtraConfig.query) {
|
921
|
+
if (typeof queryOrExtraConfig === 'string' || queryOrExtraConfig.query || queryOrExtraConfig.isFragment) {
|
1326
922
|
let query = queryOrExtraConfig
|
923
|
+
let isFragment = queryOrExtraConfig.isFragment
|
1327
924
|
if (typeof queryOrExtraConfig === 'string') {
|
1328
925
|
query = { query }
|
1329
926
|
}
|
1330
|
-
config.config.skipSemantics = skipSemantics
|
927
|
+
config.config.skipSemantics = skipSemantics && !isFragment
|
1331
928
|
const transitoryMode = global.transitoryMode
|
1332
|
-
if (property == 'fragments') {
|
929
|
+
if (isFragment || property == 'fragments') {
|
1333
930
|
global.transitoryMode = true
|
1334
931
|
}
|
1335
932
|
if (hierarchy) {
|
@@ -1347,7 +944,7 @@ const rebuildTemplate = async ({ config, target, previousResultss, startOfChange
|
|
1347
944
|
if (previousResults && previousResults.query == query.query) {
|
1348
945
|
results = previousResults
|
1349
946
|
prMessage = ' Using previous results. use -rtf for a hard rebuild of everything on the server side.'
|
1350
|
-
loadInstance(config, { resultss: [results] })
|
947
|
+
await loadInstance(config, { resultss: [results] })
|
1351
948
|
} else {
|
1352
949
|
results = await _process(config, query.query, { initializer, rebuildingTemplate: true })
|
1353
950
|
}
|
@@ -1358,18 +955,22 @@ const rebuildTemplate = async ({ config, target, previousResultss, startOfChange
|
|
1358
955
|
if (results.contexts.length > 1) {
|
1359
956
|
console.log(`query "${query.query}". There is ${results.contexts.length} contexts in the results. Make sure its producing the results that you expect.`)
|
1360
957
|
throw new Error(`query "${query.query}". There is ${results.contexts.length} contexts in the results. Make sure its producing the results that you expect.`)
|
1361
|
-
} else if (results.paraphrases[0]
|
958
|
+
} else if (results.paraphrases[0].toLowerCase() !== query.query.toLowerCase()) {
|
1362
959
|
console.log(`query "${query.query}". The paraphrase is different from the query "${results.paraphrases[0]}".${prMessage}`)
|
1363
960
|
} else {
|
1364
|
-
console.log(`query "${query.query}".${prMessage}`)
|
961
|
+
console.log(`query ${isFragment ? 'fragment' : ''}"${query.query}".${prMessage}`)
|
1365
962
|
}
|
1366
963
|
global.transitoryMode = transitoryMode
|
1367
964
|
config.config.skipSemantics = null
|
1368
965
|
results.query = query.query
|
966
|
+
results.isFragment = isFragment
|
1369
967
|
results.skipSemantics = skipSemantics
|
1370
968
|
results.development = query.development
|
1371
969
|
results.key = { query: query.query, hierarchy }
|
1372
970
|
accumulators[property].push(results)
|
971
|
+
if (isFragment) {
|
972
|
+
config.fragmentsBeingBuilt.push({ query: query.query, contexts: results.contexts })
|
973
|
+
}
|
1373
974
|
accumulators.associations = accumulators.associations.concat(results.associations)
|
1374
975
|
accumulators.learned_contextual_priorities = accumulators.learned_contextual_priorities.concat(results.learned_contextual_priorities)
|
1375
976
|
await looper(configs)
|
@@ -1383,8 +984,8 @@ const rebuildTemplate = async ({ config, target, previousResultss, startOfChange
|
|
1383
984
|
const initFunction = queryOrExtraConfig
|
1384
985
|
const objects = config.get('objects')
|
1385
986
|
const args = { objects, getObjects: getObjects(objects) }
|
1386
|
-
setupArgs(args, config, config.logs, hierarchy)
|
1387
|
-
initFunction(args)
|
987
|
+
setupArgs(args, config, config.logs, config.hierarchy)
|
988
|
+
await initFunction(args)
|
1388
989
|
accumulators[property].push({ apply: queryOrExtraConfig })
|
1389
990
|
await looper(configs)
|
1390
991
|
} else {
|
@@ -1408,6 +1009,7 @@ const rebuildTemplate = async ({ config, target, previousResultss, startOfChange
|
|
1408
1009
|
}
|
1409
1010
|
|
1410
1011
|
const finish = () => {
|
1012
|
+
config.fragmentsBeingBuilt = []
|
1411
1013
|
const instanceName = `${target}.instance.json`
|
1412
1014
|
console.log(`Writing instance file ${instanceName}`)
|
1413
1015
|
const stabilizeAssociations = (associations) => {
|
@@ -1496,11 +1098,16 @@ const checkTest = (testConfig) => {
|
|
1496
1098
|
}
|
1497
1099
|
|
1498
1100
|
const knowledgeModuleImpl = async ({
|
1101
|
+
includes,
|
1102
|
+
config : configStruct,
|
1103
|
+
api,
|
1104
|
+
initializer,
|
1105
|
+
terminator,
|
1106
|
+
multiApiInitializer,
|
1107
|
+
|
1499
1108
|
module: moduleFromJSFile,
|
1500
1109
|
description,
|
1501
1110
|
section,
|
1502
|
-
// config, createConfig,
|
1503
|
-
createConfig,
|
1504
1111
|
newWay,
|
1505
1112
|
demo,
|
1506
1113
|
test,
|
@@ -1508,7 +1115,6 @@ const knowledgeModuleImpl = async ({
|
|
1508
1115
|
errorHandler = defaultErrorHandler,
|
1509
1116
|
process: processResults = defaultProcess,
|
1510
1117
|
stopAtFirstFailure = true,
|
1511
|
-
acceptsAdditionalConfig = false,
|
1512
1118
|
...rest
|
1513
1119
|
} = {}) => {
|
1514
1120
|
const unknownArgs = Object.keys(rest)
|
@@ -1521,10 +1127,29 @@ const knowledgeModuleImpl = async ({
|
|
1521
1127
|
if (!moduleFromJSFile) {
|
1522
1128
|
throw new Error("'module' is a required parameter. The value should be either 'module' or a lambda that will be called when the file is acting as a module.")
|
1523
1129
|
}
|
1524
|
-
|
1525
|
-
if (!
|
1130
|
+
|
1131
|
+
if (!configStruct) {
|
1526
1132
|
throw new Error("'config' or 'createConfig' is a required parameter. The value should the config that defines the knowledge module.")
|
1527
1133
|
}
|
1134
|
+
|
1135
|
+
const createConfig = async () => {
|
1136
|
+
const config = new Config(configStruct, moduleFromJSFile, _process)
|
1137
|
+
config.setTerminator(terminator)
|
1138
|
+
config.stop_auto_rebuild()
|
1139
|
+
await config.add(...(includes || []))
|
1140
|
+
if (api) {
|
1141
|
+
config.setApi(api)
|
1142
|
+
}
|
1143
|
+
if (multiApiInitializer) {
|
1144
|
+
await config.setMultiApi(multiApiInitializer)
|
1145
|
+
}
|
1146
|
+
if (initializer) {
|
1147
|
+
config.initializer(initializer)
|
1148
|
+
}
|
1149
|
+
await config.restart_auto_rebuild()
|
1150
|
+
return config
|
1151
|
+
}
|
1152
|
+
|
1528
1153
|
if (!description) {
|
1529
1154
|
throw new Error("'description' is a required parameter. The value should the description of the knowledge module.")
|
1530
1155
|
}
|
@@ -1557,525 +1182,566 @@ const knowledgeModuleImpl = async ({
|
|
1557
1182
|
}
|
1558
1183
|
|
1559
1184
|
if (isProcess) {
|
1560
|
-
|
1561
|
-
|
1562
|
-
|
1563
|
-
|
1564
|
-
|
1565
|
-
description: 'Entodicton knowledge module'
|
1566
|
-
})
|
1185
|
+
let config
|
1186
|
+
try {
|
1187
|
+
const parser = new runtime.ArgumentParser({
|
1188
|
+
description: 'Entodicton knowledge module'
|
1189
|
+
})
|
1567
1190
|
|
1568
|
-
|
1569
|
-
|
1570
|
-
|
1571
|
-
|
1572
|
-
|
1573
|
-
|
1574
|
-
|
1575
|
-
|
1576
|
-
|
1577
|
-
|
1578
|
-
|
1579
|
-
|
1580
|
-
|
1581
|
-
|
1582
|
-
|
1583
|
-
|
1584
|
-
|
1585
|
-
|
1586
|
-
|
1587
|
-
|
1588
|
-
|
1589
|
-
|
1590
|
-
|
1591
|
-
|
1592
|
-
|
1593
|
-
|
1594
|
-
|
1595
|
-
|
1596
|
-
|
1597
|
-
|
1598
|
-
|
1599
|
-
|
1600
|
-
|
1601
|
-
|
1602
|
-
|
1603
|
-
|
1604
|
-
|
1605
|
-
|
1606
|
-
|
1607
|
-
|
1608
|
-
|
1609
|
-
|
1610
|
-
|
1611
|
-
|
1612
|
-
|
1613
|
-
|
1614
|
-
|
1615
|
-
|
1616
|
-
args.
|
1617
|
-
|
1191
|
+
const helpDebugWord = 'In order to get a debug break when a specific word is created set the DEBUG_WORD environment variable to the JSON of the association to break on. For example DEBUG_WORD=\'"the"\''
|
1192
|
+
const helpDebugAssociation = 'In order to get a debug break when a specific association is created set the DEBUG_ASSOCIATION environment variable to the JSON of the association to break on. For example DEBUG_ASSOCIATION=\'[["the", 0], ["mammal", 1]]\''
|
1193
|
+
const helpDebugHierarchy = 'In order to get a debug break when a specific hierarchy is created set the DEBUG_HIERARCHY environment variable to the JSON of the child-parent pair to break on. For example DEBUG_HIERARCHY=\'[["cat", 1], ["mammel", 1]]\''
|
1194
|
+
const helpDebugPriority = 'In order to get a debug break when a specific set of priorities is created set set DEBUG_PRIORITY environment variable to the JSON of the priorities that you want to break on. For example DEBUG_PRIORITY=\'[["verb", 0], ["article", 0]]\''
|
1195
|
+
const helpDebugContextualPriority = 'In order to get a debug break when a specific set of contextual priorities is created set set DEBUG_CONTEXTUAL_PRIORITY environment variable to the JSON of the priorities that you want to break on. For example DEBUG_CONTEXTUAL_PRIORITY=\'{ context: [["verb", 0], ["article", 0], select: 1}\''
|
1196
|
+
const helpDebugBridge = 'In order to get a debug break when a specific bridge is created set the DEBUG_BRIDGE environment variable to id to break on. For example DEBUG_BRIDGE=\'car\''
|
1197
|
+
const helpDebugOperator = 'In order to get a debug break when a specific hierarcy is created set the DEBUG_OPERATOR environment variable to debug any config loaded. For example DEBUG_OPERATOR=\'([operator] ([arg]))\''
|
1198
|
+
|
1199
|
+
parser.add_argument('-tmn', '--testModuleName', { help: 'When running tests instead of using the current modules tests use the specified modules tests' })
|
1200
|
+
parser.add_argument('-t', '--test', { action: 'store_true', help: 'Run the tests. Create tests by running with the --query + --save flag' })
|
1201
|
+
parser.add_argument('-tv', '--testVerbose', { action: 'store_true', help: 'Run the tests in verbose mode. Create tests by running with the --query or --loop with the --save flag' })
|
1202
|
+
// parser.add_argument('-ttr', '--testToRun', { help: 'Only the specified test will be run' })
|
1203
|
+
parser.add_argument('-tva', '--testAllVerbose', { action: 'store_true', help: 'Run the tests in verbose mode. All the tests will be run instead of stopping at first failure. Create tests by running with the --query or --loop with the --save flag. if -q is specified the tests will be run for just the specified query.' })
|
1204
|
+
parser.add_argument('-tnp', '--testNoParenthesized', { action: 'store_true', help: 'Don\' check parenthesized differences for the tests' })
|
1205
|
+
parser.add_argument('-n', '--count', { help: 'Number of times to run the tests. Default is one. Use this to check for flakey test. If possible the system will print out a message with the word "hint" suggesting how to fix the problem' })
|
1206
|
+
// parser.add_argument('-b', '--build', { help: 'Specify the template file name of the form <kmName>. There should be a file called <baseKmName>.<kmName>.template.json with the queries to run. For example { queries: [...] }. The template file will be run and generate an instantiation called <baseKmName>.<kmName>.instance.json and a file called <kmName>.js that will load the template file (this is file generated only if not already existing) and a test file called <KmName>.tests.json. This can then be loaded into an instance of the current knowledge module to setup initial conditions.' })
|
1207
|
+
parser.add_argument('-rt', '--rebuildTemplate', { action: 'store_true', help: 'Force a template rebuild. Using optimization where if the query/config has not changed it will use the previous value. One there is a change all subsequence query/configs will be run.' })
|
1208
|
+
parser.add_argument('-rtf', '--rebuildTemplateFull', { action: 'store_true', help: 'Force a template rebuild. Skip the optimization' })
|
1209
|
+
parser.add_argument('-l', '--loop', { action: 'store_true', help: 'Run a loop so that multiply queries may be run' })
|
1210
|
+
parser.add_argument('-i', '--info', { action: 'store_true', help: 'Print meta-data for the module' })
|
1211
|
+
parser.add_argument('-v', '--vimdiff', { action: 'store_true', help: 'For failures run vimdiff' })
|
1212
|
+
parser.add_argument('-g', '--greg', { action: 'store_true', help: 'Set the server to be localhost so I can debug stuff' })
|
1213
|
+
parser.add_argument('-cl', '--checkForLoop', { nargs: '?', help: 'Check for loops in the priorities, Optional argument is list of operator keys to consider. For example [["banana", 0], ["food", 1]]' })
|
1214
|
+
parser.add_argument('-r', '--reset', { action: 'store_true', help: 'Get the server to bypass the cache and rebuild everything' })
|
1215
|
+
parser.add_argument('-q', '--query', { help: 'Run the specified query' })
|
1216
|
+
parser.add_argument('-ip ', '--server', { help: 'Server to run against' })
|
1217
|
+
parser.add_argument('-qp ', '--queryParams', { help: 'Query params for the server call' })
|
1218
|
+
parser.add_argument('-dt', '--deleteTest', { help: 'Delete the specified query from the tests file.' })
|
1219
|
+
parser.add_argument('--parenthesized', { action: 'store_true', help: 'Show the generated phrases with parenthesis.' })
|
1220
|
+
parser.add_argument('-c', '--clean', { help: 'Remove data from the test files. a === association' })
|
1221
|
+
parser.add_argument('-od', '--objectDiff', { action: 'store_true', help: 'When showing the objects use a colour diff' })
|
1222
|
+
parser.add_argument('-p', '--print', { help: 'Print the specified elements c === config, w === words, b === bridges, o === operators d === objects (d for data), h === hierarchy, g === generators, s === semantics, l === load t=tests ordering p === priorities a == associations j == JSON sent to server. for example --print wb' })
|
1223
|
+
parser.add_argument('-s', '--save', { action: 'store_true', help: 'When running with the --query flag this will save the current run to the test file. When running without the --query flag all tests will be run and resaved.' })
|
1224
|
+
parser.add_argument('-sd', '--saveDeveloper', { action: 'store_true', help: 'Same as -s but the query will not show up in the info command.' })
|
1225
|
+
parser.add_argument('-dl', '--debugLoops', { action: 'store_true', help: 'When running with the --debugLoops flag the logs calls to semantics and generators will be immediately written to the console ' })
|
1226
|
+
parser.add_argument('-d', '--debug', { action: 'store_true', help: 'When running with the --debug flag this set the debug flag in the config' })
|
1227
|
+
parser.add_argument('-da', '--debugAssociation', { action: 'store_true', help: helpDebugAssociation })
|
1228
|
+
parser.add_argument('-dw', '--debugWord', { action: 'store_true', help: helpDebugWord })
|
1229
|
+
parser.add_argument('-dh', '--debugHierarchy', { action: 'store_true', help: helpDebugHierarchy })
|
1230
|
+
parser.add_argument('-dp', '--debugPriority', { action: 'store_true', help: helpDebugPriority })
|
1231
|
+
parser.add_argument('-dcp', '--debugContextualPriority', { action: 'store_true', help: helpDebugContextualPriority })
|
1232
|
+
parser.add_argument('-db', '--debugBridge', { action: 'store_true', help: helpDebugBridge })
|
1233
|
+
parser.add_argument('-do', '--debugOperator', { action: 'store_true', help: helpDebugOperator })
|
1234
|
+
parser.add_argument('-ep', '--explainPriorities', { action: 'store_true', help: 'The server will return all priorities including the generated one along with an explanation of there they came from' })
|
1235
|
+
parser.add_argument('-dic', '--debugIncludeConvolutions', { nargs: '?', help: 'When running with the --debugIncludeConvolutions flag the logs will include convolutions which are somewhat annoyingly verbose. Default is false' })
|
1236
|
+
parser.add_argument('-bc', '--bypassCache', { action: 'store_true', help: 'Bypass the cache on the server side and rebuild' })
|
1237
|
+
|
1238
|
+
const args = parser.parse_args()
|
1239
|
+
args.count = args.count || 1
|
1240
|
+
|
1241
|
+
if (args.rebuildTemplateFull) {
|
1242
|
+
args.rebuildTemplate = true
|
1243
|
+
}
|
1244
|
+
|
1245
|
+
config = await createConfig()
|
1246
|
+
|
1247
|
+
// dont debug the load of the KM's if rebuild template is on since we want to debug the template rebuild not the load
|
1248
|
+
if (args.rebuildTemplate) {
|
1249
|
+
global.pauseDebugging = true
|
1250
|
+
}
|
1618
1251
|
|
1619
|
-
|
1620
|
-
|
1621
|
-
|
1622
|
-
|
1623
|
-
|
1624
|
-
|
1625
|
-
|
1626
|
-
|
1627
|
-
|
1628
|
-
|
1629
|
-
|
1630
|
-
|
1631
|
-
|
1632
|
-
|
1633
|
-
|
1252
|
+
setupConfig(config)
|
1253
|
+
processResults = processResults({ config, errorHandler })
|
1254
|
+
|
1255
|
+
if (args.rebuildTemplate) {
|
1256
|
+
global.pauseDebugging = false
|
1257
|
+
}
|
1258
|
+
|
1259
|
+
// setup();
|
1260
|
+
|
1261
|
+
if (args.parenthesized) {
|
1262
|
+
config.parenthesized = true
|
1263
|
+
}
|
1264
|
+
if (args.checkForLoop) {
|
1265
|
+
try {
|
1266
|
+
args.checkForLoop = JSON.parse(args.checkForLoop)
|
1267
|
+
const isKey = (what) => {
|
1268
|
+
if (!Array.isArray(what)) {
|
1269
|
+
return false
|
1270
|
+
}
|
1271
|
+
if (what.length !== 2) {
|
1272
|
+
return false
|
1273
|
+
}
|
1274
|
+
if (!typeof what[0] == 'string') {
|
1275
|
+
return false
|
1276
|
+
}
|
1277
|
+
if (!typeof what[1] == 'number') {
|
1278
|
+
return false
|
1279
|
+
}
|
1280
|
+
return true
|
1634
1281
|
}
|
1635
|
-
if (!
|
1636
|
-
|
1282
|
+
if (!Array.isArray(args.checkForLoop) || args.checkForLoop.some((value) => !isKey(value))) {
|
1283
|
+
throw new Error('Error for the checkForLoop argument. Expected a JSON array of operator keys of the form "[<id>, <level>]"')
|
1637
1284
|
}
|
1638
|
-
|
1639
|
-
}
|
1640
|
-
if (!Array.isArray(args.checkForLoop) || args.checkForLoop.some((value) => !isKey(value))) {
|
1285
|
+
} catch (e) {
|
1641
1286
|
throw new Error('Error for the checkForLoop argument. Expected a JSON array of operator keys of the form "[<id>, <level>]"')
|
1642
1287
|
}
|
1643
|
-
}
|
1644
|
-
|
1288
|
+
} else {
|
1289
|
+
if (process.argv.includes('--checkForLoop') || process.argv.includes('-cl')) {
|
1290
|
+
args.checkForLoop = true
|
1291
|
+
}
|
1645
1292
|
}
|
1646
|
-
|
1647
|
-
|
1648
|
-
|
1293
|
+
if (args.debugAssociation) {
|
1294
|
+
console.log(helpDebugAssociation)
|
1295
|
+
runtime.process.exit(-1)
|
1296
|
+
}
|
1297
|
+
if (args.debugWord) {
|
1298
|
+
console.log(helpDebugWord)
|
1299
|
+
runtime.process.exit(-1)
|
1300
|
+
}
|
1301
|
+
if (args.debugHierarchy) {
|
1302
|
+
console.log(helpDebugHierarchy)
|
1303
|
+
runtime.process.exit(-1)
|
1304
|
+
}
|
1305
|
+
if (args.debugPriority) {
|
1306
|
+
console.log(helpDebugPriority)
|
1307
|
+
runtime.process.exit(-1)
|
1308
|
+
}
|
1309
|
+
if (args.debugBridge) {
|
1310
|
+
console.log(helpDebugBridge)
|
1311
|
+
runtime.process.exit(-1)
|
1312
|
+
}
|
1313
|
+
if (args.debugOperator) {
|
1314
|
+
console.log(helpDebugOperator)
|
1315
|
+
runtime.process.exit(-1)
|
1649
1316
|
}
|
1650
|
-
}
|
1651
|
-
if (args.debugAssociation) {
|
1652
|
-
console.log(helpDebugAssociation)
|
1653
|
-
runtime.process.exit(-1)
|
1654
|
-
}
|
1655
|
-
if (args.debugHierarchy) {
|
1656
|
-
console.log(helpDebugHierarchy)
|
1657
|
-
runtime.process.exit(-1)
|
1658
|
-
}
|
1659
|
-
if (args.debugPriority) {
|
1660
|
-
console.log(helpDebugPriority)
|
1661
|
-
runtime.process.exit(-1)
|
1662
|
-
}
|
1663
|
-
if (args.debugBridge) {
|
1664
|
-
console.log(helpDebugBridge)
|
1665
|
-
runtime.process.exit(-1)
|
1666
|
-
}
|
1667
|
-
if (args.debugOperator) {
|
1668
|
-
console.log(helpDebugOperator)
|
1669
|
-
runtime.process.exit(-1)
|
1670
|
-
}
|
1671
1317
|
|
1672
|
-
|
1673
|
-
|
1674
|
-
|
1675
|
-
|
1318
|
+
if (args.clean) {
|
1319
|
+
const tests = JSON.parse(runtime.fs.readFileSync(testConfig.name))
|
1320
|
+
for (const test of tests) {
|
1321
|
+
delete test.associations
|
1322
|
+
}
|
1323
|
+
writeTestFile(testConfig.name, tests)
|
1324
|
+
console.log(`Cleaned ${testConfig.name}`)
|
1325
|
+
return
|
1676
1326
|
}
|
1677
|
-
writeTestFile(testConfig.name, tests)
|
1678
|
-
console.log(`Cleaned ${testConfig.name}`)
|
1679
|
-
return
|
1680
|
-
}
|
1681
1327
|
|
1682
|
-
|
1683
|
-
|
1684
|
-
|
1685
|
-
|
1686
|
-
|
1687
|
-
|
1688
|
-
|
1328
|
+
if (args.deleteTest) {
|
1329
|
+
let tests = JSON.parse(runtime.fs.readFileSync(testConfig.name))
|
1330
|
+
tests = tests.filter((test) => test.query !== args.deleteTest)
|
1331
|
+
writeTestFile(testConfig.name, tests)
|
1332
|
+
console.log(`Remove the test for "${args.deleteTest}"`)
|
1333
|
+
return
|
1334
|
+
}
|
1689
1335
|
|
1690
|
-
|
1691
|
-
|
1692
|
-
|
1693
|
-
|
1694
|
-
|
1695
|
-
|
1696
|
-
|
1697
|
-
|
1698
|
-
|
1699
|
-
|
1336
|
+
const options = { rebuild: false }
|
1337
|
+
if (args.rebuildTemplate) {
|
1338
|
+
options.rebuild = true
|
1339
|
+
}
|
1340
|
+
if (args.greg) {
|
1341
|
+
config.server('http://localhost:3000', '6804954f-e56d-471f-bbb8-08e3c54d9321')
|
1342
|
+
}
|
1343
|
+
if (args.server) {
|
1344
|
+
config.server(args.server)
|
1345
|
+
}
|
1700
1346
|
|
1701
|
-
|
1702
|
-
|
1703
|
-
|
1347
|
+
if (args.queryParams) {
|
1348
|
+
config.setQueryParams(args.queryParams)
|
1349
|
+
}
|
1704
1350
|
|
1705
|
-
|
1706
|
-
|
1707
|
-
|
1351
|
+
if (args.debug) {
|
1352
|
+
config.config.debug = true
|
1353
|
+
}
|
1708
1354
|
|
1709
|
-
|
1710
|
-
|
1711
|
-
|
1355
|
+
if (args.reset) {
|
1356
|
+
config.config.skip_cache = true
|
1357
|
+
}
|
1712
1358
|
|
1713
|
-
|
1714
|
-
|
1715
|
-
|
1359
|
+
if (args.explainPriorities) {
|
1360
|
+
config.config.explain_priorities = true
|
1361
|
+
}
|
1716
1362
|
|
1717
|
-
|
1363
|
+
config.config.debugIncludeConvolutions = args.debugIncludeConvolutions || process.argv.includes('--debugIncludeConvolutions') || process.argv.includes('-dic')
|
1718
1364
|
|
1719
|
-
|
1720
|
-
|
1721
|
-
|
1722
|
-
|
1723
|
-
}
|
1724
|
-
configPrinted = true
|
1725
|
-
if (args.print) {
|
1726
|
-
if (args.print.includes('t')) {
|
1727
|
-
console.log('Test queries')
|
1728
|
-
let counter = 0
|
1729
|
-
for (const test of config.tests) {
|
1730
|
-
console.log(`${counter} - ${test.query}`)
|
1731
|
-
counter += 1
|
1732
|
-
}
|
1733
|
-
}
|
1734
|
-
if (args.print.includes('c')) {
|
1735
|
-
const { data } = setupProcessB({ config })
|
1736
|
-
console.log('Config as sent to server')
|
1737
|
-
console.log(JSON.stringify(data, null, 2))
|
1365
|
+
let configPrinted = false
|
1366
|
+
const printConfig = () => {
|
1367
|
+
if (configPrinted) {
|
1368
|
+
return
|
1738
1369
|
}
|
1370
|
+
configPrinted = true
|
1371
|
+
if (args.print) {
|
1372
|
+
if (args.print.includes('t')) {
|
1373
|
+
console.log('Test queries')
|
1374
|
+
let counter = 0
|
1375
|
+
for (const test of config.tests) {
|
1376
|
+
console.log(`${counter} - ${test.query}`)
|
1377
|
+
counter += 1
|
1378
|
+
}
|
1379
|
+
}
|
1380
|
+
if (args.print.includes('c')) {
|
1381
|
+
const { data } = setupProcessB({ config })
|
1382
|
+
console.log('Config as sent to server')
|
1383
|
+
console.log(JSON.stringify(data, null, 2))
|
1384
|
+
}
|
1739
1385
|
|
1740
|
-
|
1741
|
-
|
1742
|
-
|
1743
|
-
|
1386
|
+
if (args.print.includes('l')) {
|
1387
|
+
console.log('Module load ordering')
|
1388
|
+
for (const km of config.configs) {
|
1389
|
+
console.log(` ${km.name}`)
|
1390
|
+
}
|
1744
1391
|
}
|
1745
|
-
|
1746
|
-
|
1747
|
-
|
1748
|
-
|
1392
|
+
if (args.print.includes('w')) {
|
1393
|
+
// { literals: Object, patterns: Array(2), hierarchy: Array(97) }
|
1394
|
+
console.log('literals')
|
1395
|
+
for (const word in config.config.words.literals) {
|
1396
|
+
console.log(' ' + word.concat(...config.config.words.literals[word].map((def, i) => ((i > 0) ? ' '.repeat(4+word.length) : ' ') + JSON.stringify(def) + '\n')))
|
1397
|
+
}
|
1398
|
+
console.log('patterns')
|
1399
|
+
for (const pattern of config.config.words.patterns) {
|
1400
|
+
console.log(' ' + JSON.stringify(pattern))
|
1401
|
+
}
|
1749
1402
|
}
|
1750
|
-
|
1751
|
-
|
1752
|
-
|
1753
|
-
|
1403
|
+
if (args.print.includes('b')) {
|
1404
|
+
for (const bridge of config.config.bridges) {
|
1405
|
+
console.log(JSON.stringify(bridge))
|
1406
|
+
}
|
1754
1407
|
}
|
1755
|
-
|
1756
|
-
|
1757
|
-
|
1758
|
-
|
1408
|
+
if (args.print.includes('o')) {
|
1409
|
+
for (const operator of config.config.operators) {
|
1410
|
+
console.log(JSON.stringify(operator))
|
1411
|
+
}
|
1759
1412
|
}
|
1760
|
-
|
1761
|
-
|
1762
|
-
|
1763
|
-
|
1764
|
-
|
1765
|
-
|
1766
|
-
|
1767
|
-
|
1768
|
-
|
1769
|
-
|
1770
|
-
|
1771
|
-
|
1413
|
+
if (args.print.includes('j')) {
|
1414
|
+
const { data } = setupProcessB({ config })
|
1415
|
+
console.log(JSON.stringify(data, null, 2))
|
1416
|
+
}
|
1417
|
+
if (args.print.includes('a')) {
|
1418
|
+
console.log('associations ================')
|
1419
|
+
const properties = ['negative', 'positive']
|
1420
|
+
for (const property of properties) {
|
1421
|
+
console.log(` ${property} ===============`)
|
1422
|
+
for (const association of config.config.associations[property]) {
|
1423
|
+
console.log(` ${JSON.stringify(association)}`)
|
1424
|
+
}
|
1772
1425
|
}
|
1773
1426
|
}
|
1774
|
-
|
1775
|
-
|
1776
|
-
console.log(JSON.stringify(config.config.objects, null, 2))
|
1777
|
-
}
|
1778
|
-
if (args.print.includes('p')) {
|
1779
|
-
for (const priority of config.config.priorities) {
|
1780
|
-
console.log(JSON.stringify(priority))
|
1427
|
+
if (args.print.includes('d')) {
|
1428
|
+
console.log(JSON.stringify(config.config.objects, null, 2))
|
1781
1429
|
}
|
1782
|
-
|
1783
|
-
|
1784
|
-
|
1785
|
-
|
1430
|
+
if (args.print.includes('p')) {
|
1431
|
+
for (const priority of config.config.priorities) {
|
1432
|
+
console.log(JSON.stringify(priority))
|
1433
|
+
}
|
1786
1434
|
}
|
1787
|
-
|
1788
|
-
|
1789
|
-
|
1790
|
-
for (const semantic of easyToRead) {
|
1791
|
-
semantic.match = semantic.match.toString()
|
1792
|
-
semantic.apply = semantic.apply.toString()
|
1793
|
-
if (semantic.applyWrapped) {
|
1794
|
-
semantic.applyWrapped = semantic.applyWrapped.toString()
|
1435
|
+
if (args.print.includes('h')) {
|
1436
|
+
for (const edge of config.config.hierarchy) {
|
1437
|
+
console.log(JSON.stringify(edge))
|
1795
1438
|
}
|
1796
1439
|
}
|
1797
|
-
|
1798
|
-
|
1799
|
-
|
1800
|
-
|
1801
|
-
|
1802
|
-
|
1803
|
-
|
1440
|
+
if (args.print.includes('g')) {
|
1441
|
+
const easyToRead = _.cloneDeep(config.config.generators)
|
1442
|
+
for (const semantic of easyToRead) {
|
1443
|
+
semantic.match = semantic.match.toString()
|
1444
|
+
semantic.apply = semantic.apply.toString()
|
1445
|
+
if (semantic.applyWrapped) {
|
1446
|
+
semantic.applyWrapped = semantic.applyWrapped.toString()
|
1447
|
+
}
|
1448
|
+
}
|
1449
|
+
console.dir(easyToRead)
|
1450
|
+
}
|
1451
|
+
if (args.print.includes('s')) {
|
1452
|
+
const easyToRead = _.cloneDeep(config.config.semantics)
|
1453
|
+
for (const semantic of easyToRead) {
|
1454
|
+
semantic.match = semantic.match.toString()
|
1455
|
+
semantic.apply = semantic.apply.toString()
|
1456
|
+
}
|
1457
|
+
console.dir(easyToRead)
|
1804
1458
|
}
|
1805
|
-
console.dir(easyToRead)
|
1806
1459
|
}
|
1807
1460
|
}
|
1808
|
-
}
|
1809
1461
|
|
1810
|
-
|
1462
|
+
checkTemplate(template)
|
1811
1463
|
|
1812
|
-
|
1813
|
-
|
1814
|
-
|
1815
|
-
|
1816
|
-
|
1817
|
-
|
1818
|
-
|
1819
|
-
|
1820
|
-
|
1464
|
+
if (template) {
|
1465
|
+
let needsRebuild
|
1466
|
+
if (args.rebuildTemplate && !args.rebuildTemplateFull) {
|
1467
|
+
// get the startOfChanges for the partial rebuild
|
1468
|
+
needsRebuild = config.needsRebuild(template.template, template.instance, { ...options, rebuild: false })
|
1469
|
+
} else {
|
1470
|
+
// do a check or full rebuild
|
1471
|
+
needsRebuild = config.needsRebuild(template.template, template.instance, options)
|
1472
|
+
}
|
1821
1473
|
|
1822
|
-
|
1823
|
-
|
1824
|
-
|
1474
|
+
if (needsRebuild.needsRebuild) {
|
1475
|
+
if (needsRebuild.previousResultss) {
|
1476
|
+
console.log('Rebuild using the optimization to use previous results until a change is hit. For a full rebuild use -rtf')
|
1477
|
+
}
|
1478
|
+
console.log(`This module "${config.name}" needs rebuilding all other arguments will be ignored. Try again after the template is rebuilt.`)
|
1479
|
+
options.rebuild = true
|
1480
|
+
config.config.rebuild = true
|
1481
|
+
}
|
1482
|
+
try {
|
1483
|
+
await config.load(rebuildTemplate, template.template, template.instance, { rebuild: needsRebuild.needsRebuild || options.rebuild, previousResultss: needsRebuild.previousResultss, startOfChanges: needsRebuild.startOfChanges })
|
1484
|
+
} catch (e) {
|
1485
|
+
console.error(`Error loading template for ${config.name}. ${e.error ? e.error : e}${e.stack ? e.stack : ''}`)
|
1486
|
+
runtime.process.exit(-1)
|
1487
|
+
}
|
1488
|
+
if (!args.query) {
|
1489
|
+
printConfig()
|
1490
|
+
}
|
1491
|
+
if (needsRebuild.needsRebuild) {
|
1492
|
+
return
|
1825
1493
|
}
|
1826
|
-
console.log(`This module "${config.name}" needs rebuilding all other arguments will be ignored. Try again after the template is rebuilt.`)
|
1827
|
-
options.rebuild = true
|
1828
|
-
config.config.rebuild = true
|
1829
1494
|
}
|
1830
|
-
|
1831
|
-
|
1832
|
-
|
1833
|
-
console.error(`Error loading template for ${config.name}. ${e.error ? e.error : e}${e.stack ? e.stack : ''}`)
|
1834
|
-
runtime.process.exit(-1)
|
1495
|
+
|
1496
|
+
if (args.bypassCache) {
|
1497
|
+
config.config.retrain = true
|
1835
1498
|
}
|
1836
|
-
|
1837
|
-
|
1499
|
+
|
1500
|
+
if (args.saveDeveloper) {
|
1501
|
+
args.save = true
|
1838
1502
|
}
|
1839
|
-
if (
|
1840
|
-
|
1503
|
+
if (args.test || args.testVerbose || args.testAllVerbose || args.save) {
|
1504
|
+
global.transitoryMode = true
|
1841
1505
|
}
|
1842
|
-
|
1843
|
-
|
1844
|
-
|
1845
|
-
|
1846
|
-
|
1847
|
-
|
1848
|
-
|
1849
|
-
|
1850
|
-
|
1851
|
-
|
1852
|
-
|
1853
|
-
|
1854
|
-
|
1855
|
-
|
1856
|
-
|
1857
|
-
} else if (args.test || args.testVerbose || args.testAllVerbose) {
|
1858
|
-
// TODO make test always a string
|
1859
|
-
if (typeof test === 'string') {
|
1860
|
-
const l = (n, hasError) => {
|
1861
|
-
if (n === 0) {
|
1862
|
-
if (hasError) {
|
1863
|
-
runtime.process.exit(-1)
|
1506
|
+
if (!args.query && !args.test && !args.info && (args.save || args.saveDeveloper)) {
|
1507
|
+
global.transitoryMode = true
|
1508
|
+
await saveTests(config, test, testConfig, args.saveDeveloper)
|
1509
|
+
// } else if (args.build) {
|
1510
|
+
} else if (args.info) {
|
1511
|
+
showInfo(description, section, config)
|
1512
|
+
} else if (args.test || args.testVerbose || args.testAllVerbose) {
|
1513
|
+
// TODO make test always a string
|
1514
|
+
if (typeof test === 'string') {
|
1515
|
+
const l = async (n, hasError) => {
|
1516
|
+
if (n === 0) {
|
1517
|
+
if (hasError) {
|
1518
|
+
runtime.process.exit(-1)
|
1519
|
+
}
|
1520
|
+
return
|
1864
1521
|
}
|
1865
|
-
|
1866
|
-
|
1867
|
-
|
1868
|
-
|
1869
|
-
|
1870
|
-
|
1871
|
-
|
1872
|
-
|
1873
|
-
|
1874
|
-
|
1875
|
-
|
1876
|
-
|
1877
|
-
|
1878
|
-
|
1879
|
-
|
1880
|
-
if (JSON.stringify(result.expected.paraphrases) !== JSON.stringify(result.actual.paraphrases)) {
|
1881
|
-
result.hasError = true
|
1882
|
-
}
|
1883
|
-
if (!args.testNoParenthesized) {
|
1884
|
-
if (JSON.stringify(result.expected.paraphrasesParenthesized) !== JSON.stringify(result.actual.paraphrasesParenthesized)) {
|
1522
|
+
let useTestConfig = testConfig
|
1523
|
+
if (args.testModuleName) {
|
1524
|
+
useTestConfig = config.getConfigs()[args.testModuleName].getTestConfig()
|
1525
|
+
useTestConfig.testModuleName = args.testModuleName
|
1526
|
+
test = useTestConfig.name
|
1527
|
+
}
|
1528
|
+
const timings = { server: 0, client: 0 }
|
1529
|
+
await runTests(config, test, { timings, args, debug: args.debug, testConfig: useTestConfig, verbose: args.testVerbose || args.testAllVerbose, stopAtFirstError: !args.testAllVerbose }).then((results) => {
|
1530
|
+
let newError = false
|
1531
|
+
if (results.length > 0) {
|
1532
|
+
let headerShown = false
|
1533
|
+
|
1534
|
+
let hasError = false
|
1535
|
+
for (const result of results) {
|
1536
|
+
if (JSON.stringify(result.expected.paraphrases) !== JSON.stringify(result.actual.paraphrases)) {
|
1885
1537
|
result.hasError = true
|
1886
1538
|
}
|
1887
|
-
if (
|
1539
|
+
if (!args.testNoParenthesized) {
|
1540
|
+
if (JSON.stringify(result.expected.paraphrasesParenthesized) !== JSON.stringify(result.actual.paraphrasesParenthesized)) {
|
1541
|
+
result.hasError = true
|
1542
|
+
}
|
1543
|
+
if (JSON.stringify(result.expected.generatedParenthesized) !== JSON.stringify(result.actual.generatedParenthesized)) {
|
1544
|
+
result.hasError = true
|
1545
|
+
}
|
1546
|
+
}
|
1547
|
+
if (JSON.stringify(result.expected.responses) !== JSON.stringify(result.actual.responses)) {
|
1888
1548
|
result.hasError = true
|
1889
1549
|
}
|
1550
|
+
if (JSON.stringify(result.expected.checked) !== JSON.stringify(result.actual.checked)) {
|
1551
|
+
result.hasError = true
|
1552
|
+
}
|
1553
|
+
if (!sameJSON(result.expected.checkedContexts, result.actual.checkedContexts)) {
|
1554
|
+
result.hasError = true
|
1555
|
+
}
|
1556
|
+
if (result.hasError) {
|
1557
|
+
hasError = true
|
1558
|
+
}
|
1890
1559
|
}
|
1891
|
-
if (JSON.stringify(result.expected.responses) !== JSON.stringify(result.actual.responses)) {
|
1892
|
-
result.hasError = true
|
1893
|
-
}
|
1894
|
-
if (JSON.stringify(result.expected.checked) !== JSON.stringify(result.actual.checked)) {
|
1895
|
-
result.hasError = true
|
1896
|
-
}
|
1897
|
-
if (!sameJSON(result.expected.checkedContexts, result.actual.checkedContexts)) {
|
1898
|
-
result.hasError = true
|
1899
|
-
}
|
1900
|
-
if (result.hasError) {
|
1901
|
-
hasError = true
|
1902
|
-
}
|
1903
|
-
}
|
1904
1560
|
|
1905
|
-
|
1906
|
-
console.log(
|
1907
|
-
|
1908
|
-
console.log('
|
1909
|
-
const
|
1910
|
-
|
1561
|
+
|
1562
|
+
console.log(`Total Server Time: ${timings.server.toFixed(2)}. Total Client Time: ${timings.client.toFixed(2)}`)
|
1563
|
+
if (hasError) {
|
1564
|
+
console.log('**************************** ERRORS ************************')
|
1565
|
+
for (const result of results) {
|
1566
|
+
console.log('Utterance: ', result.utterance)
|
1567
|
+
const show = (label, expected, actual) => {
|
1568
|
+
if (JSON.stringify(expected) !== JSON.stringify(actual)) {
|
1569
|
+
if (!headerShown) {
|
1570
|
+
console.log(' Failure')
|
1571
|
+
}
|
1572
|
+
console.log(` expected ${label}`, expected)
|
1573
|
+
console.log(` actual ${label} `, actual)
|
1574
|
+
newError = true
|
1575
|
+
headerShown = true
|
1576
|
+
if (args.vimdiff) {
|
1577
|
+
vimdiff(actual, expected, `"${result.utterance}" - ${label}`)
|
1578
|
+
}
|
1579
|
+
result.hasError = true
|
1580
|
+
}
|
1581
|
+
}
|
1582
|
+
show('paraphrases', result.expected.paraphrases, result.actual.paraphrases)
|
1583
|
+
if (!args.testNoParenthesized) {
|
1584
|
+
show('paraphrases parenthesized', result.expected.paraphrasesParenthesized, result.actual.paraphrasesParenthesized)
|
1585
|
+
}
|
1586
|
+
show('responses', result.expected.responses, result.actual.responses)
|
1587
|
+
if (!args.testNoParenthesized) {
|
1588
|
+
show('responses parenthesized', result.expected.generatedParenthesized, result.actual.generatedParenthesized)
|
1589
|
+
}
|
1590
|
+
/*
|
1591
|
+
if (JSON.stringify(result.expected.paraphrases) !== JSON.stringify(result.actual.paraphrases)) {
|
1911
1592
|
if (!headerShown) {
|
1912
1593
|
console.log(' Failure')
|
1913
1594
|
}
|
1914
|
-
console.log(
|
1915
|
-
console.log(
|
1595
|
+
console.log(' expected paraphrases', result.expected.paraphrases)
|
1596
|
+
console.log(' actual paraphrases ', result.actual.paraphrases)
|
1916
1597
|
newError = true
|
1917
1598
|
headerShown = true
|
1918
|
-
if (args.vimdiff) {
|
1919
|
-
vimdiff(actual, expected, `"${result.utterance}" - ${label}`)
|
1920
|
-
}
|
1921
|
-
result.hasError = true
|
1922
|
-
}
|
1923
|
-
}
|
1924
|
-
show('paraphrases', result.expected.paraphrases, result.actual.paraphrases)
|
1925
|
-
if (!args.testNoParenthesized) {
|
1926
|
-
show('paraphrases parenthesized', result.expected.paraphrasesParenthesized, result.actual.paraphrasesParenthesized)
|
1927
|
-
}
|
1928
|
-
show('responses', result.expected.responses, result.actual.responses)
|
1929
|
-
if (!args.testNoParenthesized) {
|
1930
|
-
show('responses parenthesized', result.expected.generatedParenthesized, result.actual.generatedParenthesized)
|
1931
|
-
}
|
1932
|
-
/*
|
1933
|
-
if (JSON.stringify(result.expected.paraphrases) !== JSON.stringify(result.actual.paraphrases)) {
|
1934
|
-
if (!headerShown) {
|
1935
|
-
console.log(' Failure')
|
1936
1599
|
}
|
1937
|
-
|
1938
|
-
|
1939
|
-
|
1940
|
-
|
1941
|
-
|
1942
|
-
|
1943
|
-
|
1944
|
-
|
1600
|
+
if (JSON.stringify(result.expected.responses) !== JSON.stringify(result.actual.responses)) {
|
1601
|
+
if (!headerShown) {
|
1602
|
+
console.log(' Failure')
|
1603
|
+
}
|
1604
|
+
console.log(' expected responses ', result.expected.responses)
|
1605
|
+
console.log(' actual responses ', result.actual.responses)
|
1606
|
+
newError = true
|
1607
|
+
headerShown = true
|
1945
1608
|
}
|
1946
|
-
|
1947
|
-
|
1948
|
-
|
1949
|
-
|
1950
|
-
|
1951
|
-
|
1952
|
-
|
1953
|
-
|
1954
|
-
|
1609
|
+
*/
|
1610
|
+
if (JSON.stringify(result.expected.checked) !== JSON.stringify(result.actual.checked)) {
|
1611
|
+
if (!headerShown) {
|
1612
|
+
console.log(' Failure')
|
1613
|
+
}
|
1614
|
+
const widths = [4, 18, 72]
|
1615
|
+
const lines = new Lines(widths)
|
1616
|
+
lines.setElement(1, 1, 'expected checked objects')
|
1617
|
+
lines.setElement(2, 2, JSON.stringify(result.expected.checked, null, 2))
|
1618
|
+
lines.log()
|
1619
|
+
lines.setElement(1, 1, 'actual checked objects')
|
1620
|
+
lines.setElement(2, 2, JSON.stringify(result.actual.checked, null, 2))
|
1621
|
+
lines.log()
|
1622
|
+
if (args.vimdiff) {
|
1623
|
+
show('checked properties for objects', result.expected.checked, result.actual.checked)
|
1624
|
+
}
|
1625
|
+
newError = true
|
1626
|
+
headerShown = true
|
1955
1627
|
}
|
1956
|
-
|
1957
|
-
|
1958
|
-
|
1959
|
-
|
1960
|
-
|
1961
|
-
|
1962
|
-
|
1963
|
-
|
1964
|
-
|
1965
|
-
|
1628
|
+
if (!sameJSON(result.expected.checkedContexts, result.actual.checkedContexts)) {
|
1629
|
+
if (!headerShown) {
|
1630
|
+
console.log(' Failure')
|
1631
|
+
}
|
1632
|
+
const widths = [4, 18, 72]
|
1633
|
+
const lines = new Lines(widths)
|
1634
|
+
lines.setElement(1, 1, 'expected checked contexts', true)
|
1635
|
+
lines.setElement(2, 2, JSON.stringify(result.expected.checkedContexts, null, 2))
|
1636
|
+
lines.log()
|
1637
|
+
lines.setElement(1, 1, 'actual checked contexts', true)
|
1638
|
+
lines.setElement(2, 2, JSON.stringify(result.actual.checkedContexts, null, 2))
|
1639
|
+
lines.log()
|
1640
|
+
if (args.vimdiff) {
|
1641
|
+
show('checked properties for context', result.expected.checkedContexts, result.actual.checkedContexts)
|
1642
|
+
}
|
1643
|
+
newError = true
|
1644
|
+
headerShown = true
|
1966
1645
|
}
|
1967
|
-
newError = true
|
1968
|
-
headerShown = true
|
1969
1646
|
}
|
1970
|
-
|
1971
|
-
|
1972
|
-
|
1647
|
+
} else {
|
1648
|
+
if (results.length > 0 && args.vimdiff) {
|
1649
|
+
for (const result of results) {
|
1650
|
+
vimdiff(result.actual, result.expected)
|
1973
1651
|
}
|
1974
|
-
const widths = [4, 18, 72]
|
1975
|
-
const lines = new Lines(widths)
|
1976
|
-
lines.setElement(1, 1, 'expected checked contexts', true)
|
1977
|
-
lines.setElement(2, 2, JSON.stringify(result.expected.checkedContexts, null, 2))
|
1978
|
-
lines.log()
|
1979
|
-
lines.setElement(1, 1, 'actual checked contexts', true)
|
1980
|
-
lines.setElement(2, 2, JSON.stringify(result.actual.checkedContexts, null, 2))
|
1981
|
-
lines.log()
|
1982
|
-
if (args.vimdiff) {
|
1983
|
-
vimdiff(result.actual.checkedContexts, result.expected.checkedContexts)
|
1984
|
-
}
|
1985
|
-
newError = true
|
1986
|
-
headerShown = true
|
1987
1652
|
}
|
1988
1653
|
}
|
1989
|
-
|
1990
|
-
|
1991
|
-
|
1992
|
-
|
1654
|
+
if (hasError) {
|
1655
|
+
if (!headerShown) {
|
1656
|
+
if (!(useTestConfig.check && useTestConfig.check.length > 0)) {
|
1657
|
+
console.log('There are failures due to things other than paraphrases, responses and checked properties being different. They are not shown because you ran -tv or -tva which only shows difference in paraphrase and results. Usually what I do is -s and do a diff to make sure there are no other problems. If the paraphrases or results were different they would have shown here.')
|
1658
|
+
}
|
1993
1659
|
}
|
1994
|
-
}
|
1995
|
-
}
|
1996
|
-
if (hasError) {
|
1997
|
-
if (!headerShown) {
|
1998
1660
|
if (!(useTestConfig.check && useTestConfig.check.length > 0)) {
|
1999
|
-
console.log('
|
2000
|
-
|
2001
|
-
|
2002
|
-
|
2003
|
-
|
2004
|
-
|
2005
|
-
|
2006
|
-
|
2007
|
-
if (result.hasError) {
|
2008
|
-
errorCount += 1
|
1661
|
+
console.log('use -v arg to write files expected.json and actual.json in the current directory for detailed comparison. Or do -s and then git diff the changes.')
|
1662
|
+
// console.log(JSON.stringify(contexts))
|
1663
|
+
let errorCount = 0
|
1664
|
+
for (const result of results) {
|
1665
|
+
if (result.hasError) {
|
1666
|
+
console.log(`FAILED ${result.utterance}`)
|
1667
|
+
errorCount += 1
|
1668
|
+
}
|
2009
1669
|
}
|
1670
|
+
console.log(`**************************** THERE WERE ${errorCount} TEST FAILURES ************************`)
|
2010
1671
|
}
|
2011
|
-
console.log(`**************************** THERE WERE ${errorCount} TEST FAILURES ************************`)
|
2012
1672
|
}
|
2013
1673
|
}
|
2014
|
-
|
2015
|
-
|
2016
|
-
|
2017
|
-
|
2018
|
-
|
2019
|
-
|
2020
|
-
|
1674
|
+
// const contexts = { failures: results }
|
1675
|
+
l(n - 1, hasError || newError)
|
1676
|
+
}).catch((error) => {
|
1677
|
+
console.error(error)
|
1678
|
+
runtime.process.exit(-1)
|
1679
|
+
errorHandler(error)
|
1680
|
+
})
|
1681
|
+
}
|
1682
|
+
await l(args.count, false)
|
1683
|
+
} else {
|
1684
|
+
test()
|
1685
|
+
}
|
1686
|
+
} else if (args.loop) {
|
1687
|
+
const readline = runtime.readline.createInterface({ input: runtime.process.stdin, output: runtime.process.stdout })
|
1688
|
+
const f = () => readline.question('Enter query? (newline to quit) ', query => {
|
1689
|
+
query = query.trim()
|
1690
|
+
if (query.length === 0) {
|
1691
|
+
return readline.close()
|
1692
|
+
}
|
1693
|
+
const promise = _process(config, query, { testsFN: test }).then((results) => {
|
1694
|
+
console.log(results.responses.join(' '))
|
2021
1695
|
})
|
1696
|
+
if (!('then' in promise)) {
|
1697
|
+
throw new Error('Return a promise from process in the definition of knowledgeModule')
|
1698
|
+
}
|
1699
|
+
promise
|
1700
|
+
.then(() => {
|
1701
|
+
f()
|
1702
|
+
})
|
1703
|
+
.catch((e) => {
|
1704
|
+
if (e.errno == 'ECONNREFUSED') {
|
1705
|
+
console.log(e)
|
1706
|
+
readline.close()
|
1707
|
+
} else {
|
1708
|
+
console.log(e)
|
1709
|
+
f()
|
1710
|
+
}
|
1711
|
+
})
|
1712
|
+
})
|
1713
|
+
f()
|
1714
|
+
} else if (args.query) {
|
1715
|
+
let useTestConfig = testConfig
|
1716
|
+
if (args.testModuleName) {
|
1717
|
+
config.testConfig.testModuleName = args.testModuleName
|
1718
|
+
config.testConfig.checks = config.getConfigs()[args.testModuleName].getTestConfig().checks
|
1719
|
+
// useTestConfig = config.getConfigs()[args.testModuleName].getTestConfig()
|
1720
|
+
// useTestConfig.testModuleName = args.testModuleName
|
2022
1721
|
}
|
2023
|
-
|
2024
|
-
|
2025
|
-
|
2026
|
-
|
2027
|
-
} else if (args.loop) {
|
2028
|
-
const readline = runtime.readline.createInterface({ input: runtime.process.stdin, output: runtime.process.stdout })
|
2029
|
-
const f = () => readline.question('Enter query? (newline to quit) ', query => {
|
2030
|
-
query = query.trim()
|
2031
|
-
if (query.length === 0) {
|
2032
|
-
return readline.close()
|
1722
|
+
const objects = getObjects(config.config.objects)(config.uuid)
|
1723
|
+
// for the compare
|
1724
|
+
if (args.objectDiff) {
|
1725
|
+
global.beforeObjects = _.cloneDeep(objects)
|
2033
1726
|
}
|
2034
|
-
|
2035
|
-
|
2036
|
-
})
|
2037
|
-
|
2038
|
-
throw new Error('Return a promise from process in the definition of knowledgeModule')
|
1727
|
+
try {
|
1728
|
+
await processResults(_process(config, args.query, { commandLineArgs: args, dontAddAssociations: args.dontAddAssociations, writeTests: args.save || args.saveDeveloper, saveDeveloper: args.saveDeveloper, testConfig, testsFN: test }))
|
1729
|
+
} catch (error) {
|
1730
|
+
console.log('Error', error)
|
2039
1731
|
}
|
2040
|
-
promise
|
2041
|
-
.then(() => {
|
2042
|
-
f()
|
2043
|
-
})
|
2044
|
-
.catch((e) => {
|
2045
|
-
if (e.errno == 'ECONNREFUSED') {
|
2046
|
-
console.log(e)
|
2047
|
-
readline.close()
|
2048
|
-
} else {
|
2049
|
-
console.log(e)
|
2050
|
-
f()
|
2051
|
-
}
|
2052
|
-
})
|
2053
|
-
})
|
2054
|
-
f()
|
2055
|
-
} else if (args.query) {
|
2056
|
-
let useTestConfig = testConfig
|
2057
|
-
if (args.testModuleName) {
|
2058
|
-
config.testConfig.testModuleName = args.testModuleName
|
2059
|
-
config.testConfig.checks = config.getConfigs()[args.testModuleName].getTestConfig().checks
|
2060
|
-
// useTestConfig = config.getConfigs()[args.testModuleName].getTestConfig()
|
2061
|
-
// useTestConfig.testModuleName = args.testModuleName
|
2062
1732
|
}
|
2063
|
-
|
2064
|
-
|
2065
|
-
if (
|
2066
|
-
|
2067
|
-
}
|
2068
|
-
try {
|
2069
|
-
await processResults(_process(config, args.query, { commandLineArgs: args, dontAddAssociations: args.dontAddAssociations, writeTests: args.save || args.saveDeveloper, saveDeveloper: args.saveDeveloper, testConfig, testsFN: test }))
|
2070
|
-
} catch (error) {
|
2071
|
-
console.log('Error', error)
|
1733
|
+
printConfig()
|
1734
|
+
} finally {
|
1735
|
+
if (config) {
|
1736
|
+
config.terminate()
|
2072
1737
|
}
|
2073
1738
|
}
|
2074
|
-
printConfig()
|
2075
1739
|
} else {
|
2076
|
-
const initConfig = (config) => {
|
1740
|
+
const initConfig = async (config) => {
|
2077
1741
|
if (template) {
|
2078
1742
|
if (config.needsRebuild(template.template, template.instance, { isModule: !isProcess }).needsRebuild) {
|
1743
|
+
debugger
|
1744
|
+
config.needsRebuild(template.template, template.instance, { isModule: !isProcess })
|
2079
1745
|
const error = `This module "${config.name}" cannot be used because the instance file needs rebuilding. Run on the command line with no arguments or the -rt argument to rebuild.`
|
2080
1746
|
throw new Error(error)
|
2081
1747
|
}
|
@@ -2108,24 +1774,21 @@ const knowledgeModuleImpl = async ({
|
|
2108
1774
|
|
2109
1775
|
if (template) {
|
2110
1776
|
try {
|
2111
|
-
config.load(template.template, template.instance)
|
1777
|
+
await config.load(rebuildTemplate, template.template, template.instance)
|
2112
1778
|
} catch (e) {
|
2113
1779
|
errorHandler(e)
|
2114
1780
|
}
|
2115
1781
|
}
|
2116
1782
|
}
|
2117
1783
|
|
2118
|
-
|
2119
|
-
|
1784
|
+
// no cache 21 minutes + rebuild fails "node tester_rebuild -m colors"
|
1785
|
+
// cache okay
|
1786
|
+
createConfigExport = async () => {
|
1787
|
+
if (false && createConfig.cached) {
|
2120
1788
|
return createConfig.cached
|
2121
1789
|
}
|
2122
|
-
const config = createConfig(
|
2123
|
-
|
2124
|
-
config.stop_auto_rebuild()
|
2125
|
-
additionalConfig(config)
|
2126
|
-
config.restart_auto_rebuild()
|
2127
|
-
}
|
2128
|
-
initConfig(config)
|
1790
|
+
const config = await createConfig()
|
1791
|
+
await initConfig(config)
|
2129
1792
|
// config.rebuild({ isModule: true })
|
2130
1793
|
createConfig.cached = config
|
2131
1794
|
return createConfig.cached
|
@@ -2154,11 +1817,6 @@ const ensureTestFile = (module, name, type) => {
|
|
2154
1817
|
}
|
2155
1818
|
}
|
2156
1819
|
|
2157
|
-
function w (func) {
|
2158
|
-
func.where = where(3)
|
2159
|
-
return func
|
2160
|
-
}
|
2161
|
-
|
2162
1820
|
const knowledgeModule = async (...args) => {
|
2163
1821
|
await knowledgeModuleImpl(...args).catch((e) => {
|
2164
1822
|
console.error(e)
|
@@ -2169,9 +1827,6 @@ const knowledgeModule = async (...args) => {
|
|
2169
1827
|
module.exports = {
|
2170
1828
|
process: _process,
|
2171
1829
|
stableId,
|
2172
|
-
where,
|
2173
|
-
w,
|
2174
|
-
// submitBug,
|
2175
1830
|
ensureTestFile,
|
2176
1831
|
rebuildTemplate,
|
2177
1832
|
processContext,
|
@@ -2188,5 +1843,6 @@ module.exports = {
|
|
2188
1843
|
loadInstance,
|
2189
1844
|
gs,
|
2190
1845
|
flattens,
|
2191
|
-
writeTest
|
1846
|
+
writeTest,
|
1847
|
+
getConfigForTest,
|
2192
1848
|
}
|