theprogrammablemind_4wp 7.5.8-beta.1 → 7.5.8-beta.10

Sign up to get free protection for your applications and to get access to all the features.
package/client.js CHANGED
@@ -288,7 +288,7 @@ const writeTestFile = (fn, tests) => {
288
288
  runtime.fs.writeFileSync(fn, stringify(tests, { space: 2 }), { encoding: 'utf8', flag: 'w+' })
289
289
  }
290
290
 
291
- const writeTest = (fn, query, objects, generated, paraphrases, responses, contexts, associations, metadata, config, saveDeveloper) => {
291
+ const writeTest = (fn, query, objects, generated, paraphrases, responses, contexts, associations, metadata, config, saveDeveloper, paraphrasesParenthesized, generatedParenthesized) => {
292
292
  let tests = []
293
293
  if (runtime.fs.existsSync(fn)) {
294
294
  tests = JSON.parse(runtime.fs.readFileSync(fn))
@@ -298,7 +298,19 @@ const writeTest = (fn, query, objects, generated, paraphrases, responses, contex
298
298
  }
299
299
  associations.sort()
300
300
  // tests[query] = sortJson({ paraphrases, responses, contexts, objects: convertToStable(objects), associations, metadata, config, developerTest: saveDeveloper }, { depth: 25 })
301
- results = sortJson({ query, paraphrases, responses, contexts, objects: convertToStable(objects), associations, metadata, config, developerTest: saveDeveloper }, { depth: 25 })
301
+ debugger
302
+ results = sortJson({
303
+ query,
304
+ paraphrases,
305
+ responses,
306
+ contexts,
307
+ objects: convertToStable(objects),
308
+ associations,
309
+ metadata,
310
+ config,
311
+ developerTest: saveDeveloper,
312
+ paraphrasesParenthesized,
313
+ generatedParenthesized }, { depth: 25 })
302
314
  let wasSet = false;
303
315
  tests.forEach( (test, index) => {
304
316
  if (test.query == query) {
@@ -360,6 +372,8 @@ const processContextsB = ({ config, hierarchy, semantics, generators, json, isTe
360
372
  const contextsPrime = []
361
373
  const generatedPrime = []
362
374
  const paraphrasesPrime = []
375
+ const paraphrasesParenthesizedPrime = []
376
+ const generatedParenthesizedPrime = []
363
377
  const responsesPrime = []
364
378
  const contexts = setupContexts(json.contexts)
365
379
 
@@ -423,7 +437,13 @@ const processContextsB = ({ config, hierarchy, semantics, generators, json, isTe
423
437
  continue
424
438
  }
425
439
  let assumed = { isResponse: true };
426
- const generated = config.getGenerators(json.logs).apply(args, contextPrime, assumed)[0]
440
+ const generated = contextPrime.isResponse ? config.getGenerators(json.logs).apply(args, contextPrime, assumed)[0] : ''
441
+ let generatedParenthesized = []
442
+ if (isTest) {
443
+ config.parenthesized = true
444
+ generatedParenthesized = contextPrime.isResponse ? config.getGenerators(json.logs).apply(args, contextPrime, assumed)[0] : ''
445
+ config.parenthesized = false
446
+ }
427
447
  // assumed = { paraphrase: true, response: false };
428
448
  assumed = { paraphrase: true };
429
449
  args.g = (c) => config.getGenerators(json.logs).apply(args, c, assumed)
@@ -432,7 +452,16 @@ const processContextsB = ({ config, hierarchy, semantics, generators, json, isTe
432
452
  args.gs = gs(args.g)
433
453
  args.gsp = gs(args.gsp)
434
454
  args.gsr = gs(args.gr)
455
+ if (isTest) {
456
+ config.parenthesized = false
457
+ }
435
458
  const paraphrases = config.getGenerators(json.logs).apply(args, contextPrime, assumed)[0]
459
+ let paraphrasesParenthesized = []
460
+ if (isTest) {
461
+ config.parenthesized = true
462
+ paraphrasesParenthesized = config.getGenerators(json.logs).apply(args, contextPrime, assumed)[0]
463
+ config.parenthesized = false
464
+ }
436
465
  args.g = (c) => config.getGenerators(json.logs).apply(args, c)
437
466
  args.gp = (c) => config.getGenerators(json.logs).apply(args, {...c, paraphrase: true, isResponse: false, response: false })
438
467
  args.gr = (c) => config.getGenerators(json.logs).apply(args, {...c, paraphrase: false })
@@ -442,6 +471,10 @@ const processContextsB = ({ config, hierarchy, semantics, generators, json, isTe
442
471
  contextsPrime.push(contextPrime)
443
472
  generatedPrime.push(generated)
444
473
  paraphrasesPrime.push(paraphrases)
474
+ if (isTest) {
475
+ paraphrasesParenthesizedPrime.push(paraphrasesParenthesized)
476
+ generatedParenthesizedPrime.push(generatedParenthesized)
477
+ }
445
478
  if (contextPrime.isResponse) {
446
479
  responsesPrime.push(generated)
447
480
  } else {
@@ -451,7 +484,7 @@ const processContextsB = ({ config, hierarchy, semantics, generators, json, isTe
451
484
  // add results to processed list
452
485
  config.config.objects.processed = config.config.objects.processed || []
453
486
  config.config.objects.processed = config.config.objects.processed.slice(0, 5)
454
- config.config.objects.processed.unshift({ context: contextPrime, paraphrases: paraphrases, responses: responsesPrime })
487
+ config.config.objects.processed.unshift({ context: contextPrime, paraphrases: paraphrases, paraphrasesParenthesized, generatedParenthesized, responses: responsesPrime })
455
488
  } catch (e) {
456
489
  if (Array.isArray(e)) {
457
490
  e = {
@@ -471,7 +504,7 @@ const processContextsB = ({ config, hierarchy, semantics, generators, json, isTe
471
504
  throw e
472
505
  }
473
506
  }
474
- return { contextsPrime, generatedPrime, paraphrasesPrime, responsesPrime }
507
+ return { contextsPrime, generatedPrime, paraphrasesPrime, paraphrasesParenthesizedPrime, generatedParenthesizedPrime, responsesPrime }
475
508
  }
476
509
 
477
510
  const doWithRetries = async (n, url, queryParams, data) => {
@@ -493,17 +526,17 @@ const doWithRetries = async (n, url, queryParams, data) => {
493
526
  }
494
527
  if (result.status === 504) {
495
528
  if (n === 0) {
496
- throw `Error ${result.status} - ${result.statusText}`
529
+ throw new Error(`Error ${result.status} - ${result.statusText}`)
497
530
  } else {
498
531
  continue
499
532
  }
500
533
  }
501
534
  if (result.status >= 500 && result.status < 600) {
502
- throw `Error ${result.status} - ${result.statusText}.`
535
+ throw new Error(`Error ${result.status} - ${result.statusText}.`)
503
536
  } if (result.status >= 404) {
504
- throw `Error ${result.status} - ${result.statusText} - Trying it connect to ${url}`
537
+ throw new Error(`Error ${result.status} - ${result.statusText} - Trying it connect to ${url}`)
505
538
  } else {
506
- throw `Error ${result.status} - ${result.statusText}`
539
+ throw new Error(`Error ${result.status} - ${result.statusText}`)
507
540
  }
508
541
  }
509
542
  }
@@ -598,6 +631,8 @@ const _process = async (config, query, { initializer, commandLineArgs, credentia
598
631
  contexts: [],
599
632
  generated: [],
600
633
  paraphrases: [],
634
+ paraphrasesParenthesized: [],
635
+ generatedParenthesized: [],
601
636
  responses: [],
602
637
  associations: [],
603
638
  }
@@ -633,7 +668,7 @@ const _process = async (config, query, { initializer, commandLineArgs, credentia
633
668
  if (json.status !== 200) {
634
669
  throw json
635
670
  } else {
636
- const { contextsPrime, generatedPrime, paraphrasesPrime, responsesPrime } =
671
+ const { contextsPrime, generatedPrime, paraphrasesPrime, paraphrasesParenthesizedPrime, generatedParenthesizedPrime, responsesPrime } =
637
672
  processContextsB({ isTest, config, hierarchy, json, commandLineArgs /*, generators, semantics */ })
638
673
  response.associations = json.associations
639
674
  response.hierarchy = json.hierarchy
@@ -650,6 +685,8 @@ const _process = async (config, query, { initializer, commandLineArgs, credentia
650
685
  response.contexts = response.contexts.concat(contextsPrime)
651
686
  response.generated = response.generated.concat(generatedPrime)
652
687
  response.paraphrases = response.paraphrases.concat(paraphrasesPrime)
688
+ response.paraphrasesParenthesized = response.paraphrasesParenthesized.concat(paraphrasesParenthesizedPrime)
689
+ response.generatedParenthesized = response.generatedParenthesized.concat(generatedParenthesizedPrime)
653
690
  response.responses = response.responses.concat(responsesPrime)
654
691
  queries = queries.slice(1)
655
692
  }
@@ -657,13 +694,13 @@ const _process = async (config, query, { initializer, commandLineArgs, credentia
657
694
 
658
695
  if (writeTests) {
659
696
  const actual_config = getConfigForTest(config, testConfig)
660
- writeTest(testsFN, query, config.config.objects, response.generated, response.paraphrases, response.responses, response.contexts, response.associations, response.metadata, actual_config, saveDeveloper)
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)
661
698
  }
662
699
 
663
700
  return response
664
701
  } catch(error) {
665
702
  error.query = query
666
- throw error
703
+ errorHandler(error)
667
704
  }
668
705
  }
669
706
 
@@ -697,11 +734,13 @@ const getConfigForTest = (config, testConfig) => {
697
734
  return configForTest
698
735
  }
699
736
 
700
- const runTest = async (config, expected, { verbose, afterTest, testConfig, debug }) => {
737
+ const runTest = async (config, expected, { args, verbose, afterTest, testConfig, debug }) => {
701
738
  const test = expected.query
702
739
  // initialize in between test so state is not preserved since the test was adding without state
703
740
  config.rebuild()
704
- config.addAssociationsFromTests(config.tests)
741
+ if (!args.dontAddAssociations) {
742
+ config.addAssociationsFromTests(config.tests)
743
+ }
705
744
  // config.addAssocationsFromTests(
706
745
  const errorHandler = (error) => {
707
746
  if (error.metadata) {
@@ -736,8 +775,11 @@ const runTest = async (config, expected, { verbose, afterTest, testConfig, debug
736
775
  lines.log()
737
776
  }
738
777
  const expected_objects = sortJson(convertToStable(expected.objects), { depth: 25 })
778
+ delete expected_objects.nameToUUID
739
779
  const actual_objects = sortJson(convertToStable(config.config.objects), { depth: 25 })
740
780
  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)
741
783
  const failed_responses = !matching(result.responses, expected.responses)
742
784
  const failed_contexts = !matching(result.contexts, expected.contexts)
743
785
  const failed_objects = !matching(actual_objects, expected_objects)
@@ -782,7 +824,7 @@ const runTest = async (config, expected, { verbose, afterTest, testConfig, debug
782
824
  const actual_config = sortJson(convertToStable(getConfigForTest(config, testConfig)), { depth: 25 })
783
825
  const expected_config = sortJson(convertToStable(expected.config), { depth: 25 })
784
826
  const failed_config = !matching(actual_config, expected_config)
785
- let failed = failed_paraphrases || failed_responses || failed_contexts || failed_objects || failed_config || failed_checked
827
+ let failed = failed_paraphrases || failed_paraphrasesParenthesized || failed_generatedParenthesized || failed_responses || failed_contexts || failed_objects || failed_config || failed_checked
786
828
  if (!failed) {
787
829
  if (config.afterTest) {
788
830
  failed = config.afterTest({ query: test, expected, actual: result, config })
@@ -790,8 +832,26 @@ const runTest = async (config, expected, { verbose, afterTest, testConfig, debug
790
832
  return {
791
833
  utterance: test,
792
834
  errorFromAfterTest: failed,
793
- expected: { responses: expected.responses, paraphrases: expected.paraphrases, results: expected.contexts, checked: expected_checked, objects: expected_objects, config: expected.config },
794
- actual: { responses: result.responses, paraphrases: result.paraphrases, results: result.contexts, checked: actual_checked, objects: actual_objects, config: actual_config }
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
+ }
795
855
  }
796
856
  }
797
857
  }
@@ -807,8 +867,26 @@ const runTest = async (config, expected, { verbose, afterTest, testConfig, debug
807
867
  if (failed) {
808
868
  return {
809
869
  utterance: test,
810
- expected: { responses: expected.responses, paraphrases: expected.paraphrases, results: expected.contexts, checked: expected_checked, objects: expected_objects, config: expected.config },
811
- actual: { responses: result.responses, paraphrases: result.paraphrases, results: result.contexts, checked: actual_checked, objects: actual_objects, config: actual_config }
870
+ expected: {
871
+ responses: expected.responses,
872
+ paraphrases: expected.paraphrases,
873
+ paraphrasesParenthesized: expected.paraphrasesParenthesized,
874
+ generatedParenthesized: expected.generatedParenthesized,
875
+ results: expected.contexts,
876
+ checked: expected_checked,
877
+ objects: expected_objects,
878
+ config: expected.config
879
+ },
880
+ actual: {
881
+ responses: result.responses,
882
+ paraphrases: result.paraphrases,
883
+ paraphrasesParenthesized: result.paraphrasesParenthesized,
884
+ generatedParenthesized: result.generatedParenthesized,
885
+ results: result.contexts,
886
+ checked: actual_checked,
887
+ objects: actual_objects,
888
+ config: actual_config
889
+ }
812
890
  }
813
891
  }
814
892
  } catch(error) {
@@ -866,13 +944,11 @@ const saveTest = async (testFile, config, test, expected, testConfig, saveDevelo
866
944
  const args = {
867
945
  }
868
946
  const saveObjects = {...config.config.objects}
869
- /*
870
947
  saveObjects.nameToUUID = {}
871
948
  for (let km of config.configs) {
872
949
  saveObjects.nameToUUID[km.name] = km.uuid
873
950
  }
874
- */
875
- writeTest(testFile, test, saveObjects, result.generated, result.paraphrases, result.responses, result.contexts, result.associations, result.metadata, actualConfig, saveDeveloper)
951
+ writeTest(testFile, test, saveObjects, result.generated, result.paraphrases, result.responses, result.contexts, result.associations, result.metadata, actualConfig, saveDeveloper, result.paraphrasesParenthesized, result.generatedParenthesized)
876
952
  }
877
953
 
878
954
  const saveTestsHelper = async (testFile, config, tests, todo, testConfig, saveDeveloper) => {
@@ -1174,7 +1250,9 @@ const build = async ({ config, target, template, errorHandler = defaultErrorHand
1174
1250
  defaultInnerProcess(config, defaultErrorHandler, results)
1175
1251
  }
1176
1252
  if (results.contexts.length > 1) {
1177
- console.log(`query ${query.query}. There is ${results.contexts.length} contexts in the results. Make sure its producing the results that you expect.`)
1253
+ console.log(`query "${query.query}". There is ${results.contexts.length} contexts in the results. Make sure its producing the results that you expect.`)
1254
+ } else if (results.paraphrases[0] != query.query) {
1255
+ console.log(`query "${query.query}". The paraphrase is different from the query "${results.paraphrases[0]}".`)
1178
1256
  } else {
1179
1257
  console.log(`query ${query.query}`)
1180
1258
  }
@@ -1283,19 +1361,19 @@ const knowledgeModule = async ({
1283
1361
  const testConfig = test
1284
1362
 
1285
1363
  if (!moduleFromJSFile) {
1286
- throw "'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."
1364
+ 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.")
1287
1365
  }
1288
1366
  if (!config) {
1289
- throw "'config' is a required parameter. The value should the config that defines the knowledge module."
1367
+ throw new Error("'config' is a required parameter. The value should the config that defines the knowledge module.")
1290
1368
  }
1291
1369
  if (!config.name) {
1292
- throw "config must have 'name' set to the knowledge module name."
1370
+ throw new Error("config must have 'name' set to the knowledge module name.")
1293
1371
  }
1294
1372
  if (!description) {
1295
- throw "'description' is a required parameter. The value should the description of the knowledge module."
1373
+ throw new Error("'description' is a required parameter. The value should the description of the knowledge module.")
1296
1374
  }
1297
1375
  if (!test) {
1298
- throw "'test' is a required parameter. The value should the path to the file used to store the tests of the knowledge module and the contents of the file in the form { name: <filePath>, contexts: <json> }."
1376
+ throw new Error("'test' is a required parameter. The value should the path to the file used to store the tests of the knowledge module and the contents of the file in the form { name: <filePath>, contexts: <json> }.")
1299
1377
  }
1300
1378
 
1301
1379
  const isProcess = require.main === moduleFromJSFile
@@ -1353,7 +1431,7 @@ const knowledgeModule = async ({
1353
1431
  if (!isProcess) {
1354
1432
  if (template) {
1355
1433
  if (config.needsRebuild(template.template, template.instance)) {
1356
- throw `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.`
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.`)
1357
1435
  }
1358
1436
  try {
1359
1437
  config.load(template.template, template.instance)
@@ -1368,6 +1446,13 @@ const knowledgeModule = async ({
1368
1446
  description: 'Entodicton knowledge module'
1369
1447
  })
1370
1448
 
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]))\' })'
1454
+
1455
+
1371
1456
  parser.add_argument('-tmn', '--testModuleName', { help: 'When running tests instead of using the current modules tests use the specified modules tests' })
1372
1457
  parser.add_argument('-t', '--test', { action: 'store_true', help: 'Run the tests. Create tests by running with the --query + --save flag' })
1373
1458
  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' })
@@ -1385,6 +1470,7 @@ const knowledgeModule = async ({
1385
1470
  parser.add_argument('-ip ', '--server', { help: 'Server to run against' })
1386
1471
  parser.add_argument('-qp ', '--queryParams', { help: 'Query params for the server call' })
1387
1472
  parser.add_argument('-dt', '--deleteTest', { help: 'Delete the specified query from the tests file.' })
1473
+ parser.add_argument('--parenthesized', { action: 'store_true', help: 'Show the generated phrases with parenthesis.' })
1388
1474
  parser.add_argument('-c', '--clean', { help: 'Remove data from the test files. a === association' })
1389
1475
  parser.add_argument('-od', '--objectDiff', { action: 'store_true', help: 'When showing the objects use a colour diff' })
1390
1476
  parser.add_argument('-daa', '--dontAddAssociations', { action: 'store_true', help: 'Do not add associations from the tests.' })
@@ -1394,30 +1480,38 @@ const knowledgeModule = async ({
1394
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' })
1395
1481
  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 '})
1396
1482
  parser.add_argument('-d', '--debug', { action: 'store_true', help: 'When running with the --debug flag this set the debug flag in the config' })
1397
- parser.add_argument('-da', '--debugAssociation', { help: 'When running with the --debugAssociation flag the debugging will break when the specified association is added to the config' })
1398
- parser.add_argument('-dh', '--debugHierarchy', { help: 'When running with the --debugHierarchy flag the debugging will break when the specified child-parent pair is added to the config for the main config. Set DEBUG_HIERARCHY to debug any config loaded. For example DEBUG_HIERARCHY=\'["cat", "mammel"]\'' })
1399
- parser.add_argument('-db', '--debugBridge', { help: 'When running with the --debugBridge flag the debugging will break when the specified bridge is added to the config for the main config. Set DEBUG_BRIDGE to debug any config loaded. For example DEBUG_BRIDGE=\'id/level\'' })
1400
- parser.add_argument('-do', '--debugOperator', { help: 'When running with the --debugOperator flag the debugging will break when the specified operator is added to the config for the main config. Set DEBUG_OPERATOR to debug any config loaded. For example DEBUG_OPERATOR=\'([operator] ([arg]))\'' })
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 })
1401
1488
 
1402
1489
  const args = parser.parse_args()
1403
1490
  args.count = args.count || 1
1404
1491
 
1492
+ if (args.parenthesized) {
1493
+ config.parenthesized = true
1494
+ }
1495
+
1405
1496
  if (args.debugAssociation) {
1406
- global.entodictonDebugAssociation = JSON.parse(args.debugAssociation)
1497
+ console.log(helpDebugAssociation)
1498
+ runtime.process.exit(-1)
1407
1499
  }
1408
1500
  if (args.debugHierarchy) {
1409
- global.entodictonDebugHierarchy = JSON.parse(args.debugHierarchy)
1501
+ console.log(helpDebugHierarchy)
1502
+ runtime.process.exit(-1)
1503
+ }
1504
+ if (args.debugPriority) {
1505
+ console.log(helpDebugPriority)
1506
+ runtime.process.exit(-1)
1410
1507
  }
1411
1508
  if (args.debugBridge) {
1412
- // id/level
1413
- global.entodictonDebugBridge = args.debugBridge.split('/')
1414
- if (global.entodictonDebugBridge.length !== 2) {
1415
- console.log('Expected DEBUG_BRIDGE to be of the form "id/level"');
1416
- }
1509
+ console.log(helpDebugBridge)
1510
+ runtime.process.exit(-1)
1417
1511
  }
1418
1512
  if (args.debugOperator) {
1419
- // id/level
1420
- global.entodictonDebugOperator = args.debugOperator
1513
+ console.log(helpDebugOperator)
1514
+ runtime.process.exit(-1)
1421
1515
  }
1422
1516
 
1423
1517
  if (args.clean) {
@@ -1486,87 +1580,94 @@ const knowledgeModule = async ({
1486
1580
  }
1487
1581
  */
1488
1582
 
1489
- if (args.print) {
1490
- if (args.print.includes('t')) {
1491
- console.log("Test queries")
1492
- let counter = 0
1493
- for (const test of config.tests) {
1494
- console.log(`${counter} - ${test.query}`)
1495
- counter += 1
1496
- }
1497
- }
1498
- if (args.print.includes('c')) {
1499
- const { data } = setupProcessB({ config })
1500
- console.log("Config as sent to server")
1501
- console.log(JSON.stringify(data, null, 2));
1583
+ let configPrinted = false
1584
+ const printConfig = () => {
1585
+ if (configPrinted) {
1586
+ return
1502
1587
  }
1588
+ configPrinted = true
1589
+ if (args.print) {
1590
+ if (args.print.includes('t')) {
1591
+ console.log("Test queries")
1592
+ let counter = 0
1593
+ for (const test of config.tests) {
1594
+ console.log(`${counter} - ${test.query}`)
1595
+ counter += 1
1596
+ }
1597
+ }
1598
+ if (args.print.includes('c')) {
1599
+ const { data } = setupProcessB({ config })
1600
+ console.log("Config as sent to server")
1601
+ console.log(JSON.stringify(data, null, 2));
1602
+ }
1503
1603
 
1504
- if (args.print.includes('l')) {
1505
- console.log('Module load ordering')
1506
- for (const km of config.configs) {
1507
- console.log(` ${km.name}`)
1604
+ if (args.print.includes('l')) {
1605
+ console.log('Module load ordering')
1606
+ for (const km of config.configs) {
1607
+ console.log(` ${km.name}`)
1608
+ }
1508
1609
  }
1509
- }
1510
- if (args.print.includes('w')) {
1511
- for (const word in config.config.words) {
1512
- console.log(word.concat(' ', ...config.config.words[word].map((def) => JSON.stringify(def))))
1610
+ if (args.print.includes('w')) {
1611
+ for (const word in config.config.words) {
1612
+ console.log(word.concat(' ', ...config.config.words[word].map((def) => JSON.stringify(def))))
1613
+ }
1513
1614
  }
1514
- }
1515
- if (args.print.includes('b')) {
1516
- for (const bridge of config.config.bridges) {
1517
- console.log(JSON.stringify(bridge))
1615
+ if (args.print.includes('b')) {
1616
+ for (const bridge of config.config.bridges) {
1617
+ console.log(JSON.stringify(bridge))
1618
+ }
1518
1619
  }
1519
- }
1520
- if (args.print.includes('o')) {
1521
- for (const operator of config.config.operators) {
1522
- console.log(JSON.stringify(operator))
1620
+ if (args.print.includes('o')) {
1621
+ for (const operator of config.config.operators) {
1622
+ console.log(JSON.stringify(operator))
1623
+ }
1523
1624
  }
1524
- }
1525
- if (args.print.includes('j')) {
1526
- const { data } = setupProcessB( { config } )
1527
- console.log(JSON.stringify(data, null, 2))
1528
- }
1529
- if (args.print.includes('a')) {
1530
- console.log('associations ================')
1531
- const properties = ['negative', 'positive']
1532
- for (let property of properties) {
1533
- console.log(` ${property} ===============`)
1534
- for (let association of config.config.associations[property]) {
1535
- console.log(` ${JSON.stringify(association)}`)
1625
+ if (args.print.includes('j')) {
1626
+ const { data } = setupProcessB( { config } )
1627
+ console.log(JSON.stringify(data, null, 2))
1628
+ }
1629
+ if (args.print.includes('a')) {
1630
+ console.log('associations ================')
1631
+ const properties = ['negative', 'positive']
1632
+ for (let property of properties) {
1633
+ console.log(` ${property} ===============`)
1634
+ for (let association of config.config.associations[property]) {
1635
+ console.log(` ${JSON.stringify(association)}`)
1636
+ }
1536
1637
  }
1537
1638
  }
1538
- }
1539
- if (args.print.includes('d')) {
1540
- console.log(JSON.stringify(config.config.objects, null, 2))
1541
- }
1542
- if (args.print.includes('p')) {
1543
- for (let priority of config.config.priorities) {
1544
- console.log(JSON.stringify(priority))
1639
+ if (args.print.includes('d')) {
1640
+ console.log(JSON.stringify(config.config.objects, null, 2))
1545
1641
  }
1546
- }
1547
- if (args.print.includes('h')) {
1548
- for (let edge of config.config.hierarchy) {
1549
- console.log(JSON.stringify(edge))
1642
+ if (args.print.includes('p')) {
1643
+ for (let priority of config.config.priorities) {
1644
+ console.log(JSON.stringify(priority))
1645
+ }
1550
1646
  }
1551
- }
1552
- if (args.print.includes('g')) {
1553
- const easyToRead = _.cloneDeep(config.config.generators)
1554
- for (const semantic of easyToRead) {
1555
- semantic.match = semantic.match.toString()
1556
- semantic.apply = semantic.apply.toString()
1557
- if (semantic.applyWrapped) {
1558
- semantic.applyWrapped = semantic.applyWrapped.toString()
1647
+ if (args.print.includes('h')) {
1648
+ for (let edge of config.config.hierarchy) {
1649
+ console.log(JSON.stringify(edge))
1559
1650
  }
1560
1651
  }
1561
- console.dir(easyToRead)
1562
- }
1563
- if (args.print.includes('s')) {
1564
- const easyToRead = _.cloneDeep(config.config.semantics)
1565
- for (const semantic of easyToRead) {
1566
- semantic.match = semantic.match.toString()
1567
- semantic.apply = semantic.apply.toString()
1652
+ if (args.print.includes('g')) {
1653
+ const easyToRead = _.cloneDeep(config.config.generators)
1654
+ for (const semantic of easyToRead) {
1655
+ semantic.match = semantic.match.toString()
1656
+ semantic.apply = semantic.apply.toString()
1657
+ if (semantic.applyWrapped) {
1658
+ semantic.applyWrapped = semantic.applyWrapped.toString()
1659
+ }
1660
+ }
1661
+ console.dir(easyToRead)
1662
+ }
1663
+ if (args.print.includes('s')) {
1664
+ const easyToRead = _.cloneDeep(config.config.semantics)
1665
+ for (const semantic of easyToRead) {
1666
+ semantic.match = semantic.match.toString()
1667
+ semantic.apply = semantic.apply.toString()
1668
+ }
1669
+ console.dir(easyToRead)
1568
1670
  }
1569
- console.dir(easyToRead)
1570
1671
  }
1571
1672
  }
1572
1673
 
@@ -1601,7 +1702,7 @@ const knowledgeModule = async ({
1601
1702
  test = useTestConfig.name
1602
1703
 
1603
1704
  }
1604
- runTests(config, test, { debug: args.debug, testConfig: useTestConfig, verbose: args.testVerbose || args.testAllVerbose, stopAtFirstError: !args.testAllVerbose }).then((results) => {
1705
+ runTests(config, test, { args, debug: args.debug, testConfig: useTestConfig, verbose: args.testVerbose || args.testAllVerbose, stopAtFirstError: !args.testAllVerbose }).then((results) => {
1605
1706
  let newError = false
1606
1707
  if (results.length > 0) {
1607
1708
  let headerShown = false
@@ -1611,6 +1712,12 @@ const knowledgeModule = async ({
1611
1712
  if (JSON.stringify(result.expected.paraphrases) !== JSON.stringify(result.actual.paraphrases)) {
1612
1713
  hasError = true
1613
1714
  }
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
1720
+ }
1614
1721
  if (JSON.stringify(result.expected.responses) !== JSON.stringify(result.actual.responses)) {
1615
1722
  hasError = true
1616
1723
  }
@@ -1623,6 +1730,22 @@ const knowledgeModule = async ({
1623
1730
  console.log('**************************** ERRORS ************************')
1624
1731
  for (const result of results) {
1625
1732
  console.log('Utterance: ', result.utterance)
1733
+ const show = (label, expected, actual) => {
1734
+ if (JSON.stringify(expected) !== JSON.stringify(actual)) {
1735
+ if (!headerShown) {
1736
+ console.log(' Failure')
1737
+ }
1738
+ console.log(` expected ${label}`, expected)
1739
+ console.log(` actual ${label} `, actual)
1740
+ newError = true
1741
+ headerShown = true
1742
+ }
1743
+ }
1744
+ show('paraphrases', result.expected.paraphrases, result.actual.paraphrases)
1745
+ show('paraphrases parenthesized', result.expected.paraphrasesParenthesized, result.actual.paraphrasesParenthesized)
1746
+ show('responses', result.expected.responses, result.actual.responses)
1747
+ show('responses parenthesized', result.expected.generatedParenthesized, result.actual.generatedParenthesized)
1748
+ /*
1626
1749
  if (JSON.stringify(result.expected.paraphrases) !== JSON.stringify(result.actual.paraphrases)) {
1627
1750
  if (!headerShown) {
1628
1751
  console.log(' Failure')
@@ -1641,6 +1764,7 @@ const knowledgeModule = async ({
1641
1764
  newError = true
1642
1765
  headerShown = true
1643
1766
  }
1767
+ */
1644
1768
  if (JSON.stringify(result.expected.checked) !== JSON.stringify(result.actual.checked)) {
1645
1769
  if (!headerShown) {
1646
1770
  console.log(' Failure')
@@ -1702,7 +1826,7 @@ const knowledgeModule = async ({
1702
1826
  console.log(results.responses.join(' '))
1703
1827
  })
1704
1828
  if (!('then' in promise)) {
1705
- throw 'Return a promise from process in the definition of knowledgeModule'
1829
+ throw new Error('Return a promise from process in the definition of knowledgeModule')
1706
1830
  }
1707
1831
  promise
1708
1832
  .then(() => {
@@ -1727,11 +1851,12 @@ const knowledgeModule = async ({
1727
1851
  }
1728
1852
  config.beforeQuery({ query: args.query, isModule: false, objects })
1729
1853
  try {
1730
- processResults(_process(config, args.query, { commandLineArgs: args, dontAddAssociations: args.dontAddAssociations, writeTests: args.save || args.saveDeveloper, saveDeveloper: args.saveDeveloper, testConfig, testsFN: test }))
1854
+ await processResults(_process(config, args.query, { commandLineArgs: args, dontAddAssociations: args.dontAddAssociations, writeTests: args.save || args.saveDeveloper, saveDeveloper: args.saveDeveloper, testConfig, testsFN: test }))
1731
1855
  } catch( error ) {
1732
1856
  console.log('Error', error);
1733
1857
  }
1734
1858
  }
1859
+ printConfig()
1735
1860
  } else {
1736
1861
  config.addAssociationsFromTests(config.tests);
1737
1862
  //for (let query in config.tests) {
@@ -1739,6 +1864,7 @@ const knowledgeModule = async ({
1739
1864
  //}
1740
1865
  module()
1741
1866
  }
1867
+
1742
1868
  }
1743
1869
 
1744
1870
  /*
package/lines.js CHANGED
@@ -13,7 +13,7 @@ class Lines {
13
13
  setElement (row, column, value) {
14
14
  const values = value.toString().split('\n')
15
15
  if (column >= this.widths.length) {
16
- throw "Column out of range."
16
+ throw new Error("Column out of range.")
17
17
  }
18
18
  const width = this.widths[column]
19
19
  let index = 0
package/package.json CHANGED
@@ -63,6 +63,6 @@
63
63
  "json-stable-stringify": "^1.0.1",
64
64
  "node-fetch": "^2.6.1"
65
65
  },
66
- "version": "7.5.8-beta.1",
66
+ "version": "7.5.8-beta.10",
67
67
  "license": "ISC"
68
68
  }
package/src/config.js CHANGED
@@ -5,6 +5,7 @@ const { Generators } = require('./generators')
5
5
  const client = require('../client')
6
6
  const DigraphInternal = require('./digraph_internal')
7
7
  const helpers = require('./helpers')
8
+ const { ecatch } = require('./helpers')
8
9
  const runtime = require('../runtime')
9
10
  const _ = require('lodash')
10
11
 
@@ -22,103 +23,131 @@ const indent = (string, indent) => {
22
23
  }
23
24
 
24
25
  const handleBridgeProps = (config, bridge) => {
25
- if (!bridge.bridge) {
26
- bridge.bridge = "{ ...next(operator) }"
27
- }
28
- if (!bridge.level) {
29
- bridge.level = 0
30
- }
31
- if (bridge.children) {
32
- for (let child of bridge.children) {
33
- config.addHierarchy(child, bridge.id)
34
- }
35
- }
36
- if (bridge.parents) {
37
- for (let parent of bridge.parents) {
38
- config.addHierarchy(bridge.id, parent)
39
- }
40
- }
41
- if (bridge.isA) {
42
- for (let parent of bridge.isA) {
43
- config.addHierarchy(bridge.id, parent)
44
- }
45
- }
46
- if (bridge.before) {
47
- for (let after of bridge.before) {
48
- if (typeof after == 'string') {
49
- after = [after, 0]
26
+ ecatch(`While processing the bridge for ${bridge.id}#${bridge.level}`,
27
+ () => {
28
+ if (!bridge.bridge) {
29
+ bridge.bridge = "{ ...next(operator) }"
50
30
  }
51
- config.addPriorities([after, [bridge.id, bridge.level]])
52
- }
53
- }
54
- if (bridge.words) {
55
- for (let def of bridge.words) {
56
- if (typeof def == 'string') {
57
- config.addWordInternal(def, {"id": bridge.id, "initial": `{ value: "${def}"}` })
58
- } else {
59
- const word = def.word
60
- def = { initial: JSON.stringify(def), id: bridge.id, word: undefined }
61
- config.addWordInternal(word, def)
31
+ if (!bridge.level) {
32
+ bridge.level = 0
33
+ }
34
+ if (bridge.children) {
35
+ for (let child of bridge.children) {
36
+ config.addHierarchy(child, bridge.id)
37
+ }
38
+ }
39
+ if (bridge.parents) {
40
+ for (let parent of bridge.parents) {
41
+ config.addHierarchy(bridge.id, parent)
42
+ }
43
+ }
44
+ if (bridge.isA) {
45
+ for (let parent of bridge.isA) {
46
+ config.addHierarchy(bridge.id, parent)
47
+ }
48
+ }
49
+ if (bridge.before) {
50
+ for (let after of bridge.before) {
51
+ if (typeof after == 'string') {
52
+ after = [after, 0]
53
+ }
54
+ config.addPriorities([after, [bridge.id, bridge.level]])
55
+ }
56
+ }
57
+ if (bridge.after) {
58
+ for (let before of bridge.after) {
59
+ if (typeof before == 'string') {
60
+ before = [before, 0]
61
+ }
62
+ config.addPriorities([[bridge.id, bridge.level], before])
63
+ }
64
+ }
65
+ if (bridge.words) {
66
+ for (let def of bridge.words) {
67
+ if (typeof def == 'string') {
68
+ config.addWordInternal(def, {"id": bridge.id, "initial": `{ value: "${def}"}` })
69
+ } else {
70
+ const word = def.word
71
+ def = { initial: JSON.stringify(def), id: bridge.id, word: undefined }
72
+ config.addWordInternal(word, def)
73
+ }
74
+ }
75
+ }
76
+ if (bridge.generator) {
77
+ config.config.generators.unshift(bridge.generator)
78
+ }
79
+ if (bridge.generators) {
80
+ const generators = [...bridge.generators]
81
+ generators.reverse()
82
+ for (let generator of generators) {
83
+ config.config.generators.unshift(generator)
84
+ }
85
+ }
86
+ if (bridge.generatorpr) {
87
+ bridge.generatorp = bridge.generatorpr
88
+ bridge.generatorr = bridge.generatorpr
89
+ }
90
+ if (bridge.generatorp) {
91
+ const match = bridge.generatorp.match || (() => true)
92
+ const apply = typeof bridge.generatorp == 'function' ? bridge.generatorp : bridge.generatorp.apply || bridge.generatorp
93
+ const level = bridge.generatorp.level >= 0 ? bridge.generatorp.level : bridge.level + 1
94
+ config.config.generators.unshift({
95
+ where: bridge.generatorp.where || bridge.where || client.where(4),
96
+ match: (args) => bridge.id == args.context.marker && args.context.level == level && args.context.paraphrase && match(args),
97
+ apply: (args) => apply(args),
98
+ applyWrapped: apply,
99
+ property: 'generatorp',
100
+ })
101
+ }
102
+ if (bridge.generatorr) {
103
+ const match = bridge.generatorr.match || (() => true)
104
+ const apply = typeof bridge.generatorr == 'function' ? bridge.generatorr : bridge.generatorr.apply || bridge.generatorr
105
+ const level = bridge.generatorr.level >= 0 ? bridge.generatorr.level : bridge.level + 1
106
+ config.config.generators.unshift({
107
+ where: bridge.generatorr.where || bridge.where || client.where(4),
108
+ match: (args) => bridge.id == args.context.marker && args.context.level == level && !args.context.paraphrase && (args.context.response || args.context.isResponse) && match(args),
109
+ apply: (args) => apply(args),
110
+ applyWrapped: apply,
111
+ property: 'generatorr',
112
+ })
113
+ }
114
+ /*
115
+ if (bridge.generatorr) {
116
+ config.config.generators.unshift({
117
+ // TODO merge response and isResponse
118
+ where: bridge.generatorr.where || bridge.where || client.where(3),
119
+ match: ({context}) => bridge.id == context.marker && !context.paraphrase && (context.response || context.isResponse),
120
+ apply: (args) => bridge.generatorr(args),
121
+ applyWrapped: bridge.generatorr,
122
+ property: 'generatorr',
123
+ })
124
+ }
125
+ */
126
+ if (bridge.evaluator) {
127
+ config.config.semantics.unshift({
128
+ where: bridge.evaluator.where || bridge.where || client.where(3),
129
+ match: ({context}) => bridge.id == context.marker && context.evaluate,
130
+ apply: (args) => bridge.evaluator(args),
131
+ applyWrapped: bridge.evaluator,
132
+ property: 'evaluator',
133
+ })
134
+ }
135
+ if (bridge.semantic) {
136
+ config.config.semantics.unshift({
137
+ where: bridge.semantic.where || bridge.where || client.where(3),
138
+ match: ({context}) => bridge.id == context.marker,
139
+ apply: (args) => bridge.semantic(args),
140
+ applyWrapped: bridge.semantic,
141
+ property: 'semantic',
142
+ })
62
143
  }
63
144
  }
64
- }
65
- if (bridge.generator) {
66
- config.config.generators.unshift(bridge.generator)
67
- }
68
- if (bridge.generators) {
69
- const generators = [...bridge.generators]
70
- generators.reverse()
71
- for (let generator of generators) {
72
- config.config.generators.unshift(generator)
73
- }
74
- }
75
- if (bridge.generatorpr) {
76
- bridge.generatorp = bridge.generatorpr
77
- bridge.generatorr = bridge.generatorpr
78
- }
79
- if (bridge.generatorp) {
80
- config.config.generators.unshift({
81
- where: bridge.generatorp.where || bridge.where || client.where(4),
82
- // match: ({context}) => bridge.id == context.marker && context.paraphrase,
83
- match: ({context}) => bridge.id == context.marker && context.level == bridge.level + 1 && context.paraphrase,
84
- apply: (args) => bridge.generatorp(args),
85
- applyWrapped: bridge.generatorp,
86
- property: 'generatorp',
87
- })
88
- }
89
- if (bridge.generatorr) {
90
- config.config.generators.unshift({
91
- // TODO merge response and isResponse
92
- where: bridge.generatorr.where || bridge.where || client.where(3),
93
- match: ({context}) => bridge.id == context.marker && !context.paraphrase && (context.response || context.isResponse),
94
- apply: (args) => bridge.generatorr(args),
95
- applyWrapped: bridge.generatorr,
96
- property: 'generatorr',
97
- })
98
- }
99
- if (bridge.evaluator) {
100
- config.config.semantics.unshift({
101
- where: bridge.evaluator.where || bridge.where || client.where(3),
102
- match: ({context}) => bridge.id == context.marker && context.evaluate,
103
- apply: (args) => bridge.evaluator(args),
104
- applyWrapped: bridge.evaluator,
105
- property: 'evaluator',
106
- })
107
- }
108
- if (bridge.semantic) {
109
- config.config.semantics.unshift({
110
- where: bridge.semantic.where || bridge.where || client.where(3),
111
- match: ({context}) => bridge.id == context.marker,
112
- apply: (args) => bridge.semantic(args),
113
- applyWrapped: bridge.semantic,
114
- property: 'semantic',
115
- })
116
- }
145
+ )
117
146
  }
118
147
 
119
148
  const handleCalculatedProps = (baseConfig, moreConfig) => {
120
149
  for (let bridge of moreConfig.bridges) {
121
- const valid = [ 'before', 'bridge', 'development', 'evaluator', 'generatorp', 'generatorr', 'generatorpr', 'generators', 'id', 'convolution', 'inverted', 'isA', 'children', 'parents',
150
+ const valid = [ 'after', 'before', 'bridge', 'development', 'evaluator', 'generatorp', 'generatorr', 'generatorpr', 'generators', 'id', 'convolution', 'inverted', 'isA', 'children', 'parents',
122
151
  'level', 'optional', 'selector', 'semantic', 'words', /Bridge$/, 'localHierarchy', 'levelSpecificHierarchy', 'where' ]
123
152
  helpers.validProps(valid, bridge, 'bridge')
124
153
  handleBridgeProps(baseConfig, bridge)
@@ -138,13 +167,21 @@ if (runtime.process.env.DEBUG_HIERARCHY) {
138
167
  global.entodictonDebugHierarchy = JSON.parse(runtime.process.env.DEBUG_HIERARCHY)
139
168
  }
140
169
 
170
+ if (runtime.process.env.DEBUG_PRIORITY) {
171
+ global.entodictonDebugPriority = JSON.parse(runtime.process.env.DEBUG_PRIORITY)
172
+ }
173
+
174
+ if (runtime.process.env.DEBUG_ASSOCIATION) {
175
+ global.entodictonDebugAssociation = JSON.parse(runtime.process.env.DEBUG_ASSOCIATION)
176
+ }
177
+
141
178
  if (runtime.process.env.DEBUG_BRIDGE) {
142
179
  // id/level
143
180
  global.entodictonDebugBridge = runtime.process.env.DEBUG_BRIDGE.split('/')
144
181
  if (global.entodictonDebugBridge.length !== 2) {
145
182
  console.log('Expected DEBUG_BRIDGE to be of the form "id/level"');
146
183
  }
147
- global.entodictonDebugBridge[1] = int(global.entodictonDebugBridge[1])
184
+ global.entodictonDebugBridge[1] = parseInt(global.entodictonDebugBridge[1])
148
185
  }
149
186
 
150
187
  if (runtime.process.env.DEBUG_OPERATOR) {
@@ -162,7 +199,7 @@ const hierarchyCanonical = (element) => {
162
199
 
163
200
  const isValidDef = (word, def, config) => {
164
201
  if (!def.id) {
165
- throw `In the KM "${config.name}", for the word ${word} the following definition is missing the "id" property: ${JSON.stringify(def)}`
202
+ throw new Error(`In the KM "${config.name}", for the word ${word} the following definition is missing the "id" property: ${JSON.stringify(def)}`)
166
203
  }
167
204
  /*
168
205
  if (!def.initial) {
@@ -725,7 +762,7 @@ class Config {
725
762
  "semantics",
726
763
  "associations",
727
764
  ]
728
- return !properties.find( (property) => instance[property].length > 0 )
765
+ return !properties.find( (property) => instance[property] && instance[property].length > 0 )
729
766
  }
730
767
  if (!isEmpty(instance)) {
731
768
  instance.name = this.name
@@ -779,10 +816,15 @@ class Config {
779
816
  if (!this.config.priorities) {
780
817
  this.config.priorities = []
781
818
  }
819
+ if (global.entodictonDebugPriority) {
820
+ if (helpers.safeEquals(entodictonDebugPriority, priorities)) {
821
+ debugger; // debug hierarchy hit
822
+ }
823
+ }
782
824
  this.config.priorities.push(priorities)
783
825
  this._delta.json.priorities.push({ action: 'add', priorities })
784
826
  }
785
-
827
+
786
828
  addHierarchy (child, parent) {
787
829
  if (child && parent || !child || Array.isArray(child) || (typeof child == 'string' && !parent)) {
788
830
  this.addHierarchyChildParent(child, parent)
@@ -795,13 +837,13 @@ class Config {
795
837
  addHierarchyProperties (edge) {
796
838
  const { child, parent } = edge
797
839
  if (typeof child !== 'string') {
798
- throw `addHierarchy expected child property to be a string. got ${JSON.stringify(child)}`
840
+ throw new Error(`addHierarchy expected child property to be a string. got ${JSON.stringify(child)}`)
799
841
  }
800
842
  if (typeof parent !== 'string') {
801
- throw `addHierarchy expected parent property to be a string. got ${JSON.stringify(parent)}`
843
+ throw new Error(`addHierarchy expected parent property to be a string. got ${JSON.stringify(parent)}`)
802
844
  }
803
845
  if (global.entodictonDebugHierarchy) {
804
- if ((helpers.safeEquals.entodictonDebugHierarchy, [child, parent])) {
846
+ if (helpers.safeEquals(entodictonDebugHierarchy, [child, parent])) {
805
847
  debugger; // debug hierarchy hit
806
848
  }
807
849
  }
@@ -812,10 +854,10 @@ class Config {
812
854
 
813
855
  addHierarchyChildParent (child, parent) {
814
856
  if (typeof child !== 'string') {
815
- throw `addHierarchy expected child to be a string. got ${JSON.stringify(child)}`
857
+ throw new Error(`addHierarchy expected child to be a string. got ${JSON.stringify(child)}`)
816
858
  }
817
859
  if (typeof parent !== 'string') {
818
- throw `addHierarchy expected parent to be a string. got ${JSON.stringify(parent)}`
860
+ throw new Error(`addHierarchy expected parent to be a string. got ${JSON.stringify(parent)}`)
819
861
  }
820
862
 
821
863
  if (global.entodictonDebugHierarchy) {
@@ -848,7 +890,7 @@ class Config {
848
890
  }
849
891
  const bridges = this.config.bridges
850
892
  const def = Object.assign({}, bridge, { uuid: this._uuid })
851
-
893
+
852
894
  if (global.entodictonDebugBridge) {
853
895
  if (global.entodictonDebugBridge[0] == bridge.id && global.entodictonDebugBridge[1] == bridge.level) {
854
896
  debugger; // debug hierarchy hit
@@ -876,10 +918,10 @@ class Config {
876
918
  }
877
919
 
878
920
  if (!(typeof generator.match === 'function')) {
879
- throw 'addGenerator: Expected matcher to be a function'
921
+ throw new Error('addGenerator: Expected matcher to be a function')
880
922
  }
881
923
  if (!(typeof generator.apply === 'function')) {
882
- throw 'addGenerator: Expected action to be a function'
924
+ throw new Error('addGenerator: Expected action to be a function')
883
925
  }
884
926
 
885
927
  if (!this.config.generators) {
@@ -903,10 +945,10 @@ class Config {
903
945
  }
904
946
 
905
947
  if (!(typeof semantic.match === 'function')) {
906
- throw 'addSemantic: Expected match to be a function'
948
+ throw new Error('addSemantic: Expected match to be a function')
907
949
  }
908
950
  if (!(typeof semantic.apply === 'function')) {
909
- throw 'addSemantic: Expected apply to be a function'
951
+ throw new Error('addSemantic: Expected apply to be a function')
910
952
  }
911
953
 
912
954
  if (!this.config.semantics) {
@@ -1180,7 +1222,7 @@ class Config {
1180
1222
  // configs = [ { config, namespace } ... ]
1181
1223
  constructor (config, module) {
1182
1224
  if (config instanceof Config) {
1183
- throw 'Excepted the config argument to be a hash not a Config object'
1225
+ throw new Error('Excepted the config argument to be a hash not a Config object')
1184
1226
  }
1185
1227
 
1186
1228
  if (config) {
@@ -1261,7 +1303,7 @@ class Config {
1261
1303
  }
1262
1304
  duplicated = Array.from(duplicated)
1263
1305
  if (duplicated.length > 0) {
1264
- throw `In the KM ${config.name}, the following operators are duplicated in the bridges: ${duplicated}`
1306
+ throw new Error(`In the KM ${config.name}, the following operators are duplicated in the bridges: ${duplicated}`)
1265
1307
  }
1266
1308
  }
1267
1309
 
@@ -1376,13 +1418,13 @@ class Config {
1376
1418
  if (this._api && this._api.multiApi) {
1377
1419
  this._api.add(this, this._api, api)
1378
1420
  } else {
1379
- throw "Can only add apis to a multi-api";
1421
+ throw new Error("Can only add apis to a multi-api")
1380
1422
  }
1381
1423
  }
1382
1424
 
1383
1425
  set api (value) {
1384
1426
  if (!value.initialize) {
1385
- throw `Expected the API to have an initialize function for ${this.name}.`
1427
+ throw new Error(`Expected the API to have an initialize function for ${this.name}.`)
1386
1428
  }
1387
1429
 
1388
1430
  if (this._api && this._api.multiApi) {
@@ -1449,7 +1491,7 @@ class Config {
1449
1491
  }
1450
1492
 
1451
1493
  doMotivations (args, context) {
1452
- args = Object.assign({}, args, { context })
1494
+ args = Object.assign({}, args, { context, api: this.api })
1453
1495
  // console.log('src/config doMotivations this.uuid', this.uuid)
1454
1496
  // args.objects = args.getObjects(this.uuid)
1455
1497
  const motivations = this.motivations
@@ -1684,7 +1726,7 @@ class Config {
1684
1726
  for (let option of Object.keys(options)) {
1685
1727
  const validOptions = ['initAfterApi']
1686
1728
  if (!['initAfterApi'].includes(option)) {
1687
- throw `For Config.initializer, unrecognized option ${option}. The valid options are ${validOptions}`
1729
+ throw new Error(`For Config.initializer, unrecognized option ${option}. The valid options are ${validOptions}`)
1688
1730
  }
1689
1731
  }
1690
1732
  }
@@ -1921,7 +1963,20 @@ class Config {
1921
1963
  // TODO change name of config: to baseConfig:
1922
1964
  const kmFn = (name) => this.getConfig(name)
1923
1965
  // const hierarchy = new DigraphInternal((config.config || {}).hierarchy)
1924
- const args = { isModule, addWord: aw, km: kmFn, hierarchy: this.hierarchy, config, baseConfig: this, currentConfig: config, uuid: config._uuid, objects: namespacedObjects, namespace, api: config.api }
1966
+ const args = {
1967
+ isModule,
1968
+ addWord: aw,
1969
+ km: kmFn,
1970
+ hierarchy: this.hierarchy,
1971
+ config,
1972
+ baseConfig: this,
1973
+ currentConfig: config,
1974
+ uuid: config._uuid,
1975
+ objects: namespacedObjects,
1976
+ namespace,
1977
+ motivation: (m) => config.addMotivation(m),
1978
+ api: config.api
1979
+ }
1925
1980
  config.initializerFn(args)
1926
1981
  if (config.initAfterApi) {
1927
1982
  // reverse the list
@@ -2309,14 +2364,14 @@ class Config {
2309
2364
 
2310
2365
  set (property, value) {
2311
2366
  if (!this.config.hasOwnProperty(property)) {
2312
- throw `Setting invalid property ${property}`
2367
+ throw new Error(`Setting invalid property ${property}`)
2313
2368
  }
2314
2369
 
2315
2370
  if ('words' == property) {
2316
2371
  for (let word in value) {
2317
2372
  for (let def of value[word]) {
2318
2373
  if (!def['uuid']) {
2319
- throw `All definitions for '${property}' must have the uuid property set (config.uuid). uuid is missing from ${JSON.stringify(def)} for the word '${word}'`
2374
+ throw new Error(`All definitions for '${property}' must have the uuid property set (config.uuid). uuid is missing from ${JSON.stringify(def)} for the word '${word}'`)
2320
2375
  }
2321
2376
  }
2322
2377
  }
@@ -2325,7 +2380,7 @@ class Config {
2325
2380
  if (['operators', 'bridges'].includes(property)) {
2326
2381
  for (let def of value) {
2327
2382
  if (!def['uuid']) {
2328
- throw `All definitions for '${property}' must have the uuid property set (config.uuid). uuid is missing from ${JSON.stringify(def)}`
2383
+ throw new Error(`All definitions for '${property}' must have the uuid property set (config.uuid). uuid is missing from ${JSON.stringify(def)}`)
2329
2384
  }
2330
2385
  }
2331
2386
  }
@@ -2357,7 +2412,7 @@ class Config {
2357
2412
 
2358
2413
  add (more) {
2359
2414
  if (more === this) {
2360
- throw 'Cannot add an object to itself.'
2415
+ throw new Error('Cannot add an object to itself.')
2361
2416
  }
2362
2417
  if (!(more instanceof Config)) {
2363
2418
  more = new Config(more)
@@ -2525,7 +2580,7 @@ class Config {
2525
2580
  this.config[key] = this.config[key].concat(more[key])
2526
2581
  } else {
2527
2582
  if (!(key in this.config)) {
2528
- throw `Unexpected property in config ${key}`
2583
+ throw new Error(`Unexpected property in config ${key}`)
2529
2584
  }
2530
2585
  this.config[key] = more[key]
2531
2586
  }
@@ -2643,7 +2698,7 @@ class Config {
2643
2698
  this.config[key] = more[key].concat(this.config[key])
2644
2699
  } else {
2645
2700
  if (!(key in this.config)) {
2646
- throw `Unexpected property in config ${key}`
2701
+ throw new Error(`Unexpected property in config ${key}`)
2647
2702
  }
2648
2703
  this.config[key] = more[key]
2649
2704
  }
package/src/generators.js CHANGED
@@ -75,7 +75,7 @@ class Generator {
75
75
 
76
76
  apply (baseArgs, objects, g, gs, context, hierarchy, config, response, log, options = {}) {
77
77
  if (!log) {
78
- throw 'generators.apply argument log is required'
78
+ throw new Error('generators.apply argument log is required')
79
79
  }
80
80
  if (baseArgs.call && config && sbaseArgs.calls.stack.length > config.maxDepth) {
81
81
  throw new Error(`Max depth of ${config.maxDepth} for calls has been exceeded. maxDepth can be set on the config object. To see the calls run with the --dl or set the debugLoops property on the config`)
@@ -292,7 +292,7 @@ class Generators {
292
292
  lines.setElement(0, 2, JSON.stringify(context, null, 2))
293
293
  this.logs.push(lines.toString())
294
294
  }
295
- contextsPrime.push(generated)
295
+ contextsPrime.push((config || {}).parenthesized ? "(" + generated + ")" : generated)
296
296
  }
297
297
  return contextsPrime
298
298
  }
package/src/helpers.js CHANGED
@@ -54,6 +54,9 @@ const safeEquals = (v1, v2) => {
54
54
  } else if (type == 'function') {
55
55
  return v1.toString() == v2.toString()
56
56
  } else {
57
+ if (v1.length != v2.length) {
58
+ return false
59
+ }
57
60
  for (let key in v1) {
58
61
  if (!safeEquals(v1[key], v2[key])) {
59
62
  return false
@@ -235,13 +238,17 @@ const validProps = (valids, object, type) => {
235
238
  for (let prop of Object.keys(object)) {
236
239
  let okay = false
237
240
  for (valid of valids) {
238
- if (prop.match(valid)) {
239
- okay = true
241
+ if (typeof valid == 'string') {
242
+ okay = prop == valid
243
+ } else {
244
+ okay = prop.match(valid)
245
+ }
246
+ if (okay) {
240
247
  break
241
248
  }
242
249
  }
243
250
  if (!okay) {
244
- throw `Unknown property "${prop}" in the ${type}. Valid properties are ${valids}. The ${type} is ${JSON.stringify(object)}`
251
+ throw new Error(`Unknown property "${prop}" in the ${type}. Valid properties are ${valids}. The ${type} is ${JSON.stringify(object)}`)
245
252
  }
246
253
  }
247
254
  }
@@ -309,7 +316,16 @@ const functionsToStrings = (config) => {
309
316
  return config
310
317
  }
311
318
 
319
+ const ecatch = (where, call) => {
320
+ try {
321
+ return call()
322
+ } catch( e ) {
323
+ throw new Error(`${where} ${e}`)
324
+ }
325
+ }
326
+
312
327
  module.exports = {
328
+ ecatch,
313
329
  functionsToStrings,
314
330
  updateQueries,
315
331
  mapInPlace,
package/src/semantics.js CHANGED
@@ -89,7 +89,7 @@ class Semantic {
89
89
  // const ask = baseArgs.getAsk(this.uuid)
90
90
  if (!log) {
91
91
  console.trace()
92
- throw 'log is a required argument'
92
+ throw new Error('log is a required argument')
93
93
  }
94
94
  const contextPrime = Object.assign({}, context)
95
95
  let n = (id) => id