theprogrammablemind 7.5.8-beta.7 → 7.5.8-beta.70

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
@@ -2,6 +2,7 @@ const { Semantics, Semantic } = require('./src/semantics')
2
2
  const { Generators, Generator } = require('./src/generators')
3
3
  const DigraphInternal = require('./src/digraph_internal')
4
4
  const Digraph = require('./src/digraph')
5
+ const { project } = require('./src/project')
5
6
  const fetch = require('node-fetch')
6
7
  const base64 = require('base-64')
7
8
  const deepEqual = require('deep-equal')
@@ -13,16 +14,30 @@ const { appendNoDups, InitCalls, updateQueries } = require('./src/helpers')
13
14
  const runtime = require('./runtime')
14
15
  const sortJson = runtime.sortJson
15
16
 
17
+ const getConfig_getObjectCheck = (testConfig) => {
18
+ return (testConfig.checks && testConfig.checks.objects) || testConfig.check || []
19
+ }
20
+
21
+ const getConfig_getContextCheck = (testConfig) => {
22
+ return (testConfig.checks && testConfig.checks.context) || []
23
+ }
24
+
25
+ const pickContext = (testConfig) => (context) => {
26
+ return project(context, getConfig_getContextCheck(testConfig))
27
+ }
28
+
16
29
  const getAsk = (config) => (uuid) => (asks) => {
17
30
  for (let ask of asks) {
18
- config.addMotivation({
31
+ config.addSemantic({
19
32
  uuid,
33
+ oneShot: true,
20
34
  match: (args) => ask.matchr(args),
21
35
  apply: (args) => ask.applyr(args)
22
36
  })
23
37
  }
24
- config.addMotivation({
38
+ config.addSemantic({
25
39
  uuid,
40
+ oneShot: true,
26
41
  match: ({context}) => context.marker == 'controlEnd' || context.marker == 'controlBetween',
27
42
  apply: (args) => {
28
43
  for (let ask of asks) {
@@ -37,7 +52,7 @@ const getAsk = (config) => (uuid) => (asks) => {
37
52
  }
38
53
  }
39
54
  if (matchq(args)) {
40
- args.context.motivationKeep = true
55
+ // args.context.motivationKeep = true
41
56
  args.context.verbatim = applyq(args)
42
57
  args.context.isResponse = true;
43
58
  delete args.context.controlRemove;
@@ -58,7 +73,6 @@ const vimdiff = (actualJSON, expectedJSON) => {
58
73
  // console.log(`vimdiff ${path}/actual.json ${path}/expected.json`)
59
74
  {
60
75
  const editor = runtime.process.env.EDITOR || 'vimdiff'
61
- debugger
62
76
  // const child = runtime.child_process.spawn(editor, [`${path}/expected.json`, `${path}/actual.json`], { stdio: 'inherit' })
63
77
  console.log(`${editor} ${path}/expected.json ${path}/actual.json`)
64
78
  runtime.child_process.execSync(`${editor} ${path}/expected.json ${path}/actual.json`, {stdio: 'inherit'})
@@ -109,11 +123,12 @@ class ErrorReason extends Error {
109
123
 
110
124
  const setupArgs = (args, config, logs, hierarchy) => {
111
125
  config.setArgs(args)
112
- args.calls = new InitCalls(config.name)
126
+ args.calls = new InitCalls(args.isInstance ? `${args.isInstance}#${config.name}` : config.name)
113
127
  if (global.theprogrammablemind && global.theprogrammablemind.loadForTesting) {
114
128
  args.calls = new InitCalls(Object.keys(global.theprogrammablemind.loadForTesting)[0])
115
129
  }
116
130
  args.km = (name) => config.getConfig(name)
131
+ args.api = (name) => config.getConfig(name).api
117
132
  args.error = (context) => {
118
133
  throw new ErrorReason(context)
119
134
  }
@@ -124,6 +139,7 @@ const setupArgs = (args, config, logs, hierarchy) => {
124
139
  args.listable = listable(hierarchy)
125
140
  args.asList = asList
126
141
  args.retry = () => { throw new RetryError() }
142
+ args.fragments = (query) => config.fragment(query)
127
143
  const scopedAsk = getAsk(config)
128
144
 
129
145
  const getAPI = (uuid) => {
@@ -143,7 +159,6 @@ const setupArgs = (args, config, logs, hierarchy) => {
143
159
  apis: getAPIs(uuid)
144
160
  }
145
161
  }
146
- args.motivation = (m) => config.addMotivation(m)
147
162
  args.breakOnSemantics = false
148
163
  args.theDebugger = {
149
164
  breakOnSemantics: (value) => args.breakOnSemantics = value
@@ -157,10 +172,10 @@ const setupArgs = (args, config, logs, hierarchy) => {
157
172
  }
158
173
  args.e = (c) => config.getEvaluator(args.s, args.calls, logs, c)
159
174
  args.log = (message) => logs.push(message)
160
- // config.getAddedArgs(args)
161
175
  args.gs = gs(args.g)
162
176
  args.gsp = gs(args.gp)
163
177
  args.gsr = gs(args.gr)
178
+ config.getAddedArgs(args)
164
179
  }
165
180
 
166
181
  const gs = (g) => (contexts, separator, lastSeparator) => {
@@ -298,7 +313,6 @@ const writeTest = (fn, query, objects, generated, paraphrases, responses, contex
298
313
  }
299
314
  associations.sort()
300
315
  // tests[query] = sortJson({ paraphrases, responses, contexts, objects: convertToStable(objects), associations, metadata, config, developerTest: saveDeveloper }, { depth: 25 })
301
- debugger
302
316
  results = sortJson({
303
317
  query,
304
318
  paraphrases,
@@ -367,7 +381,7 @@ const setupContexts = (rawContexts) => {
367
381
  return contexts
368
382
  }
369
383
 
370
- const processContextsB = ({ config, hierarchy, semantics, generators, json, isTest, query, data, retries, url, commandLineArgs }) => {
384
+ const processContextsB = ({ config, hierarchy, semantics, generators, json, isTest, isInstance, instance, query, data, retries, url, commandLineArgs }) => {
371
385
  // TODO fix this name to contextsPrime
372
386
  const contextsPrime = []
373
387
  const generatedPrime = []
@@ -378,7 +392,7 @@ const processContextsB = ({ config, hierarchy, semantics, generators, json, isTe
378
392
  const contexts = setupContexts(json.contexts)
379
393
 
380
394
  const objects = config.get('objects')
381
- const args = { objects, isResponse: true, response: json, isTest, getObjects: getObjects(objects) }
395
+ const args = { objects, isResponse: true, response: json, isTest, isInstance, getObjects: getObjects(objects), instance }
382
396
  if (!json.logs) {
383
397
  json.logs = []
384
398
  }
@@ -389,28 +403,6 @@ const processContextsB = ({ config, hierarchy, semantics, generators, json, isTe
389
403
  config.debugLoops = commandLineArgs && commandLineArgs.debugLoops
390
404
  while (toDo.length > 0) {
391
405
  const context = toDo.shift()
392
- /*
393
- if (false && query) {
394
- if (config.wasChanged()) {
395
- // process contexts that overlap
396
- overlap = lastRange
397
- } else {
398
- config.watch()
399
- }
400
- if (overlap) {
401
- if (overlaps(overlap, context)) {
402
- // okay
403
- query = query.slice(overlap.end+1)
404
- data.utterance = query
405
- const json = await doWithRetries(retries, url, data)
406
- toDo = setupContexts(json.contexts).slice(1) // take off the start context
407
- }
408
- overlap = undefined
409
- }
410
- lastRange = context.range
411
- }
412
- */
413
-
414
406
  args.calls.next()
415
407
  let contextPrime = context
416
408
  context.topLevel = true
@@ -418,19 +410,21 @@ const processContextsB = ({ config, hierarchy, semantics, generators, json, isTe
418
410
  if (json.has_errors) {
419
411
  throw new Error('There are errors in the logs. Run with the -d flag and grep for Error')
420
412
  }
413
+ const generateParenthesized = isTest || (commandLineArgs && commandLineArgs.save)
421
414
  if (!config.get('skipSemantics')) {
422
- if (!config.doMotivations(args, context)) {
423
- const semantics = config.getSemantics(json.logs)
424
- try {
425
- contextPrime = semantics.apply(args, context)
426
- } catch( e ) {
427
- if (e.message == 'Maximum call stack size exceeded') {
428
- const mostCalled = semantics.getMostCalled()
429
- e.message += `\nThe most called semantic was:\nnotes: ${mostCalled.notes}\nmatch: ${mostCalled.matcher.toString()}\napply: ${mostCalled._apply.toString()}\n`
430
- }
431
- // contextPrime = semantics.apply(args, { marker: 'error', context, error: e })
432
- contextPrime = semantics.apply(args, { marker: 'error', context, reason: e.reason })
415
+ const semantics = config.getSemantics(json.logs)
416
+ try {
417
+ contextPrime = semantics.apply(args, context)
418
+ } catch( e ) {
419
+ if (e.message == 'Maximum call stack size exceeded') {
420
+ const mostCalled = semantics.getMostCalled()
421
+ e.message += `\nThe most called semantic was:\nnotes: ${mostCalled.notes}\nmatch: ${mostCalled.matcher.toString()}\napply: ${mostCalled._apply.toString()}\n`
422
+ }
423
+ // contextPrime = semantics.apply(args, { marker: 'error', context, error: e })
424
+ if (isInstance) {
425
+ console.log('error', e.error)
433
426
  }
427
+ contextPrime = semantics.apply(args, { marker: 'error', context, reason: e.reason })
434
428
  }
435
429
  }
436
430
  if (contextPrime.controlRemove) {
@@ -439,7 +433,7 @@ const processContextsB = ({ config, hierarchy, semantics, generators, json, isTe
439
433
  let assumed = { isResponse: true };
440
434
  const generated = contextPrime.isResponse ? config.getGenerators(json.logs).apply(args, contextPrime, assumed)[0] : ''
441
435
  let generatedParenthesized = []
442
- if (isTest) {
436
+ if (generateParenthesized) {
443
437
  config.parenthesized = true
444
438
  generatedParenthesized = contextPrime.isResponse ? config.getGenerators(json.logs).apply(args, contextPrime, assumed)[0] : ''
445
439
  config.parenthesized = false
@@ -452,12 +446,12 @@ const processContextsB = ({ config, hierarchy, semantics, generators, json, isTe
452
446
  args.gs = gs(args.g)
453
447
  args.gsp = gs(args.gsp)
454
448
  args.gsr = gs(args.gr)
455
- if (isTest) {
449
+ if (generateParenthesized) {
456
450
  config.parenthesized = false
457
451
  }
458
452
  const paraphrases = config.getGenerators(json.logs).apply(args, contextPrime, assumed)[0]
459
453
  let paraphrasesParenthesized = []
460
- if (isTest) {
454
+ if (generateParenthesized) {
461
455
  config.parenthesized = true
462
456
  paraphrasesParenthesized = config.getGenerators(json.logs).apply(args, contextPrime, assumed)[0]
463
457
  config.parenthesized = false
@@ -471,7 +465,7 @@ const processContextsB = ({ config, hierarchy, semantics, generators, json, isTe
471
465
  contextsPrime.push(contextPrime)
472
466
  generatedPrime.push(generated)
473
467
  paraphrasesPrime.push(paraphrases)
474
- if (isTest) {
468
+ if (generateParenthesized) {
475
469
  paraphrasesParenthesizedPrime.push(paraphrasesParenthesized)
476
470
  generatedParenthesizedPrime.push(generatedParenthesized)
477
471
  }
@@ -549,8 +543,11 @@ const setupProcessB = ({ config, initializer, allowDelta=false } = {}) => {
549
543
  // console.log('config', config)
550
544
  data.delta = config.delta()
551
545
  } else {
552
- Object.assign(data, config.config)
546
+ config.toData(data)
547
+ // Object.assign(data, config.config)
553
548
  }
549
+
550
+ // config.toServer(data)
554
551
 
555
552
  if (data.namespaces) {
556
553
  for (const uuid of Object.keys(data.namespaces)) {
@@ -574,7 +571,7 @@ const setupProcessB = ({ config, initializer, allowDelta=false } = {}) => {
574
571
  }
575
572
 
576
573
  // instance template
577
- const processInstance = (config, instance) => {
574
+ const loadInstance = (config, instance) => {
578
575
  const transitoryMode = global.transitoryMode
579
576
  global.transitoryMode = false
580
577
  const { /* data, generators, semantics, */ hierarchy } = setupProcessB({ config })
@@ -584,15 +581,15 @@ const processInstance = (config, instance) => {
584
581
  if (results.extraConfig) {
585
582
  // config.addInternal(results, useOldVersion = true, skipObjects = false, includeNamespaces = true, allowNameToBeNull = false)
586
583
  // config.addInternal(config.template.queries[i], { handleCalculatedProps: true } )
587
- config.addInternal(instance.template.queries[i], { handleCalculatedProps: true } )
584
+ config.addInternal(instance.template.queries[i], { addFirst: true, handleCalculatedProps: true } )
588
585
  } else {
589
- processContextsB({ config, hierarchy, json: results/*, generators, semantics */, commandLineArgs: {} })
586
+ processContextsB({ config, hierarchy, json: results/*, generators, semantics */, commandLineArgs: {}, isInstance: `instance${i}`, instance: instance.queries[i] })
590
587
  }
591
588
  }
592
589
  global.transitoryMode = transitoryMode
593
590
  }
594
591
 
595
- const _process = async (config, query, { initializer, commandLineArgs, credentials, writeTests, isTest, saveDeveloper, testConfig, testsFN, errorHandler = defaultErrorHandler } = {}) => {
592
+ const _process = async (config, query, { initializer, commandLineArgs, credentials, writeTests, isTest, saveDeveloper, rebuildingTemplate, testConfig, testsFN, errorHandler = defaultErrorHandler } = {}) => {
596
593
  if (credentials) {
597
594
  config.server(credentials.server, credentials.key)
598
595
  }
@@ -606,7 +603,6 @@ const _process = async (config, query, { initializer, commandLineArgs, credentia
606
603
  if (writeTests) {
607
604
  config.rebuild()
608
605
  const objects = getObjects(config.config.objects)(config.uuid)
609
- config.beforeQuery({ query, isModule: false, objects })
610
606
  }
611
607
  } catch(error) {
612
608
  throw error
@@ -614,7 +610,10 @@ const _process = async (config, query, { initializer, commandLineArgs, credentia
614
610
 
615
611
  let { data, /* generators, semantics, */ hierarchy } = setupProcessB({ config, initializer, allowDelta: true })
616
612
  if (commandLineArgs && commandLineArgs.checkForLoop) {
617
- data.checkForLoop = true
613
+ data.checkForLoop = commandLineArgs.checkForLoop
614
+ }
615
+ if (rebuildingTemplate) {
616
+ data.errors_ignore_contextual_priorities_non_existant_ops = true
618
617
  }
619
618
  let queries = query.split('\\n')
620
619
 
@@ -681,6 +680,7 @@ const _process = async (config, query, { initializer, commandLineArgs, credentia
681
680
  response.times += json.times
682
681
  response.trace = response.trace.concat(json.trace)
683
682
  response.version = json.version
683
+ response.explain_priorities = json.explain_priorities
684
684
 
685
685
  response.contexts = response.contexts.concat(contextsPrime)
686
686
  response.generated = response.generated.concat(generatedPrime)
@@ -694,7 +694,12 @@ const _process = async (config, query, { initializer, commandLineArgs, credentia
694
694
 
695
695
  if (writeTests) {
696
696
  const actual_config = getConfigForTest(config, testConfig)
697
- writeTest(testsFN, query, config.config.objects, response.generated, response.paraphrases, response.responses, response.contexts, response.associations, response.metadata, actual_config, saveDeveloper, response.paraphrasesParenthesized, response.generatedParenthesized)
697
+ const saveObjects = {...config.config.objects}
698
+ saveObjects.nameToUUID = {}
699
+ for (let km of config.configs) {
700
+ saveObjects.nameToUUID[km.name] = km.uuid
701
+ }
702
+ writeTest(testsFN, query, saveObjects, response.generated, response.paraphrases, response.responses, response.contexts, response.associations, response.metadata, actual_config, saveDeveloper, response.paraphrasesParenthesized, response.generatedParenthesized)
698
703
  }
699
704
 
700
705
  return response
@@ -734,7 +739,7 @@ const getConfigForTest = (config, testConfig) => {
734
739
  return configForTest
735
740
  }
736
741
 
737
- const runTest = async (config, expected, { args, verbose, afterTest, testConfig, debug }) => {
742
+ const runTest = async (config, expected, { args, verbose, testConfig, debug }) => {
738
743
  const test = expected.query
739
744
  // initialize in between test so state is not preserved since the test was adding without state
740
745
  config.rebuild()
@@ -759,8 +764,6 @@ const runTest = async (config, expected, { args, verbose, afterTest, testConfig,
759
764
  objects = getObjects(config.config.objects)(config.getConfigs()[testConfig.testModuleName].uuid)
760
765
  testConfigName = testConfig.testModuleName
761
766
  }
762
- config.beforeQuery({ query: test, isModule: false, objects })
763
- // config.resetMotivations()
764
767
  try {
765
768
  const result = await _process(config, test, { errorHandler, isTest: true })
766
769
  result.query = test
@@ -778,20 +781,30 @@ const runTest = async (config, expected, { args, verbose, afterTest, testConfig,
778
781
  delete expected_objects.nameToUUID
779
782
  const actual_objects = sortJson(convertToStable(config.config.objects), { depth: 25 })
780
783
  const failed_paraphrases = !matching(result.paraphrases, expected.paraphrases)
781
- const failed_paraphrasesParenthesized = !matching(result.paraphrasesParenthesized, expected.paraphrasesParenthesized)
782
- const failed_generatedParenthesized = !matching(result.generatedParenthesized, expected.generatedParenthesized)
784
+ let failed_paraphrasesParenthesized = !matching(result.paraphrasesParenthesized, expected.paraphrasesParenthesized)
785
+ let failed_generatedParenthesized = !matching(result.generatedParenthesized, expected.generatedParenthesized)
786
+ // TODO fix the naming conventions: camelcase + use actual instead of result
783
787
  const failed_responses = !matching(result.responses, expected.responses)
784
788
  const failed_contexts = !matching(result.contexts, expected.contexts)
785
789
  const failed_objects = !matching(actual_objects, expected_objects)
786
790
 
791
+ if (args.testNoParenthesized) {
792
+ failed_paraphrasesParenthesized = false
793
+ failed_generatedParenthesized = false
794
+ }
795
+
796
+ const pickedResultContexts = result.contexts.map(pickContext(testConfig))
797
+ const pickedExpectedContexts = expected.contexts.map(pickContext(testConfig))
798
+ const failedCheckedContexts = !matching(pickedResultContexts, pickedExpectedContexts)
799
+
787
800
  const pickEm = (getObjects) => {
788
801
  const picked = {}
789
- for (let prop of (testConfig.check || [])) {
802
+ for (let prop of getConfig_getObjectCheck(testConfig)) {
790
803
  if (prop.km) {
791
804
  c = config.getConfig(prop.km)
792
805
  o = getObjects(prop.km)
793
806
  picked[prop.km] = {}
794
- for (let p of c.testConfig.check) {
807
+ for (let p of getConfig_getObjectCheck(c.testConfig)) {
795
808
  if (p.km) {
796
809
  continue
797
810
  }
@@ -809,6 +822,7 @@ const runTest = async (config, expected, { args, verbose, afterTest, testConfig,
809
822
  }
810
823
  return expected.objects.namespaced[expected.objects.nameToUUID[name]]
811
824
  }
825
+ sortJson(pickEm(expectedGetObjects), { depth: 25 })
812
826
  const expected_checked = sortJson(pickEm(expectedGetObjects), { depth: 25 })
813
827
  const actualGetObjects = (name) => {
814
828
  if (!name) {
@@ -824,38 +838,7 @@ const runTest = async (config, expected, { args, verbose, afterTest, testConfig,
824
838
  const actual_config = sortJson(convertToStable(getConfigForTest(config, testConfig)), { depth: 25 })
825
839
  const expected_config = sortJson(convertToStable(expected.config), { depth: 25 })
826
840
  const failed_config = !matching(actual_config, expected_config)
827
- let failed = failed_paraphrases || failed_paraphrasesParenthesized || failed_generatedParenthesized || failed_responses || failed_contexts || failed_objects || failed_config || failed_checked
828
- if (!failed) {
829
- if (config.afterTest) {
830
- failed = config.afterTest({ query: test, expected, actual: result, config })
831
- if (failed) {
832
- return {
833
- utterance: test,
834
- errorFromAfterTest: failed,
835
- expected: {
836
- responses: expected.responses,
837
- paraphrases: expected.paraphrases,
838
- paraphrasesParenthesized: expected.paraphrasesParenthesized,
839
- generatedParenthesized: expected.generatedParenthesized,
840
- results: expected.contexts,
841
- checked: expected_checked,
842
- objects: expected_objects,
843
- config: expected.config
844
- },
845
- actual: {
846
- responses: result.responses,
847
- paraphrases: result.paraphrases,
848
- paraphrasesParenthesized: result.paraphrasesParenthesized,
849
- generatedParenthesized: result.generatedParenthesized,
850
- results: result.contexts,
851
- checked: actual_checked,
852
- objects: actual_objects,
853
- config: actual_config
854
- }
855
- }
856
- }
857
- }
858
- }
841
+ let failed = failed_paraphrases || failed_paraphrasesParenthesized || failed_generatedParenthesized || failed_responses || failed_contexts || failed_objects || failed_config || failed_checked || failedCheckedContexts
859
842
 
860
843
  if (expected.metadata && result.metadata && failed) {
861
844
  const priorities = analyzeMetaData(expected.metadata, result.metadata)
@@ -874,6 +857,7 @@ const runTest = async (config, expected, { args, verbose, afterTest, testConfig,
874
857
  generatedParenthesized: expected.generatedParenthesized,
875
858
  results: expected.contexts,
876
859
  checked: expected_checked,
860
+ checkedContexts: pickedExpectedContexts,
877
861
  objects: expected_objects,
878
862
  config: expected.config
879
863
  },
@@ -884,6 +868,7 @@ const runTest = async (config, expected, { args, verbose, afterTest, testConfig,
884
868
  generatedParenthesized: result.generatedParenthesized,
885
869
  results: result.contexts,
886
870
  checked: actual_checked,
871
+ checkedContexts: pickedResultContexts,
887
872
  objects: actual_objects,
888
873
  config: actual_config
889
874
  }
@@ -923,20 +908,16 @@ const runTestsHelper = async (config, tests, failed, juicyBits) => {
923
908
 
924
909
  const runTests = async (config, testFile, juicyBits) => {
925
910
  const tests = JSON.parse(runtime.fs.readFileSync(testFile))
926
- config.beforeTests()
927
911
  if (juicyBits.verbose) {
928
912
  console.log('\n', testFile, '-----------------------------------------------', '\n')
929
913
  }
930
914
  const v = await runTestsHelper(config, [...tests], [], juicyBits)
931
- config.afterTests()
932
915
  return v
933
916
  }
934
917
 
935
918
  const saveTest = async (testFile, config, test, expected, testConfig, saveDeveloper) => {
936
919
  config.rebuild()
937
920
  const objects = getObjects(config.config.objects)(config.uuid)
938
- //config.resetMotivations()
939
- config.beforeQuery({ query: test, isModule: false, objects })
940
921
  console.log(test)
941
922
  const result = await _process(config, test, { isTest: true })
942
923
  // const actualObjects = config.config.objects
@@ -1118,10 +1099,11 @@ const defaultErrorHandler = async (error) => {
1118
1099
  doErrorExit = true
1119
1100
  }
1120
1101
 
1121
- if (doErrorExit) {
1102
+ if (typeof runtime.process.exit == 'function' && doErrorExit) {
1122
1103
  runtime.process.exit(-1)
1123
1104
  }
1124
- // throw error
1105
+
1106
+ throw error
1125
1107
  }
1126
1108
 
1127
1109
  const defaultInnerProcess = (config, errorHandler, responses) => {
@@ -1142,6 +1124,43 @@ const defaultInnerProcess = (config, errorHandler, responses) => {
1142
1124
  } else {
1143
1125
  console.log('objects', runtime.util.inspect(config.get('objects'), { depth: Infinity, sorted: true }))
1144
1126
  }
1127
+
1128
+ const pickEm = () => {
1129
+ const picked = {}
1130
+ const namespaced = config.get('objects')['namespaced']
1131
+ for (let prop of getConfig_getObjectCheck(config.testConfig)) {
1132
+ if (prop.km) {
1133
+ /*
1134
+ const objects = namespaced[prop.km]]
1135
+ picked[prop.km] = {}
1136
+ for (let p of c.testConfig.check) {
1137
+ if (p.km) {
1138
+ continue
1139
+ }
1140
+ picked[p] = objects[p]
1141
+ }
1142
+ */
1143
+ console.log('TODO implement this if needed')
1144
+ } else {
1145
+ const objects = namespaced[config.uuid]
1146
+ picked[prop] = objects[prop]
1147
+ }
1148
+ }
1149
+ return picked
1150
+ }
1151
+
1152
+ if (responses.explain_priorities) {
1153
+ console.log("Explain Priorities")
1154
+ for ([inputss, outpus, reason] of responses.explain_priorities) {
1155
+ console.log(` ${JSON.stringify(inputss)} reason: ${reason}`)
1156
+ }
1157
+ }
1158
+ const picked = pickEm()
1159
+ if (!_.isEmpty(picked)) {
1160
+ console.log('--- checked object properties ---')
1161
+ console.log(JSON.stringify(picked, null, 2))
1162
+ }
1163
+
1145
1164
  console.log('--- The contexts are ----------')
1146
1165
  console.log(JSON.stringify(sortJson(responses.contexts, { depth: 25 }), null, 2))
1147
1166
  console.log('')
@@ -1182,32 +1201,8 @@ const defaultProcess = ({ config, errorHandler }) => async (promise) => {
1182
1201
  }
1183
1202
  }
1184
1203
 
1185
- /*
1186
- const kmFileTemplate = (kmBaseName, kmName) =>
1187
- `const entodicton = require('entodicton')
1188
- const base = require('./${kmBaseName}').copy()
1189
- const ${kmName}_tests = require('./${kmName}.test.json')
1190
- const ${kmName}_instance = require('./${kmBaseName}.${kmName}.instance.json')
1191
-
1192
- const config = new entodicton.Config({ name: '${kmName}' })
1193
- config.add(base)
1194
- kirk_instance.base = '${kmBaseName}'
1195
- config.load(${kmName}_instance)
1196
-
1197
- entodicton.knowledgeModule( {
1198
- module,
1199
- description: '${kmName} related concepts',
1200
- section,
1201
- config,
1202
- test: {
1203
- name: './${kmName}.test.json',
1204
- contents: ${kmName}_tests
1205
- },
1206
- })
1207
- `
1208
- */
1209
-
1210
- const build = async ({ config, target, template, errorHandler = defaultErrorHandler }) => {
1204
+ // loadTemplate BuiltTemplate
1205
+ const rebuildTemplate = async ({ config, target, template, errorHandler = defaultErrorHandler }) => {
1211
1206
  const accumulators = {
1212
1207
  resultss: [],
1213
1208
  fragments: [],
@@ -1231,8 +1226,6 @@ const build = async ({ config, target, template, errorHandler = defaultErrorHand
1231
1226
  if (property == 'fragments') {
1232
1227
  global.transitoryMode = true
1233
1228
  }
1234
- // greg32
1235
- // config.addInternal( query )
1236
1229
  if (hierarchy) {
1237
1230
  for (let edge of hierarchy) {
1238
1231
  if (Array.isArray(edge)) {
@@ -1244,7 +1237,7 @@ const build = async ({ config, target, template, errorHandler = defaultErrorHand
1244
1237
  }
1245
1238
 
1246
1239
  try {
1247
- const results = await _process(config, query.query, {initializer})
1240
+ const results = await _process(config, query.query, {initializer, rebuildingTemplate: true})
1248
1241
  if (config.config.debug) {
1249
1242
  // TODO pass in the error handler like the other ones
1250
1243
  defaultInnerProcess(config, defaultErrorHandler, results)
@@ -1274,6 +1267,12 @@ const build = async ({ config, target, template, errorHandler = defaultErrorHand
1274
1267
  // it will just get added to the config
1275
1268
  const extraConfig = queryOrExtraConfig
1276
1269
  console.log('config', extraConfig)
1270
+ try {
1271
+ config.addInternal(_.cloneDeep(extraConfig), { handleCalculatedProps: true } )
1272
+ } catch ( e ) {
1273
+ const where = extraConfig.where ? ` ${extraConfig.where}` : ''
1274
+ throw new Error(`Error processing extra config${where}: ${e.stack}}`)
1275
+ }
1277
1276
  accumulators[property].push({ extraConfig: true, ...extraConfig })
1278
1277
  await looper(queries)
1279
1278
  }
@@ -1338,36 +1337,31 @@ const knowledgeModule = async ({
1338
1337
  module: moduleFromJSFile,
1339
1338
  description,
1340
1339
  section,
1341
- config,
1340
+ // config, createConfig,
1341
+ createConfig,
1342
+ newWay,
1342
1343
  demo,
1343
1344
  test,
1344
1345
  template,
1345
1346
  errorHandler = defaultErrorHandler,
1346
1347
  process: processResults = defaultProcess,
1347
1348
  stopAtFirstFailure = true,
1348
- beforeQuery = () => {},
1349
- beforeTests = () => {},
1350
- afterTests = () => {},
1351
- beforeTest = () => {},
1352
- afterTest = () => {}
1349
+ ...rest
1353
1350
  } = {}) => {
1354
1351
 
1355
- config.beforeQuery = beforeQuery
1356
- config.beforeTests = beforeTests
1357
- config.afterTests = afterTests
1358
- config.beforeTest = beforeTest
1359
- config.afterTest = afterTest
1352
+ const unknownArgs = Object.keys(rest)
1353
+ if (unknownArgs.length > 0) {
1354
+ throw new Error(`Unknown arguments to knowledgeModule: ${unknownArgs.join()}`)
1355
+ }
1360
1356
 
1361
1357
  const testConfig = test
1362
1358
 
1363
1359
  if (!moduleFromJSFile) {
1364
1360
  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.")
1365
1361
  }
1366
- if (!config) {
1367
- throw new Error("'config' is a required parameter. The value should the config that defines the knowledge module.")
1368
- }
1369
- if (!config.name) {
1370
- throw new Error("config must have 'name' set to the knowledge module name.")
1362
+ // if (!config && !createConfig) {
1363
+ if (!createConfig) {
1364
+ throw new Error("'config' or 'createConfig' is a required parameter. The value should the config that defines the knowledge module.")
1371
1365
  }
1372
1366
  if (!description) {
1373
1367
  throw new Error("'description' is a required parameter. The value should the description of the knowledge module.")
@@ -1377,86 +1371,51 @@ const knowledgeModule = async ({
1377
1371
  }
1378
1372
 
1379
1373
  const isProcess = require.main === moduleFromJSFile
1380
- let loadForTesting = false
1381
- if (global.theprogrammablemind) {
1382
- if (global.theprogrammablemind.loadForTesting[config.name]) {
1383
- loadForTesting = true
1374
+
1375
+ const setupConfig = (config) => {
1376
+ if (!config.name) {
1377
+ throw new Error("config must have 'name' set to the knowledge module name.")
1384
1378
  }
1385
- }
1386
1379
 
1387
- // remove test only stuff
1388
- if (!isProcess && !loadForTesting) {
1389
- config.config.operators = config.config.operators.filter( (operator) => {
1390
- if (operator.development) {
1391
- return false
1392
- } else {
1393
- return true
1394
- }
1395
- })
1396
- config.config.bridges = config.config.bridges.filter( (bridge) => {
1397
- if (bridge.development) {
1398
- return false
1399
- } else {
1400
- return true
1380
+ config.description = description
1381
+ if (typeof test === 'object') {
1382
+ if (test.contents) {
1383
+ config.tests = test.contents
1384
+ test = test.name
1401
1385
  }
1402
- })
1403
- }
1404
-
1405
- let module
1406
- if (_.isFunction(moduleFromJSFile)) {
1407
- module = moduleFromJSFile
1408
- } else {
1409
- module = () => {
1410
- config.rebuild({ isModule: true })
1411
- moduleFromJSFile.exports = config
1412
- }
1413
- }
1414
- processResults = processResults({ config, errorHandler })
1415
- config.description = description
1416
- config.demo = demo
1417
- if (typeof test === 'object') {
1418
- if (test.contents) {
1419
- config.tests = test.contents
1420
- test = test.name
1421
- }
1422
- } else {
1423
- if (runtime.fs && runtime.fs.existsSync(test)) {
1424
- config.tests = JSON.parse(runtime.fs.readFileSync(test))
1425
1386
  } else {
1426
- config.tests = {}
1427
- }
1428
- }
1429
- config.setTestConfig(testConfig)
1430
-
1431
- if (!isProcess) {
1432
- if (template) {
1433
- if (config.needsRebuild(template.template, template.instance)) {
1434
- throw new Error(`This module "${config.name}" cannot be used because the instance file needs rebuilding. Run on the command line with no arguements or the -rt argument to rebuild.`)
1435
- }
1436
- try {
1437
- config.load(template.template, template.instance)
1438
- } catch( e ) {
1439
- errorHandler(e)
1387
+ if (runtime.fs && runtime.fs.existsSync(test)) {
1388
+ config.tests = JSON.parse(runtime.fs.readFileSync(test))
1389
+ } else {
1390
+ config.tests = []
1440
1391
  }
1441
1392
  }
1393
+ config.setTestConfig(testConfig)
1442
1394
  }
1395
+
1396
+
1443
1397
  if (isProcess) {
1398
+ const config = createConfig()
1399
+ setupConfig(config)
1400
+ processResults = processResults({ config, errorHandler })
1444
1401
  // setup();
1445
1402
  const parser = new runtime.ArgumentParser({
1446
1403
  description: 'Entodicton knowledge module'
1447
1404
  })
1448
1405
 
1449
- 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", "mammel#0"]\' })'
1450
- 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"]\' })'
1451
- 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"]\' })'
1452
- 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\' })'
1453
- 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]))\' })'
1406
+ 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]]\''
1407
+ 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]]\''
1408
+ 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]]\''
1409
+ 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}\''
1410
+ 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\''
1411
+ 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]))\''
1454
1412
 
1455
1413
 
1456
1414
  parser.add_argument('-tmn', '--testModuleName', { help: 'When running tests instead of using the current modules tests use the specified modules tests' })
1457
1415
  parser.add_argument('-t', '--test', { action: 'store_true', help: 'Run the tests. Create tests by running with the --query + --save flag' })
1458
1416
  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' })
1459
1417
  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' })
1418
+ parser.add_argument('-tnp', '--testNoParenthesized', { action: 'store_true', help: 'Don\' check parenthesized differences for the tests' })
1460
1419
  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' })
1461
1420
  // 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.' })
1462
1421
  parser.add_argument('-rt', '--rebuildTemplate', { action: 'store_true', help: 'Force a template rebuild' })
@@ -1464,7 +1423,7 @@ const knowledgeModule = async ({
1464
1423
  parser.add_argument('-i', '--info', { action: 'store_true', help: 'Print meta-data for the module' })
1465
1424
  parser.add_argument('-v', '--vimdiff', { action: 'store_true', help: 'For failures run vimdiff' })
1466
1425
  parser.add_argument('-g', '--greg', { action: 'store_true', help: 'Set the server to be localhost so I can debug stuff' })
1467
- parser.add_argument('-cl', '--checkForLoop', { action: 'store_true', help: 'Check for loops in the priorities' })
1426
+ 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]]' })
1468
1427
  parser.add_argument('-r', '--retrain', { action: 'store_true', help: 'Get the server to retrain the neural nets' })
1469
1428
  parser.add_argument('-q', '--query', { help: 'Run the specified query' })
1470
1429
  parser.add_argument('-ip ', '--server', { help: 'Server to run against' })
@@ -1477,14 +1436,16 @@ const knowledgeModule = async ({
1477
1436
  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' })
1478
1437
  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.' })
1479
1438
  parser.add_argument('-sd', '--saveDeveloper', { action: 'store_true', help: 'Same as -s but the query will not show up in the info command.' })
1480
- parser.add_argument('-dic', '--debugIncludeConvolutions', { action: 'store_true', help: 'When running with the --debugIncludeConvolutions flag the logs will include convolutions which are somewhat annoying verbose. Default is false' })
1481
1439
  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 '})
1482
1440
  parser.add_argument('-d', '--debug', { action: 'store_true', help: 'When running with the --debug flag this set the debug flag in the config' })
1483
- parser.add_argument('-da', '--debugAssociation', { help: helpDebugAssociation })
1484
- parser.add_argument('-dh', '--debugHierarchy', { help: helpDebugHierarchy })
1485
- parser.add_argument('-dp', '--debugPriority', { help: helpDebugPriority })
1486
- parser.add_argument('-db', '--debugBridge', { help: helpDebugBridge })
1487
- parser.add_argument('-do', '--debugOperator', { help: helpDebugOperator })
1441
+ parser.add_argument('-da', '--debugAssociation', { action: 'store_true', help: helpDebugAssociation })
1442
+ parser.add_argument('-dh', '--debugHierarchy', { action: 'store_true', help: helpDebugHierarchy })
1443
+ parser.add_argument('-dp', '--debugPriority', { action: 'store_true', help: helpDebugPriority })
1444
+ parser.add_argument('-dcp', '--debugContextualPriority', { action: 'store_true', help: helpDebugContextualPriority })
1445
+ parser.add_argument('-db', '--debugBridge', { action: 'store_true', help: helpDebugBridge })
1446
+ parser.add_argument('-do', '--debugOperator', { action: 'store_true', help: helpDebugOperator })
1447
+ 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"})
1448
+ 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' })
1488
1449
 
1489
1450
  const args = parser.parse_args()
1490
1451
  args.count = args.count || 1
@@ -1492,7 +1453,35 @@ const knowledgeModule = async ({
1492
1453
  if (args.parenthesized) {
1493
1454
  config.parenthesized = true
1494
1455
  }
1495
-
1456
+ if (args.checkForLoop) {
1457
+ try {
1458
+ args.checkForLoop = JSON.parse(args.checkForLoop)
1459
+ const isKey = (what) => {
1460
+ if (!Array.isArray(what)) {
1461
+ return false
1462
+ }
1463
+ if (what.length !== 2) {
1464
+ return false
1465
+ }
1466
+ if (!typeof what[0] == 'string') {
1467
+ return false
1468
+ }
1469
+ if (!typeof what[1] == 'number') {
1470
+ return false
1471
+ }
1472
+ return true
1473
+ }
1474
+ if (!Array.isArray(args.checkForLoop) || args.checkForLoop.some((value) => !isKey(value))) {
1475
+ throw new Error(`Error for the checkForLoop argument. Expected a JSON array of operator keys of the form "[<id>, <level>]"`)
1476
+ }
1477
+ } catch( e ) {
1478
+ throw new Error(`Error parsing JSON of the checkForLoop argument. ${e}`)
1479
+ }
1480
+ } else {
1481
+ if (process.argv.includes('--checkForLoop') || process.argv.includes('-cl')) {
1482
+ args.checkForLoop = true
1483
+ }
1484
+ }
1496
1485
  if (args.debugAssociation) {
1497
1486
  console.log(helpDebugAssociation)
1498
1487
  runtime.process.exit(-1)
@@ -1550,7 +1539,12 @@ const knowledgeModule = async ({
1550
1539
  if (args.debug) {
1551
1540
  config.config.debug = true
1552
1541
  }
1553
- config.config.debugIncludeConvolutions = args.debugIncludeConvolutions
1542
+
1543
+ if (args.explainPriorities) {
1544
+ config.config.explain_priorities = true
1545
+ }
1546
+
1547
+ config.config.debugIncludeConvolutions = args.debugIncludeConvolutions || process.argv.includes('--debugIncludeConvolutions') || process.argv.includes('-dic')
1554
1548
 
1555
1549
  if (template) {
1556
1550
  const needsRebuild = config.needsRebuild(template.template, template.instance, options)
@@ -1559,6 +1553,10 @@ const knowledgeModule = async ({
1559
1553
 
1560
1554
  }
1561
1555
  config.load(template.template, template.instance, { rebuild: needsRebuild })
1556
+ if (config.name == 'ui') {
1557
+ console.log('config.COUNTER', config.COUNTER)
1558
+ debugger
1559
+ }
1562
1560
  if (needsRebuild) {
1563
1561
  return
1564
1562
  }
@@ -1566,20 +1564,8 @@ const knowledgeModule = async ({
1566
1564
 
1567
1565
  if (!args.save && !args.rebuildTemplate && !args.dontAddAssociations) {
1568
1566
  config.addAssociationsFromTests(config.tests);
1569
- //for (let query in config.tests) {
1570
- // config.addAssociations(config.tests[query].associations || []);
1571
- //}
1572
1567
  }
1573
1568
 
1574
- /*
1575
- if (args.buildTemplate) {
1576
- if (template) {
1577
- config.rebuild()
1578
- config.load(template.template, template.instance, { rebuild: true })
1579
- }
1580
- }
1581
- */
1582
-
1583
1569
  let configPrinted = false
1584
1570
  const printConfig = () => {
1585
1571
  if (configPrinted) {
@@ -1712,11 +1698,13 @@ const knowledgeModule = async ({
1712
1698
  if (JSON.stringify(result.expected.paraphrases) !== JSON.stringify(result.actual.paraphrases)) {
1713
1699
  hasError = true
1714
1700
  }
1715
- if (JSON.stringify(result.expected.paraphrasesParenthesized) !== JSON.stringify(result.actual.paraphrasesParenthesized)) {
1716
- hasError = true
1717
- }
1718
- if (JSON.stringify(result.expected.generatedParenthesized) !== JSON.stringify(result.actual.generatedParenthesized)) {
1719
- hasError = true
1701
+ if (!args.testNoParenthesized) {
1702
+ if (JSON.stringify(result.expected.paraphrasesParenthesized) !== JSON.stringify(result.actual.paraphrasesParenthesized)) {
1703
+ hasError = true
1704
+ }
1705
+ if (JSON.stringify(result.expected.generatedParenthesized) !== JSON.stringify(result.actual.generatedParenthesized)) {
1706
+ hasError = true
1707
+ }
1720
1708
  }
1721
1709
  if (JSON.stringify(result.expected.responses) !== JSON.stringify(result.actual.responses)) {
1722
1710
  hasError = true
@@ -1724,6 +1712,9 @@ const knowledgeModule = async ({
1724
1712
  if (JSON.stringify(result.expected.checked) !== JSON.stringify(result.actual.checked)) {
1725
1713
  hasError = true
1726
1714
  }
1715
+ if (JSON.stringify(result.expected.checkedContexts) !== JSON.stringify(result.actual.checkedContexts)) {
1716
+ hasError = true
1717
+ }
1727
1718
  }
1728
1719
 
1729
1720
  if (hasError) {
@@ -1742,9 +1733,13 @@ const knowledgeModule = async ({
1742
1733
  }
1743
1734
  }
1744
1735
  show('paraphrases', result.expected.paraphrases, result.actual.paraphrases)
1745
- show('paraphrases parenthesized', result.expected.paraphrasesParenthesized, result.actual.paraphrasesParenthesized)
1736
+ if (!args.testNoParenthesized) {
1737
+ show('paraphrases parenthesized', result.expected.paraphrasesParenthesized, result.actual.paraphrasesParenthesized)
1738
+ }
1746
1739
  show('responses', result.expected.responses, result.actual.responses)
1747
- show('responses parenthesized', result.expected.generatedParenthesized, result.actual.generatedParenthesized)
1740
+ if (!args.testNoParenthesized) {
1741
+ show('responses parenthesized', result.expected.generatedParenthesized, result.actual.generatedParenthesized)
1742
+ }
1748
1743
  /*
1749
1744
  if (JSON.stringify(result.expected.paraphrases) !== JSON.stringify(result.actual.paraphrases)) {
1750
1745
  if (!headerShown) {
@@ -1783,6 +1778,24 @@ const knowledgeModule = async ({
1783
1778
  newError = true
1784
1779
  headerShown = true
1785
1780
  }
1781
+ if (JSON.stringify(result.expected.checkedContexts) !== JSON.stringify(result.actual.checkedContexts)) {
1782
+ if (!headerShown) {
1783
+ console.log(' Failure')
1784
+ }
1785
+ const widths = [4, 18, 72]
1786
+ const lines = new Lines(widths)
1787
+ lines.setElement(1, 1, 'expected checkedContexts', true)
1788
+ lines.setElement(2, 2, JSON.stringify(result.expected.checkedContexts, null, 2))
1789
+ lines.log()
1790
+ lines.setElement(1, 1, 'actual checkedContexts', true)
1791
+ lines.setElement(2, 2, JSON.stringify(result.actual.checkedContexts, null, 2))
1792
+ lines.log()
1793
+ if (args.vimdiff) {
1794
+ vimdiff(result.actual.checkedContexts, result.expected.checkedContexts)
1795
+ }
1796
+ newError = true
1797
+ headerShown = true
1798
+ }
1786
1799
  }
1787
1800
  } else {
1788
1801
  if (results.length > 0 && args.vimdiff) {
@@ -1821,7 +1834,6 @@ const knowledgeModule = async ({
1821
1834
  if (query.length === 0) {
1822
1835
  return readline.close()
1823
1836
  }
1824
- // const promise = processResults(_process(config, query, { testsFN: test }))
1825
1837
  const promise = _process(config, query, { testsFN: test }).then((results) => {
1826
1838
  console.log(results.responses.join(' '))
1827
1839
  })
@@ -1849,7 +1861,6 @@ const knowledgeModule = async ({
1849
1861
  if (args.objectDiff) {
1850
1862
  global.beforeObjects = _.cloneDeep(objects)
1851
1863
  }
1852
- config.beforeQuery({ query: args.query, isModule: false, objects })
1853
1864
  try {
1854
1865
  await processResults(_process(config, args.query, { commandLineArgs: args, dontAddAssociations: args.dontAddAssociations, writeTests: args.save || args.saveDeveloper, saveDeveloper: args.saveDeveloper, testConfig, testsFN: test }))
1855
1866
  } catch( error ) {
@@ -1858,11 +1869,55 @@ const knowledgeModule = async ({
1858
1869
  }
1859
1870
  printConfig()
1860
1871
  } else {
1861
- config.addAssociationsFromTests(config.tests);
1862
- //for (let query in config.tests) {
1863
- // config.addAssociations(config.tests[query].associations || []);
1864
- //}
1865
- module()
1872
+ const initConfig = (config) => {
1873
+ setupConfig(config)
1874
+
1875
+ let loadForTesting = false
1876
+ if (global.theprogrammablemind) {
1877
+ if (global.theprogrammablemind.loadForTesting[config.name]) {
1878
+ loadForTesting = true
1879
+ }
1880
+ }
1881
+ // remove test only stuff
1882
+ if (!isProcess && !loadForTesting) {
1883
+ config.config.operators = config.config.operators.filter( (operator) => {
1884
+ if (operator.development) {
1885
+ return false
1886
+ } else {
1887
+ return true
1888
+ }
1889
+ })
1890
+ config.config.bridges = config.config.bridges.filter( (bridge) => {
1891
+ if (bridge.development) {
1892
+ return false
1893
+ } else {
1894
+ return true
1895
+ }
1896
+ })
1897
+ }
1898
+
1899
+ if (template) {
1900
+ if (config.needsRebuild(template.template, template.instance, { isModule: !isProcess })) {
1901
+ 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.`
1902
+ throw new Error(error)
1903
+ }
1904
+ try {
1905
+ config.load(template.template, template.instance)
1906
+ } catch( e ) {
1907
+ errorHandler(e)
1908
+ }
1909
+ }
1910
+
1911
+ config.addAssociationsFromTests(config.tests);
1912
+ }
1913
+
1914
+ createConfigExport = () => {
1915
+ const config = createConfig()
1916
+ initConfig(config)
1917
+ config.rebuild({ isModule: true })
1918
+ return config
1919
+ }
1920
+ moduleFromJSFile.exports = createConfigExport
1866
1921
  }
1867
1922
 
1868
1923
  }
@@ -1918,7 +1973,7 @@ module.exports = {
1918
1973
  w,
1919
1974
  // submitBug,
1920
1975
  ensureTestFile,
1921
- build,
1976
+ rebuildTemplate,
1922
1977
  processContext,
1923
1978
  processContexts,
1924
1979
  runTests,
@@ -1930,8 +1985,9 @@ module.exports = {
1930
1985
  Digraph,
1931
1986
  analyzeMetaData,
1932
1987
  processContextsB,
1933
- processInstance,
1988
+ loadInstance,
1934
1989
  gs,
1935
1990
  flattens,
1936
1991
  writeTest
1937
1992
  }
1993
+