theprogrammablemind 7.5.8-beta.1 → 7.5.8-beta.3

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
@@ -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.3",
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