theprogrammablemind_4wp 7.4.0 → 7.4.1

Sign up to get free protection for your applications and to get access to all the features.
package/client.js CHANGED
@@ -12,14 +12,16 @@ const { appendNoDups, InitCalls } = require('./src/helpers')
12
12
  const runtime = require('./runtime')
13
13
  const sortJson = runtime.sortJson
14
14
 
15
- const ask = (config) => (asks) => {
15
+ const getAsk = (config) => (uuid) => (asks) => {
16
16
  for (let ask of asks) {
17
17
  config.addMotivation({
18
+ uuid,
18
19
  match: (args) => ask.matchr(args),
19
20
  apply: (args) => ask.applyr(args)
20
21
  })
21
22
  }
22
23
  config.addMotivation({
24
+ uuid,
23
25
  match: ({context}) => context.marker == 'controlEnd' || context.marker == 'controlBetween',
24
26
  apply: (args) => {
25
27
  for (let ask of asks) {
@@ -100,7 +102,25 @@ const setupArgs = (args, config, logs, hierarchy) => {
100
102
  args.listable = listable(hierarchy)
101
103
  args.asList = asList
102
104
  args.retry = () => { throw new RetryError() }
103
- args.ask = ask(config)
105
+ const scopedAsk = getAsk(config)
106
+
107
+ const getAPI = (uuid) => {
108
+ if (config && config.getAPI) {
109
+ return config.getAPI(uuid)
110
+ }
111
+ }
112
+ const getAPIs = (uuid) => {
113
+ if (config && config.getAPIs) {
114
+ return config.getAPIs(uuid)
115
+ }
116
+ }
117
+ args.getUUIDScoped = (uuid) => {
118
+ return {
119
+ ask: scopedAsk(uuid),
120
+ api: getAPI(uuid),
121
+ apis: getAPIs(uuid)
122
+ }
123
+ }
104
124
  args.motivation = (m) => config.addMotivation(m)
105
125
  args.s = (c) => config.getSemantics(logs).apply(args, c)
106
126
  args.g = (c) => config.getGenerators(logs).apply(args, c)
@@ -174,11 +194,13 @@ const processContexts = (contexts, params) => {
174
194
  return { contexts: contextsPrime, generated, logs }
175
195
  }
176
196
 
177
- const getObjects = (objects) => (uuid) => {
178
- if (objects && objects.namespaced) {
179
- objects = objects.namespaced[uuid]
197
+ const getObjects = (objects) => {
198
+ return (uuid) => {
199
+ if (objects && objects.namespaced) {
200
+ return objects.namespaced[uuid]
201
+ }
202
+ return objects
180
203
  }
181
- return objects
182
204
  }
183
205
 
184
206
  const processContext = (context, { objects = {}, config, logs = [] }) => {
@@ -484,7 +506,7 @@ const processInstance = (config, instance) => {
484
506
  global.transitoryMode = transitoryMode
485
507
  }
486
508
 
487
- const _process = async (config, query, { credentials, writeTests, isTest, saveDeveloper, testConfig, testsFN, errorHandler = defaultErrorHandler, beforeQuery } = {}) => {
509
+ const _process = async (config, query, { credentials, writeTests, isTest, saveDeveloper, testConfig, testsFN, errorHandler = defaultErrorHandler } = {}) => {
488
510
  if (credentials) {
489
511
  config.server(credentials.server, credentials.key)
490
512
  }
@@ -497,7 +519,7 @@ const _process = async (config, query, { credentials, writeTests, isTest, saveDe
497
519
  if (writeTests) {
498
520
  config.rebuild()
499
521
  const objects = getObjects(config.config.objects)(config.uuid)
500
- beforeQuery({ query, isModule: false, objects })
522
+ config.beforeQuery({ query, isModule: false, objects })
501
523
  }
502
524
  } catch(error) {
503
525
  throw error
@@ -598,7 +620,7 @@ const getConfigForTest = (config, testConfig) => {
598
620
  return configForTest
599
621
  }
600
622
 
601
- const runTest = async (config, expected, { verbose, beforeQuery, afterTest, testConfig, debug }) => {
623
+ const runTest = async (config, expected, { verbose, afterTest, testConfig, debug }) => {
602
624
  const test = expected.query
603
625
  // initialize in between test so state is not preserved since the test was adding without state
604
626
  config.rebuild()
@@ -616,7 +638,7 @@ const runTest = async (config, expected, { verbose, beforeQuery, afterTest, test
616
638
  }
617
639
 
618
640
  const objects = getObjects(config.config.objects)(config.uuid)
619
- beforeQuery({ query: test, isModule: false, objects })
641
+ config.beforeQuery({ query: test, isModule: false, objects })
620
642
  config.resetMotivations()
621
643
  try {
622
644
  const result = await _process(config, test, { errorHandler, isTest: true })
@@ -642,8 +664,8 @@ const runTest = async (config, expected, { verbose, beforeQuery, afterTest, test
642
664
  const failed_config = !matching(actual_config, expected_config)
643
665
  let failed = failed_paraphrases || failed_responses || failed_contexts || failed_objects || failed_config
644
666
  if (!failed) {
645
- if (afterTest) {
646
- failed = afterTest({ query: test, expected, actual: result, config })
667
+ if (config.afterTest) {
668
+ failed = config.afterTest({ query: test, expected, actual: result, config })
647
669
  if (failed) {
648
670
  return {
649
671
  utterance: test,
@@ -703,21 +725,20 @@ const runTestsHelper = async (config, tests, failed, juicyBits) => {
703
725
 
704
726
  const runTests = async (config, testFile, juicyBits) => {
705
727
  const tests = JSON.parse(runtime.fs.readFileSync(testFile))
706
- const { beforeTests, afterTests } = juicyBits
707
- beforeTests()
728
+ config.beforeTests()
708
729
  if (juicyBits.verbose) {
709
730
  console.log('\n', testFile, '-----------------------------------------------', '\n')
710
731
  }
711
732
  const v = await runTestsHelper(config, [...tests], [], juicyBits)
712
- afterTests()
733
+ config.afterTests()
713
734
  return v
714
735
  }
715
736
 
716
- const saveTest = async (testFile, config, test, expected, beforeQuery, testConfig, saveDeveloper) => {
737
+ const saveTest = async (testFile, config, test, expected, testConfig, saveDeveloper) => {
717
738
  config.rebuild()
718
739
  const objects = getObjects(config.config.objects)(config.uuid)
719
740
  config.resetMotivations()
720
- beforeQuery({ query: test, isModule: false, objects })
741
+ config.beforeQuery({ query: test, isModule: false, objects })
721
742
  console.log(test)
722
743
  const result = await _process(config, test, { isTest: true })
723
744
  // const actualObjects = config.config.objects
@@ -725,23 +746,23 @@ const saveTest = async (testFile, config, test, expected, beforeQuery, testConfi
725
746
  writeTest(testFile, test, config.config.objects, result.generated, result.paraphrases, result.responses, result.contexts, result.associations, result.metadata, actualConfig, saveDeveloper)
726
747
  }
727
748
 
728
- const saveTestsHelper = async (testFile, config, tests, todo, beforeQuery, testConfig, saveDeveloper) => {
749
+ const saveTestsHelper = async (testFile, config, tests, todo, testConfig, saveDeveloper) => {
729
750
  if (todo.length === 0) {
730
751
  return
731
752
  }
732
753
  const test = todo.pop()
733
754
  config.rebuild()
734
- const result = await saveTest(testFile, config, test, tests[test], beforeQuery, testConfig, saveDeveloper)
755
+ const result = await saveTest(testFile, config, test, tests[test], testConfig, saveDeveloper)
735
756
  // initialize in between test so state is not preserved since the test was adding without state
736
757
  // config.initialize({force: true})
737
758
  config.rebuild()
738
- return saveTestsHelper(testFile, config, tests, todo, beforeQuery, testConfig, saveDeveloper)
759
+ return saveTestsHelper(testFile, config, tests, todo, testConfig, saveDeveloper)
739
760
  }
740
761
 
741
- const saveTests = (config, testFile, beforeQuery, testConfig) => {
762
+ const saveTests = (config, testFile, testConfig) => {
742
763
  const tests = JSON.parse(runtime.fs.readFileSync(testFile))
743
764
  console.log(testFile)
744
- return saveTestsHelper(testFile, config, tests, tests.map( (test) => test.query ), beforeQuery, testConfig)
765
+ return saveTestsHelper(testFile, config, tests, tests.map( (test) => test.query ), testConfig)
745
766
  }
746
767
 
747
768
  /*
@@ -962,7 +983,7 @@ entodicton.knowledgeModule( {
962
983
  `
963
984
  */
964
985
 
965
- const build = async ({ config, target, beforeQuery, template, errorHandler = defaultErrorHandler }) => {
986
+ const build = async ({ config, target, template, errorHandler = defaultErrorHandler }) => {
966
987
  const accumulators = {
967
988
  resultss: [],
968
989
  fragments: [],
@@ -1000,7 +1021,7 @@ const build = async ({ config, target, beforeQuery, template, errorHandler = def
1000
1021
  }
1001
1022
 
1002
1023
  try {
1003
- const results = await _process(config, query.query, { beforeQuery })
1024
+ const results = await _process(config, query.query, {})
1004
1025
  if (config.config.debug) {
1005
1026
  // TODO pass in the error handler like the other ones
1006
1027
  defaultInnerProcess(config, defaultErrorHandler, results)
@@ -1097,11 +1118,40 @@ const knowledgeModule = async ({
1097
1118
  afterTest = () => {}
1098
1119
  } = {}) => {
1099
1120
 
1100
- const isProcess = require.main === moduleFromJSFile
1121
+ config.beforeQuery = beforeQuery
1122
+ config.beforeTests = beforeTests
1123
+ config.afterTests = afterTests
1124
+ config.beforeTest = beforeTest
1125
+ config.afterTest = afterTest
1126
+
1101
1127
  const testConfig = test
1102
1128
 
1129
+ if (!moduleFromJSFile) {
1130
+ 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."
1131
+ }
1132
+ if (!config) {
1133
+ throw "'config' is a required parameter. The value should the config that defines the knowledge module."
1134
+ }
1135
+ if (!config.name) {
1136
+ throw "config must have 'name' set to the knowledge module name."
1137
+ }
1138
+ if (!description) {
1139
+ throw "'description' is a required parameter. The value should the description of the knowledge module."
1140
+ }
1141
+ if (!test) {
1142
+ 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> }."
1143
+ }
1144
+
1145
+ const isProcess = require.main === moduleFromJSFile
1146
+ let loadForTesting = false
1147
+ if (global.theprogrammablemind) {
1148
+ if (global.theprogrammablemind.loadForTesting[config.name]) {
1149
+ loadForTesting = true
1150
+ }
1151
+ }
1152
+
1103
1153
  // remove test only stuff
1104
- if (!isProcess) {
1154
+ if (!isProcess && !loadForTesting) {
1105
1155
  config.config.operators = config.config.operators.filter( (operator) => {
1106
1156
  if (operator.development) {
1107
1157
  return false
@@ -1118,22 +1168,6 @@ const knowledgeModule = async ({
1118
1168
  })
1119
1169
  }
1120
1170
 
1121
- if (!moduleFromJSFile) {
1122
- 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."
1123
- }
1124
- if (!config) {
1125
- throw "'config' is a required parameter. The value should the config that defines the knowledge module."
1126
- }
1127
- if (!config.name) {
1128
- throw "config must have 'name' set to the knowledge module name."
1129
- }
1130
- if (!description) {
1131
- throw "'description' is a required parameter. The value should the description of the knowledge module."
1132
- }
1133
- if (!test) {
1134
- 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> }."
1135
- }
1136
-
1137
1171
  let module
1138
1172
  if (_.isFunction(moduleFromJSFile)) {
1139
1173
  module = moduleFromJSFile
@@ -1172,6 +1206,7 @@ const knowledgeModule = async ({
1172
1206
  description: 'Entodicton knowledge module'
1173
1207
  })
1174
1208
 
1209
+ parser.add_argument('-tfn', '--testFileName', { help: 'Override the test file for the module when the tests are being run' })
1175
1210
  parser.add_argument('-t', '--test', { action: 'store_true', help: 'Run the tests. Create tests by running with the --query + --save flag' })
1176
1211
  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' })
1177
1212
  parser.add_argument('-tva', '--testAllVerbose', { action: 'store_true', help: 'Run the tests in verbose mode. All the tests will be run instead of stopping at first failure. Create tests by running with the --query or --loop with the --save flag' })
@@ -1366,9 +1401,8 @@ const knowledgeModule = async ({
1366
1401
 
1367
1402
  if (!args.query && !args.test && !args.info && (args.save || args.saveDeveloper)) {
1368
1403
  global.transitoryMode = true
1369
- saveTests(config, test, beforeQuery, testConfig, args.saveDeveloper)
1404
+ saveTests(config, test, testConfig, args.saveDeveloper)
1370
1405
  // } else if (args.build) {
1371
- // build({ config, target: args.build, beforeQuery, errorHandler })
1372
1406
  } else if (args.info) {
1373
1407
  showInfo(description, section, config)
1374
1408
  } else if (args.test || args.testVerbose || args.testAllVerbose) {
@@ -1381,7 +1415,7 @@ const knowledgeModule = async ({
1381
1415
  }
1382
1416
  return
1383
1417
  }
1384
- runTests(config, test, { debug: args.debug, testConfig: testConfig, verbose: args.testVerbose || args.testAllVerbose, stopAtFirstError: !args.testAllVerbose, beforeQuery, beforeTests, afterTests, beforeTest, afterTest }).then((results) => {
1418
+ runTests(config, args.testFileName ? `${args.testFileName}.test.json` : test, { debug: args.debug, testConfig: testConfig, verbose: args.testVerbose || args.testAllVerbose, stopAtFirstError: !args.testAllVerbose }).then((results) => {
1385
1419
  if (results.length > 0 && args.vimdiff) {
1386
1420
  for (const result of results) {
1387
1421
  vimdiff(result.expected, result.actual)
@@ -1454,9 +1488,9 @@ const knowledgeModule = async ({
1454
1488
  if (args.objectDiff) {
1455
1489
  global.beforeObjects = _.cloneDeep(objects)
1456
1490
  }
1457
- beforeQuery({ query: args.query, isModule: false, objects })
1491
+ config.beforeQuery({ query: args.query, isModule: false, objects })
1458
1492
  try {
1459
- processResults(_process(config, args.query, { dontAddAssociations: args.dontAddAssociations, writeTests: args.save || args.saveDeveloper, saveDeveloper: args.saveDeveloper, testConfig, testsFN: test, beforeQuery }))
1493
+ processResults(_process(config, args.query, { dontAddAssociations: args.dontAddAssociations, writeTests: args.save || args.saveDeveloper, saveDeveloper: args.saveDeveloper, testConfig, testsFN: test }))
1460
1494
  } catch( error ) {
1461
1495
  console.log('Error', error);
1462
1496
  }
package/package.json CHANGED
@@ -61,6 +61,6 @@
61
61
  "json-stable-stringify": "^1.0.1",
62
62
  "node-fetch": "^2.6.1"
63
63
  },
64
- "version": "7.4.0",
64
+ "version": "7.4.1",
65
65
  "license": "ISC"
66
66
  }
package/src/config.js CHANGED
@@ -767,6 +767,23 @@ class Config {
767
767
  }
768
768
  }
769
769
 
770
+ getAPIs (uuid) {
771
+ let config
772
+ if (this._uuid === uuid) {
773
+ config = this
774
+ } else {
775
+ for (const km of this.configs) {
776
+ if (km._uuid === uuid) {
777
+ config = km.config
778
+ break
779
+ }
780
+ }
781
+ }
782
+ if (config && config._api && config._api.multiApi) {
783
+ return config._api.apis
784
+ }
785
+ }
786
+
770
787
  getServer() {
771
788
  return this._server
772
789
  }
@@ -888,6 +905,19 @@ class Config {
888
905
  return configs;
889
906
  }
890
907
 
908
+ getConfigByUUID (uuid) {
909
+ if (this.uuid === uuid) {
910
+ return this
911
+ }
912
+ for (const config of this.configs) {
913
+ if (config.config instanceof Config) {
914
+ if (config.uuid === uuid) {
915
+ return config.config
916
+ }
917
+ }
918
+ }
919
+ }
920
+
891
921
  getConfig (name) {
892
922
  if (this.name === name) {
893
923
  return this
@@ -932,7 +962,13 @@ class Config {
932
962
  }
933
963
 
934
964
  this.addedArgss = []
935
- const isProcess = require.main === module
965
+ let isProcess = require.main === module
966
+ if (global.theprogrammablemind && config) {
967
+ if (global.theprogrammablemind.loadForTesting[config.name]) {
968
+ isProcess = true
969
+ this.loadedForTesting = true
970
+ }
971
+ }
936
972
  this.isModule = !isProcess
937
973
  if (this.isModule) {
938
974
  this.removeDevelopmentElements(config)
@@ -1198,6 +1234,9 @@ class Config {
1198
1234
 
1199
1235
  // motivation === { match, apply, uuid }
1200
1236
  addMotivation (motivation) {
1237
+ if (!motivation.uuid) {
1238
+ motivation.uuid = this.uuid
1239
+ }
1201
1240
  this.motivations.push(motivation)
1202
1241
  }
1203
1242
 
@@ -1207,11 +1246,13 @@ class Config {
1207
1246
 
1208
1247
  doMotivations (args, context) {
1209
1248
  args = Object.assign({}, args, { context })
1210
- args.objects = args.getObjects(this.uuid)
1249
+ // console.log('src/config doMotivations this.uuid', this.uuid)
1250
+ // args.objects = args.getObjects(this.uuid)
1211
1251
  const motivations = this.motivations
1212
1252
  this.motivations = []
1213
1253
  let done = false
1214
1254
  for (const motivation of motivations) {
1255
+ args.objects = args.getObjects(motivation.uuid)
1215
1256
  if (!done && motivation.match(args)) {
1216
1257
  motivation.apply(args)
1217
1258
  if (args.context.controlKeepMotivation || motivation.repeat) {
@@ -1255,6 +1296,7 @@ class Config {
1255
1296
  cp.tests = this.tests
1256
1297
  cp.motivations = this.motivations
1257
1298
  cp.isModule = this.isModule
1299
+ cp.loadedForTesting = this.loadedForTesting
1258
1300
  cp.initInstances = this.initInstances.slice()
1259
1301
  cp.instances = this.instances.slice()
1260
1302
  cp.configCounter = this.configCounter
@@ -1603,6 +1645,12 @@ class Config {
1603
1645
  // already set
1604
1646
  // this.isModule = this.isModule || mainIsModule
1605
1647
  mainIsModule = (mainIsModule === undefined) ? this.isModule : mainIsModule
1648
+ if (mainIsModule !== undefined) {
1649
+ this.isModule = mainIsModule
1650
+ }
1651
+ if (this.loadedForTesting) {
1652
+ this.isModule = false
1653
+ }
1606
1654
  this.config.objects.namespaced = {}
1607
1655
  this.resetWasInitialized()
1608
1656
 
@@ -1640,7 +1688,9 @@ class Config {
1640
1688
  if (!(config instanceof Config)) {
1641
1689
  config = this
1642
1690
  isSelf = true
1643
- isModule = mainIsModule
1691
+ isModule = config.isModule || mainIsModule
1692
+ } else {
1693
+ isModule = config.isModule
1644
1694
  }
1645
1695
  if (!isSelf) {
1646
1696
  config.config = _.cloneDeep(config.initConfig)
package/src/generators.js CHANGED
@@ -59,7 +59,7 @@ class Generator {
59
59
  api: this.getAPI(config),
60
60
  apis: this.getAPIs(config)
61
61
  }
62
- const args = Object.assign({}, baseArgs, moreArgs)
62
+ const args = Object.assign({}, baseArgs, moreArgs, (baseArgs.getUUIDScoped || (() => { return {} }))(this.uuid))
63
63
  // return this.match(args)
64
64
  const matches = this.match(args)
65
65
  if ((matches && (options.debug || {}).match)
@@ -106,7 +106,7 @@ class Generator {
106
106
  api: this.getAPI(config),
107
107
  apis: this.getAPIs(config)
108
108
  }
109
- const args = Object.assign({}, baseArgs, moreArgs)
109
+ const args = Object.assign({}, baseArgs, moreArgs, (baseArgs.getUUIDScoped || (() => { return {} }))(this.uuid))
110
110
  // if (this.callId) {
111
111
  // greg
112
112
  /*
package/src/semantics.js CHANGED
@@ -45,13 +45,16 @@ class Semantic {
45
45
  matches (baseArgs, context, options = {}) {
46
46
  const hierarchy = baseArgs.hierarchy
47
47
  const config = baseArgs.config
48
+
48
49
  const objects = baseArgs.getObjects(this.uuid)
50
+ // const ask = baseArgs.getAsk(this.uuid)
51
+
49
52
  // return this.matcher(Object.assign({}, argsBase, {args: contextArgs(context, hierarchy), objects: objects, global: objects, context: context, hierarchy: hierarchy, api: this.getAPI(config)})
50
53
  const callId = baseArgs.calls.current()
51
54
  const moreArgs = {
52
55
  uuid: this.uuid,
53
56
  args: contextArgs(context, hierarchy),
54
- objects: objects,
57
+ objects,
55
58
  global: objects,
56
59
  context: context,
57
60
  // hierarchy: hierarchy,
@@ -59,7 +62,7 @@ class Semantic {
59
62
  api: this.getAPI(config),
60
63
  apis: this.getAPIs(config)
61
64
  }
62
- const args = Object.assign({}, baseArgs, moreArgs)
65
+ const args = Object.assign({}, baseArgs, moreArgs, (baseArgs.getUUIDScoped || (() => { return {} }))(this.uuid))
63
66
 
64
67
  const matches = this.matcher(args)
65
68
  if (matches && (options.debug || {}).match
@@ -74,6 +77,7 @@ class Semantic {
74
77
  apply (baseArgs, context, s, log, options = {}) {
75
78
  const { hierarchy, config, response } = baseArgs
76
79
  const objects = baseArgs.getObjects(this.uuid)
80
+ // const ask = baseArgs.getAsk(this.uuid)
77
81
  if (!log) {
78
82
  console.trace()
79
83
  throw 'log is a required argument'
@@ -99,7 +103,7 @@ class Semantic {
99
103
  api: this.getAPI(config),
100
104
  apis: this.getAPIs(config)
101
105
  }
102
- const args = Object.assign({}, baseArgs, moreArgs)
106
+ const args = Object.assign({}, baseArgs, moreArgs, (baseArgs.getUUIDScoped || (() => { return {} }))(this.uuid))
103
107
  if ((options.debug || {}).apply
104
108
  ||
105
109
  callId == this.callId) {