theprogrammablemind_4wp 8.0.0 → 8.1.0-beta.1

Sign up to get free protection for your applications and to get access to all the features.
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
- return { [testConfigName]: checks }
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
- configForTest.operators = config.config.operators.map((operator) => Object.assign({}, operator, { uuid: undefined }))
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
- configForTest.bridges = config.config.bridges.map((bridge) => Object.assign({}, bridge, { uuid: undefined }))
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 (global.beforeObjects) {
1214
- console.log('objects', runtime.jsonDiff.diffString(global.beforeObjects, config.get('objects')))
1215
- } else {
1216
- console.log('objects', runtime.util.inspect(config.get('objects'), { depth: Infinity, sorted: true }))
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] != query.query) {
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
- // if (!config && !createConfig) {
1525
- if (!createConfig) {
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
- const config = createConfig()
1561
- setupConfig(config)
1562
- processResults = processResults({ config, errorHandler })
1563
- // setup();
1564
- const parser = new runtime.ArgumentParser({
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
- 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]]\''
1569
- 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]]\''
1570
- 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]]\''
1571
- 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}\''
1572
- const helpDebugBridge = 'In order to get a debug break when a specific bridge is created set the DEBUG_BRIDGE environment variable to id/level to break on. For example DEBUG_BRIDGE=\'id#level\''
1573
- 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]))\''
1574
-
1575
- parser.add_argument('-tmn', '--testModuleName', { help: 'When running tests instead of using the current modules tests use the specified modules tests' })
1576
- parser.add_argument('-t', '--test', { action: 'store_true', help: 'Run the tests. Create tests by running with the --query + --save flag' })
1577
- 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' })
1578
- // parser.add_argument('-ttr', '--testToRun', { help: 'Only the specified test will be run' })
1579
- 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' })
1580
- parser.add_argument('-tnp', '--testNoParenthesized', { action: 'store_true', help: 'Don\' check parenthesized differences for the tests' })
1581
- 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' })
1582
- // 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.' })
1583
- 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.' })
1584
- parser.add_argument('-rtf', '--rebuildTemplateFull', { action: 'store_true', help: 'Force a template rebuild. Skip the optimization' })
1585
- parser.add_argument('-l', '--loop', { action: 'store_true', help: 'Run a loop so that multiply queries may be run' })
1586
- parser.add_argument('-i', '--info', { action: 'store_true', help: 'Print meta-data for the module' })
1587
- parser.add_argument('-v', '--vimdiff', { action: 'store_true', help: 'For failures run vimdiff' })
1588
- parser.add_argument('-g', '--greg', { action: 'store_true', help: 'Set the server to be localhost so I can debug stuff' })
1589
- 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]]' })
1590
- parser.add_argument('-r', '--reset', { action: 'store_true', help: 'Get the server to bypass the cache and rebuild everything' })
1591
- parser.add_argument('-q', '--query', { help: 'Run the specified query' })
1592
- parser.add_argument('-ip ', '--server', { help: 'Server to run against' })
1593
- parser.add_argument('-qp ', '--queryParams', { help: 'Query params for the server call' })
1594
- parser.add_argument('-dt', '--deleteTest', { help: 'Delete the specified query from the tests file.' })
1595
- parser.add_argument('--parenthesized', { action: 'store_true', help: 'Show the generated phrases with parenthesis.' })
1596
- parser.add_argument('-c', '--clean', { help: 'Remove data from the test files. a === association' })
1597
- parser.add_argument('-od', '--objectDiff', { action: 'store_true', help: 'When showing the objects use a colour diff' })
1598
- 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' })
1599
- 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.' })
1600
- parser.add_argument('-sd', '--saveDeveloper', { action: 'store_true', help: 'Same as -s but the query will not show up in the info command.' })
1601
- 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 ' })
1602
- parser.add_argument('-d', '--debug', { action: 'store_true', help: 'When running with the --debug flag this set the debug flag in the config' })
1603
- parser.add_argument('-da', '--debugAssociation', { action: 'store_true', help: helpDebugAssociation })
1604
- parser.add_argument('-dh', '--debugHierarchy', { action: 'store_true', help: helpDebugHierarchy })
1605
- parser.add_argument('-dp', '--debugPriority', { action: 'store_true', help: helpDebugPriority })
1606
- parser.add_argument('-dcp', '--debugContextualPriority', { action: 'store_true', help: helpDebugContextualPriority })
1607
- parser.add_argument('-db', '--debugBridge', { action: 'store_true', help: helpDebugBridge })
1608
- parser.add_argument('-do', '--debugOperator', { action: 'store_true', help: helpDebugOperator })
1609
- 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' })
1610
- 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' })
1611
-
1612
- const args = parser.parse_args()
1613
- args.count = args.count || 1
1614
-
1615
- if (args.rebuildTemplateFull) {
1616
- args.rebuildTemplate = true
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
- if (args.parenthesized) {
1620
- config.parenthesized = true
1621
- }
1622
- if (args.checkForLoop) {
1623
- try {
1624
- args.checkForLoop = JSON.parse(args.checkForLoop)
1625
- const isKey = (what) => {
1626
- if (!Array.isArray(what)) {
1627
- return false
1628
- }
1629
- if (what.length !== 2) {
1630
- return false
1631
- }
1632
- if (!typeof what[0] == 'string') {
1633
- return false
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 (!typeof what[1] == 'number') {
1636
- return false
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
- return true
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
- } catch (e) {
1644
- throw new Error(`Error parsing JSON of the checkForLoop argument. ${e}`)
1288
+ } else {
1289
+ if (process.argv.includes('--checkForLoop') || process.argv.includes('-cl')) {
1290
+ args.checkForLoop = true
1291
+ }
1645
1292
  }
1646
- } else {
1647
- if (process.argv.includes('--checkForLoop') || process.argv.includes('-cl')) {
1648
- args.checkForLoop = true
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
- if (args.clean) {
1673
- const tests = JSON.parse(runtime.fs.readFileSync(testConfig.name))
1674
- for (const test of tests) {
1675
- delete test.associations
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
- if (args.deleteTest) {
1683
- let tests = JSON.parse(runtime.fs.readFileSync(testConfig.name))
1684
- tests = tests.filter((test) => test.query !== args.deleteTest)
1685
- writeTestFile(testConfig.name, tests)
1686
- console.log(`Remove the test for "${args.deleteTest}"`)
1687
- return
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
- const options = { rebuild: false }
1691
- if (args.rebuildTemplate) {
1692
- options.rebuild = true
1693
- }
1694
- if (args.greg) {
1695
- config.server('http://localhost:3000', '6804954f-e56d-471f-bbb8-08e3c54d9321')
1696
- }
1697
- if (args.server) {
1698
- config.server(args.server)
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
- if (args.queryParams) {
1702
- config.setQueryParams(args.queryParams)
1703
- }
1347
+ if (args.queryParams) {
1348
+ config.setQueryParams(args.queryParams)
1349
+ }
1704
1350
 
1705
- if (args.debug) {
1706
- config.config.debug = true
1707
- }
1351
+ if (args.debug) {
1352
+ config.config.debug = true
1353
+ }
1708
1354
 
1709
- if (args.reset) {
1710
- config.config.skip_cache = true
1711
- }
1355
+ if (args.reset) {
1356
+ config.config.skip_cache = true
1357
+ }
1712
1358
 
1713
- if (args.explainPriorities) {
1714
- config.config.explain_priorities = true
1715
- }
1359
+ if (args.explainPriorities) {
1360
+ config.config.explain_priorities = true
1361
+ }
1716
1362
 
1717
- config.config.debugIncludeConvolutions = args.debugIncludeConvolutions || process.argv.includes('--debugIncludeConvolutions') || process.argv.includes('-dic')
1363
+ config.config.debugIncludeConvolutions = args.debugIncludeConvolutions || process.argv.includes('--debugIncludeConvolutions') || process.argv.includes('-dic')
1718
1364
 
1719
- let configPrinted = false
1720
- const printConfig = () => {
1721
- if (configPrinted) {
1722
- return
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
- if (args.print.includes('l')) {
1741
- console.log('Module load ordering')
1742
- for (const km of config.configs) {
1743
- console.log(` ${km.name}`)
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
- if (args.print.includes('w')) {
1747
- for (const word in config.config.words) {
1748
- console.log(word.concat(' ', ...config.config.words[word].map((def) => JSON.stringify(def))))
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
- if (args.print.includes('b')) {
1752
- for (const bridge of config.config.bridges) {
1753
- console.log(JSON.stringify(bridge))
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
- if (args.print.includes('o')) {
1757
- for (const operator of config.config.operators) {
1758
- console.log(JSON.stringify(operator))
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
- if (args.print.includes('j')) {
1762
- const { data } = setupProcessB({ config })
1763
- console.log(JSON.stringify(data, null, 2))
1764
- }
1765
- if (args.print.includes('a')) {
1766
- console.log('associations ================')
1767
- const properties = ['negative', 'positive']
1768
- for (const property of properties) {
1769
- console.log(` ${property} ===============`)
1770
- for (const association of config.config.associations[property]) {
1771
- console.log(` ${JSON.stringify(association)}`)
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
- if (args.print.includes('d')) {
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
- if (args.print.includes('h')) {
1784
- for (const edge of config.config.hierarchy) {
1785
- console.log(JSON.stringify(edge))
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
- if (args.print.includes('g')) {
1789
- const easyToRead = _.cloneDeep(config.config.generators)
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
- console.dir(easyToRead)
1798
- }
1799
- if (args.print.includes('s')) {
1800
- const easyToRead = _.cloneDeep(config.config.semantics)
1801
- for (const semantic of easyToRead) {
1802
- semantic.match = semantic.match.toString()
1803
- semantic.apply = semantic.apply.toString()
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
- checkTemplate(template)
1462
+ checkTemplate(template)
1811
1463
 
1812
- if (template) {
1813
- let needsRebuild
1814
- if (args.rebuildTemplate && !args.rebuildTemplateFull) {
1815
- // get the startOfChanges for the partial rebuild
1816
- needsRebuild = config.needsRebuild(template.template, template.instance, { ...options, rebuild: false })
1817
- } else {
1818
- // do a check or full rebuild
1819
- needsRebuild = config.needsRebuild(template.template, template.instance, options)
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
- if (needsRebuild.needsRebuild) {
1823
- if (needsRebuild.previousResultss) {
1824
- console.log('Rebuild using the optimization to use previous results until a change is hit. For a full rebuild use -rtf')
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
- try {
1831
- config.load(template.template, template.instance, { rebuild: needsRebuild.needsRebuild || options.rebuild, previousResultss: needsRebuild.previousResultss, startOfChanges: needsRebuild.startOfChanges })
1832
- } catch (e) {
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
- if (!args.query) {
1837
- printConfig()
1499
+
1500
+ if (args.saveDeveloper) {
1501
+ args.save = true
1838
1502
  }
1839
- if (needsRebuild.needsRebuild) {
1840
- return
1503
+ if (args.test || args.testVerbose || args.testAllVerbose || args.save) {
1504
+ global.transitoryMode = true
1841
1505
  }
1842
- }
1843
-
1844
- if (args.retrain) {
1845
- config.config.retrain = true
1846
- }
1847
-
1848
- if (args.test || args.testVerbose || args.testAllVerbose || args.save) {
1849
- global.transitoryMode = true
1850
- }
1851
- if (!args.query && !args.test && !args.info && (args.save || args.saveDeveloper)) {
1852
- global.transitoryMode = true
1853
- saveTests(config, test, testConfig, args.saveDeveloper)
1854
- // } else if (args.build) {
1855
- } else if (args.info) {
1856
- showInfo(description, section, config)
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
- return
1866
- }
1867
- let useTestConfig = testConfig
1868
- if (args.testModuleName) {
1869
- useTestConfig = config.getConfigs()[args.testModuleName].getTestConfig()
1870
- useTestConfig.testModuleName = args.testModuleName
1871
- test = useTestConfig.name
1872
- }
1873
- runTests(config, test, { args, debug: args.debug, testConfig: useTestConfig, verbose: args.testVerbose || args.testAllVerbose, stopAtFirstError: !args.testAllVerbose }).then((results) => {
1874
- let newError = false
1875
- if (results.length > 0) {
1876
- let headerShown = false
1877
-
1878
- let hasError = false
1879
- for (const result of results) {
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 (JSON.stringify(result.expected.generatedParenthesized) !== JSON.stringify(result.actual.generatedParenthesized)) {
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
- if (hasError) {
1906
- console.log('**************************** ERRORS ************************')
1907
- for (const result of results) {
1908
- console.log('Utterance: ', result.utterance)
1909
- const show = (label, expected, actual) => {
1910
- if (JSON.stringify(expected) !== JSON.stringify(actual)) {
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(` expected ${label}`, expected)
1915
- console.log(` actual ${label} `, actual)
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
- console.log(' expected paraphrases', result.expected.paraphrases)
1938
- console.log(' actual paraphrases ', result.actual.paraphrases)
1939
- newError = true
1940
- headerShown = true
1941
- }
1942
- if (JSON.stringify(result.expected.responses) !== JSON.stringify(result.actual.responses)) {
1943
- if (!headerShown) {
1944
- console.log(' Failure')
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
- console.log(' expected responses ', result.expected.responses)
1947
- console.log(' actual responses ', result.actual.responses)
1948
- newError = true
1949
- headerShown = true
1950
- }
1951
- */
1952
- if (JSON.stringify(result.expected.checked) !== JSON.stringify(result.actual.checked)) {
1953
- if (!headerShown) {
1954
- console.log(' Failure')
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
- const widths = [4, 18, 72]
1957
- const lines = new Lines(widths)
1958
- lines.setElement(1, 1, 'expected checked objects')
1959
- lines.setElement(2, 2, JSON.stringify(result.expected.checked, null, 2))
1960
- lines.log()
1961
- lines.setElement(1, 1, 'actual checked objects')
1962
- lines.setElement(2, 2, JSON.stringify(result.actual.checked, null, 2))
1963
- lines.log()
1964
- if (args.vimdiff) {
1965
- vimdiff(result.actual.checked, result.expected.checked)
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
- if (!sameJSON(result.expected.checkedContexts, result.actual.checkedContexts)) {
1971
- if (!headerShown) {
1972
- console.log(' Failure')
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
- } else {
1990
- if (results.length > 0 && args.vimdiff) {
1991
- for (const result of results) {
1992
- vimdiff(result.actual, result.expected)
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('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.')
2000
- }
2001
- }
2002
- if (!(useTestConfig.check && useTestConfig.check.length > 0)) {
2003
- 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.')
2004
- // console.log(JSON.stringify(contexts))
2005
- let errorCount = 0
2006
- for (const result of results) {
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
- // const contexts = { failures: results }
2016
- l(n - 1, hasError || newError)
2017
- }).catch((error) => {
2018
- console.error(error)
2019
- runtime.process.exit(-1)
2020
- errorHandler(error)
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
- l(args.count, false)
2024
- } else {
2025
- test()
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
- const promise = _process(config, query, { testsFN: test }).then((results) => {
2035
- console.log(results.responses.join(' '))
2036
- })
2037
- if (!('then' in promise)) {
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
- const objects = getObjects(config.config.objects)(config.uuid)
2064
- // for the compare
2065
- if (args.objectDiff) {
2066
- global.beforeObjects = _.cloneDeep(objects)
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
- createConfigExport = (additionalConfig) => {
2119
- if (createConfig.cached) {
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(acceptsAdditionalConfig ? additionalConfig : null)
2123
- if (!acceptsAdditionalConfig && additionalConfig) {
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
  }