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 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
  }