theprogrammablemind 9.1.1-beta.3 → 9.1.1-beta.31

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
@@ -12,9 +12,10 @@ const _ = require('lodash')
12
12
  const stringify = require('json-stable-stringify')
13
13
  const Lines = require('./lines')
14
14
  const flattens = require('./src/flatten')
15
- const { appendNoDups, InitCalls, updateQueries, safeNoDups, stableId, where, suggestAssociationsFix, suggestAssociationsFixFromSummaries } = require('./src/helpers')
15
+ const { appendNoDups, InitCalls, updateQueries, safeNoDups, stableId, where, suggestAssociationsFix, suggestAssociationsFixFromSummaries, validProps } = require('./src/helpers')
16
16
  const runtime = require('./runtime')
17
17
  const sortJson = runtime.sortJson
18
+ const debug = require('./src/debug')
18
19
 
19
20
  const getConfig_getObjectsCheck = (config, testConfig) => {
20
21
  let testConfigName = config.name
@@ -477,6 +478,11 @@ const runTest = async (config, expected, { args, verbose, testConfig, debug, tim
477
478
 
478
479
  const objects = getObjects(config.config.objects)(config.uuid)
479
480
  try {
481
+ if (testConfig.initializer) {
482
+ const args = {}
483
+ setupArgs(args, config)
484
+ await testConfig.initializer(args)
485
+ }
480
486
  const result = await _process(config, test, { errorHandler, isTest: true })
481
487
  result.query = test
482
488
  if (debug) {
@@ -820,7 +826,7 @@ const defaultInnerProcess = (config, errorHandler, responses) => {
820
826
  }
821
827
  console.log(responses.trace)
822
828
 
823
- if (false) {
829
+ if (true) {
824
830
  if (global.beforeObjects) {
825
831
  console.log('objects', runtime.jsonDiff.diffString(global.beforeObjects, config.get('objects')))
826
832
  } else {
@@ -931,6 +937,19 @@ const rebuildTemplate = async ({ config, instance, target, previousResultss, reb
931
937
  learned_contextual_priorities: []
932
938
  }
933
939
  config.fragmentsBeingBuilt = []
940
+
941
+ const toProperties = (queryStringOrProperties) => {
942
+ if (typeof queryStringOrProperties === 'string') {
943
+ return { query: queryStringOrProperties }
944
+ } else {
945
+ return queryStringOrProperties
946
+ }
947
+ }
948
+ const fragmentToTodo = (query, index) => {
949
+ const pr = instance.fragments[index]
950
+ return Object.assign({}, toProperties(query), { property: 'fragments', previousResults: pr, skipSemantics: false })
951
+ }
952
+
934
953
  const looper = async (configs) => {
935
954
  if (configs.length === 0) {
936
955
  finish()
@@ -1024,7 +1043,17 @@ const rebuildTemplate = async ({ config, instance, target, previousResultss, reb
1024
1043
  const objects = config.get('objects')
1025
1044
  const args = { objects, getObjects: getObjects(objects) }
1026
1045
  setupArgs(args, config, config.logs, config.hierarchy)
1046
+ // this watch stuff was for allowing fragment to be made in the template load. that is not a good idea
1047
+ // because needs rebuild would need to run the rebuild to know if a rebuild was needed. the fragment creates
1048
+ // need to go in the intializer
1049
+ // const new_fragments = []
1050
+ // config.watchNewFragments(new_fragments)
1027
1051
  await initFunction(args)
1052
+ /*
1053
+ if (new_fragments.length > 0) {
1054
+ configs = configs.concat(new_fragments.map(fragmentToTodo))
1055
+ }
1056
+ */
1028
1057
  accumulators[property].push({ apply: queryOrExtraConfig })
1029
1058
  await looper(configs)
1030
1059
  } else {
@@ -1093,13 +1122,6 @@ const rebuildTemplate = async ({ config, instance, target, previousResultss, reb
1093
1122
  }
1094
1123
  }
1095
1124
 
1096
- const toProperties = (queryStringOrProperties) => {
1097
- if (typeof queryStringOrProperties === 'string') {
1098
- return { query: queryStringOrProperties }
1099
- } else {
1100
- return queryStringOrProperties
1101
- }
1102
- }
1103
1125
  let todo = []
1104
1126
  todo = todo.concat((template.initializers || []).map((query) => { return { initializer: true, property: 'resultss', query, skipSemantics: false || query.skipSemantics } }))
1105
1127
  /*
@@ -1115,14 +1137,17 @@ const rebuildTemplate = async ({ config, instance, target, previousResultss, reb
1115
1137
  for (let configsIndex = 0; configsIndex < template.configs.length; ++configsIndex) {
1116
1138
  const query = template.configs[configsIndex]
1117
1139
  // account for things for example associations being added to the config while debugginer
1118
- const pr = previousResultss.find((pr) => pr.query == query)
1140
+ const pr = previousResultss && previousResultss.find((pr) => pr.query == query)
1119
1141
  todo.push({ property: 'resultss', query, previousResults: pr, skipSemantics: false || query.skipSemantics })
1120
1142
  }
1121
1143
  }
1144
+ todo = todo.concat((template.fragments || []).map(fragmentToTodo))
1145
+ /*
1122
1146
  todo = todo.concat((template.fragments || []).map((query, index) => {
1123
1147
  const pr = instance.fragments[index]
1124
1148
  return Object.assign({}, toProperties(query), { property: 'fragments', previousResults: pr, skipSemantics: false })
1125
1149
  }))
1150
+ */
1126
1151
  todo = todo.concat((template.semantics || []).map((definition) => {
1127
1152
  return { property: 'semantics', query: `${definition.from}\n${definition.to}`, skipSemantics: true }
1128
1153
  }))
@@ -1136,6 +1161,7 @@ const checkTemplate = (template) => {
1136
1161
  if (template.checks) {
1137
1162
  throw new Error("The 'checks' property should be in the 'test' property not the 'template' property")
1138
1163
  }
1164
+ validProps(['fragments', 'configs'], template.template, 'template.template')
1139
1165
  }
1140
1166
 
1141
1167
  const checkTest = (testConfig) => {
@@ -1156,7 +1182,7 @@ const checkTest = (testConfig) => {
1156
1182
  const knowledgeModuleImpl = async ({
1157
1183
  includes,
1158
1184
  config: configStruct,
1159
- api,
1185
+ api, apiKMs,
1160
1186
  initializer,
1161
1187
  terminator,
1162
1188
  multiApiInitializer,
@@ -1188,8 +1214,31 @@ const knowledgeModuleImpl = async ({
1188
1214
  throw new Error("'config' or 'createConfig' is a required parameter. The value should the config that defines the knowledge module.")
1189
1215
  }
1190
1216
 
1217
+ const setupConfig = (config) => {
1218
+ if (!config.name) {
1219
+ throw new Error("config must have 'name' set to the knowledge module name.")
1220
+ }
1221
+
1222
+ config.description = description
1223
+ if (typeof testConfig === 'object') {
1224
+ if (testConfig.contents) {
1225
+ config.tests = testConfig.contents
1226
+ test = testConfig.name
1227
+ }
1228
+ } else {
1229
+ if (runtime.fs && runtime.fs.existsSync(test)) {
1230
+ config.tests = JSON.parse(runtime.fs.readFileSync(test))
1231
+ } else {
1232
+ config.tests = []
1233
+ }
1234
+ }
1235
+ config.setTestConfig(testConfig)
1236
+ }
1237
+
1191
1238
  const createConfig = async () => {
1192
- const config = new Config(configStruct, moduleFromJSFile, _process)
1239
+ const config = new Config(configStruct, moduleFromJSFile, _process, apiKMs)
1240
+ setupConfig(config)
1241
+ config.expect_template = !!template
1193
1242
  config.setTerminator(terminator)
1194
1243
  config.stop_auto_rebuild()
1195
1244
  await config.add(...(includes || []))
@@ -1216,27 +1265,6 @@ const knowledgeModuleImpl = async ({
1216
1265
 
1217
1266
  const isProcess = require.main === moduleFromJSFile
1218
1267
 
1219
- const setupConfig = (config) => {
1220
- if (!config.name) {
1221
- throw new Error("config must have 'name' set to the knowledge module name.")
1222
- }
1223
-
1224
- config.description = description
1225
- if (typeof testConfig === 'object') {
1226
- if (testConfig.contents) {
1227
- config.tests = testConfig.contents
1228
- test = testConfig.name
1229
- }
1230
- } else {
1231
- if (runtime.fs && runtime.fs.existsSync(test)) {
1232
- config.tests = JSON.parse(runtime.fs.readFileSync(test))
1233
- } else {
1234
- config.tests = []
1235
- }
1236
- }
1237
- config.setTestConfig(testConfig)
1238
- }
1239
-
1240
1268
  if (isProcess) {
1241
1269
  let config
1242
1270
  try {
@@ -1298,7 +1326,6 @@ const knowledgeModuleImpl = async ({
1298
1326
  if (args.rebuildTemplateFull) {
1299
1327
  args.rebuildTemplate = true
1300
1328
  }
1301
-
1302
1329
  config = await createConfig()
1303
1330
 
1304
1331
  // dont debug the load of the KM's if rebuild template is on since we want to debug the template rebuild not the load
@@ -1306,7 +1333,7 @@ const knowledgeModuleImpl = async ({
1306
1333
  global.pauseDebugging = true
1307
1334
  }
1308
1335
 
1309
- setupConfig(config)
1336
+ // setupConfig(config)
1310
1337
  processResults = processResults({ config, errorHandler })
1311
1338
 
1312
1339
  if (args.rebuildTemplate) {
@@ -1542,6 +1569,7 @@ const knowledgeModuleImpl = async ({
1542
1569
  }
1543
1570
  try {
1544
1571
  await config.load(rebuildTemplate, template.template, template.instance, { rebuild: needsRebuild.needsRebuild || options.rebuild, previousResultss: needsRebuild.previousResultss, startOfChanges: needsRebuild.startOfChanges })
1572
+ config.fixtures()
1545
1573
  } catch (e) {
1546
1574
  console.error(`Error loading template for ${config.name}. ${e.error ? e.error : e}${e.stack ? e.stack : ''}`)
1547
1575
  runtime.process.exit(-1)
@@ -1841,6 +1869,7 @@ const knowledgeModuleImpl = async ({
1841
1869
  config.terminate()
1842
1870
  }
1843
1871
  }
1872
+ moduleFromJSFile.exports = createConfig
1844
1873
  } else {
1845
1874
  const initConfig = async (config) => {
1846
1875
  if (template) {
@@ -1910,6 +1939,11 @@ const test = (name) => {
1910
1939
  }
1911
1940
  */
1912
1941
 
1942
+ // for testing
1943
+ const getRequireMain = () => {
1944
+ return require.main
1945
+ }
1946
+
1913
1947
  const ensureTestFile = (module, name, type) => {
1914
1948
  const isProcess = require.main === module
1915
1949
  if (isProcess) {
@@ -1931,6 +1965,7 @@ const knowledgeModule = async (...args) => {
1931
1965
  module.exports = {
1932
1966
  process: _process,
1933
1967
  stableId,
1968
+ getRequireMain, // for testing
1934
1969
  ensureTestFile,
1935
1970
  rebuildTemplate,
1936
1971
  processContext,
package/index.js CHANGED
@@ -6,6 +6,7 @@ const Digraph = require('./src/digraph')
6
6
  const client = require('./client')
7
7
  const flattens = require('./src/flatten')
8
8
  const unflatten = require('./src/unflatten')
9
+ const debug = require('./src/debug')
9
10
 
10
11
  module.exports = {
11
12
  process: client.process,
@@ -26,5 +27,6 @@ module.exports = {
26
27
  Digraph,
27
28
  flattens: flattens.flattens,
28
29
  flatten: flattens.flatten,
29
- unflatten: unflatten.unflatten
30
+ unflatten: unflatten.unflatten,
31
+ debug
30
32
  }
package/package.json CHANGED
@@ -9,7 +9,8 @@
9
9
  "eslint-plugin-node": "^11.1.0",
10
10
  "eslint-plugin-promise": "^5.1.0",
11
11
  "globals": "^16.0.0",
12
- "jest": "^29.7.0"
12
+ "jest": "^29.7.0",
13
+ "argparse": "^2.0.1"
13
14
  },
14
15
  "scripts": {
15
16
  "to:debug": "node inspect node_modules/.bin/jest --runInBand -t NEO23",
@@ -47,6 +48,7 @@
47
48
  "src/config.js",
48
49
  "src/configHelpers.js",
49
50
  "src/copy.js",
51
+ "src/debug.js",
50
52
  "src/digraph.js",
51
53
  "src/digraph_internal.js",
52
54
  "src/generators.js",
@@ -67,6 +69,6 @@
67
69
  "sort-json": "^2.0.0",
68
70
  "uuid": "^8.3.2"
69
71
  },
70
- "version": "9.1.1-beta.3",
72
+ "version": "9.1.1-beta.31",
71
73
  "license": "UNLICENSED"
72
74
  }
package/src/config.js CHANGED
@@ -9,6 +9,7 @@ const { InitCalls } = require('./helpers')
9
9
  const { ecatch } = require('./helpers')
10
10
  const runtime = require('../runtime')
11
11
  const _ = require('lodash')
12
+ const db = require('./debug')
12
13
 
13
14
  const debugBreak = () => {
14
15
  // debugger
@@ -472,7 +473,7 @@ const handleCalculatedProps = (baseConfig, moreConfig, { addFirst, uuid } = {})
472
473
  if (moreConfig.bridges) {
473
474
  moreConfig.bridges = moreConfig.bridges.map((bridge) => {
474
475
  bridge = { ...bridge }
475
- const valid = ['after', 'before', 'bridge', 'development', 'return_type_selector', 'evaluator', 'evaluators', 'generatorp', 'generatorr', 'generatorpr', 'generators', 'operator', 'id', 'convolution', 'inverted', 'isA', 'children', 'parents',
476
+ const valid = ['after', 'associations', 'before', 'bridge', 'development', 'return_type_selector', 'evaluator', 'evaluators', 'generatorp', 'generatorr', 'generatorpr', 'generators', 'operator', 'id', 'convolution', 'inverted', 'isA', 'children', 'parents',
476
477
  'level', 'optional', 'selector', 'semantic', 'semantics', 'words', /Bridge$/, 'localHierarchy', 'levelSpecificHierarchy', 'where', 'uuid']
477
478
  helpers.validProps(valid, bridge, 'bridge')
478
479
  handleBridgeProps(baseConfig, bridge, { addFirst, uuid })
@@ -575,6 +576,13 @@ const addWord = (config, uuid) => ({ word, id, initial }) => {
575
576
 
576
577
  const normalizeConfig = (config) => {
577
578
  if (config) {
579
+ if (!config.objects) {
580
+ config.objects = {
581
+ namespaced: {},
582
+ server: {},
583
+ }
584
+ }
585
+
578
586
  for (const bag of bags) {
579
587
  if (config[bag]) {
580
588
  config[bag] = config[bag].map(normalizeGenerator)
@@ -844,14 +852,6 @@ const multiApiImpl = (initializer) => {
844
852
  }
845
853
  },
846
854
 
847
- /*
848
- set objects (value) {
849
- for (const key in Object.keys(this.apis)) {
850
- this.apis[key].objects = value
851
- }
852
- },
853
- */
854
-
855
855
  // "product1": apiInstance(testData1),
856
856
  apis: {
857
857
  },
@@ -869,6 +869,15 @@ class Config {
869
869
  return config_toServer(config)
870
870
  }
871
871
 
872
+ async fixtures () {
873
+ if (this.testConfig?.fixtures) {
874
+ const args = {}
875
+ args.uuid = this._uuid
876
+ configHelpers.setupArgs(args, this)
877
+ return this.testConfig.fixtures(args)
878
+ }
879
+ }
880
+
872
881
  getInfo () {
873
882
  const name = this.name
874
883
  const includes = this.configs.slice(1).map((km) => km.config.name)
@@ -892,7 +901,7 @@ class Config {
892
901
 
893
902
  getPseudoConfig (uuid, config) {
894
903
  return {
895
- description: 'this is a pseudo config that has limited functionality due to being available in the initializer function context',
904
+ description: 'this is a pseudo config that has limited functionality due to being available in the initializer and fixtures function context',
896
905
  addAssociation: (...args) => this.addAssociation(...args),
897
906
  addAssociations: (...args) => this.addAssociations(...args),
898
907
  addBridge: (...args) => this.addBridge(...args, uuid),
@@ -960,7 +969,8 @@ class Config {
960
969
  },
961
970
  objects: {
962
971
  // this is where the namespaced configs have their objects
963
- namespaced: {}
972
+ namespaced: {},
973
+ server: {},
964
974
  },
965
975
  description: '',
966
976
  words: {
@@ -1324,6 +1334,8 @@ class Config {
1324
1334
 
1325
1335
  toData (data) {
1326
1336
  Object.assign(data, this.config)
1337
+ // greg99 delete data.objects
1338
+ data.objects = data.objects.server
1327
1339
  config_toServer(data)
1328
1340
  }
1329
1341
 
@@ -1363,12 +1375,22 @@ class Config {
1363
1375
  this.instances.push(instance)
1364
1376
  await configHelpers.loadInstance(this, instance)
1365
1377
  }
1378
+ this.expect_template = false
1366
1379
  }
1367
1380
  }
1368
1381
 
1382
+ watchNewFragments (list) {
1383
+ this.addFragmentWatcher = list
1384
+ }
1385
+
1369
1386
  addFragments (fragments) {
1370
1387
  // only run this if not loading as module write error if loading as module and different
1371
1388
  this.dynamicFragments = this.dynamicFragments.concat(fragments)
1389
+ if (this.addFragmentWatcher) {
1390
+ for (const fragment of fragments) {
1391
+ this.addFragmentWatcher.push(fragment)
1392
+ }
1393
+ }
1372
1394
  }
1373
1395
 
1374
1396
  objects () {
@@ -1755,6 +1777,9 @@ class Config {
1755
1777
  if (!config.objects) {
1756
1778
  config.objects = {
1757
1779
  namespaced: {
1780
+ },
1781
+ // sent to server
1782
+ server: {
1758
1783
  }
1759
1784
  }
1760
1785
  }
@@ -1908,11 +1933,15 @@ class Config {
1908
1933
  }
1909
1934
 
1910
1935
  // configs = [ { config, namespace } ... ]
1911
- constructor (config, module, clientProcess) {
1936
+ constructor (config, module, clientProcess, apiKMs) {
1912
1937
  if (config instanceof Config) {
1913
1938
  throw new Error('Excepted the config argument to be a hash not a Config object')
1914
1939
  }
1915
1940
 
1941
+ if (!apiKMs) {
1942
+ apiKMs = []
1943
+ }
1944
+
1916
1945
  if (config) {
1917
1946
  validConfigProps(config)
1918
1947
 
@@ -1926,6 +1955,8 @@ class Config {
1926
1955
  config.priorities = config.priorities || []
1927
1956
  }
1928
1957
 
1958
+ this._apiKMs = apiKMs
1959
+
1929
1960
  this.clientProcess = clientProcess
1930
1961
  this.maxDepth = 20 // for generators and semantics
1931
1962
  this.debugLoops = false // for generators and semantics
@@ -2072,7 +2103,28 @@ class Config {
2072
2103
  this.resetDelta(cacheKey)
2073
2104
  }
2074
2105
 
2106
+ // use this to set the api if you only want to partially override the KM api
2107
+ apiBase (name) {
2108
+ if (this._api && this._api.multiApi) {
2109
+ throw new Error('This is intended to be used to instantiate a new class based on the existing API.')
2110
+ } else {
2111
+ if (name) {
2112
+ if (this.name == name) {
2113
+ return this._api.constructor
2114
+ } else {
2115
+ return this.getConfig(name)._api.constructor
2116
+ }
2117
+ } else {
2118
+ return this._api.constructor
2119
+ }
2120
+ }
2121
+ }
2122
+
2075
2123
  get api () {
2124
+ if (this._stop_auto_rebuild) {
2125
+ throw new Error('The API cannot be accessed until the auto rebuild is restarted')
2126
+ }
2127
+
2076
2128
  if (this._api && this._api.multiApi) {
2077
2129
  return this._api.api(this._api)
2078
2130
  } else {
@@ -2094,13 +2146,26 @@ class Config {
2094
2146
  }
2095
2147
  }
2096
2148
 
2149
+ // constructors is a constructor
2097
2150
  async setApi (constructor) {
2098
2151
  if (typeof constructor !== 'function') {
2099
2152
  throw new Error(`Expected the argument to be an API constructor for ${this.name}.`)
2100
2153
  }
2101
2154
  const value = constructor()
2102
- if (!value.initialize) {
2103
- throw new Error(`Expected the API to have an initialize function for ${this.name}.`)
2155
+ if (this._apiKMs.length > 0) {
2156
+ for (const name of this._apiKMs) {
2157
+ const api = value[name]
2158
+ if (!api) {
2159
+ throw new Error(`The API for ${this.name} is not being provided by the API constructor.`)
2160
+ }
2161
+ if (!api.initialize) {
2162
+ throw new Error(`Expected the API for ${this.name} to have an initialize function.`)
2163
+ }
2164
+ }
2165
+ } else {
2166
+ if (!value.initialize) {
2167
+ throw new Error(`Expected the API to have an initialize function for ${this.name}.`)
2168
+ }
2104
2169
  }
2105
2170
 
2106
2171
  if (this._api && this._api.multiApi) {
@@ -2113,8 +2178,14 @@ class Config {
2113
2178
  return api
2114
2179
  }
2115
2180
  } else {
2116
- this._api = value
2117
2181
  this._apiConstructor = constructor
2182
+ if (this._apiKMs.length > 0) {
2183
+ for (const name of this._apiKMs) {
2184
+ this.km(name)._api = value[name]
2185
+ }
2186
+ } else {
2187
+ this._api = value
2188
+ }
2118
2189
  await this.rebuild()
2119
2190
  }
2120
2191
  }
@@ -2182,10 +2253,21 @@ class Config {
2182
2253
  // update uuid here set the uuid in the objects and add error checking
2183
2254
  cp.initializerFn = this.initializerFn
2184
2255
  cp.terminatorFn = this.terminatorFn
2185
- // cp._api = _.cloneDeep(this._api)
2186
- if (this._apiConstructor) {
2187
- cp._api = this._apiConstructor(cp)
2188
- cp._apiConstructor = this._apiConstructor
2256
+ cp._apiKMs = this._apiKMs
2257
+ cp._apiConstructor = this._apiConstructor
2258
+ if (cp._apiConstructor) {
2259
+ if (this._apiKMs.length > 0) {
2260
+ const apis = cp._apiConstructor(cp)
2261
+ for (const name of this._apiKMs) {
2262
+ if (name == this.name) {
2263
+ cp._api = apis[name]
2264
+ } else {
2265
+ cp.km(name)._api = apis[name]
2266
+ }
2267
+ }
2268
+ } else {
2269
+ cp._api = cp._apiConstructor(cp)
2270
+ }
2189
2271
  }
2190
2272
  cp._namespace = this._namespace
2191
2273
  cp._eqClasses = this._eqClasses
@@ -2217,7 +2299,10 @@ class Config {
2217
2299
  await cp.rebuild(options) // in copy
2218
2300
  } else {
2219
2301
  if (!cp.config.objects) {
2220
- cp.config.objects = { namespaced: {} }
2302
+ cp.config.objects = {
2303
+ namespaced: {},
2304
+ server: {},
2305
+ }
2221
2306
  } else if (!cp.config.objects.namespaced) {
2222
2307
  cp.config.objects.namespaced = {}
2223
2308
  }
@@ -2565,7 +2650,9 @@ class Config {
2565
2650
  const initAfterApis = []
2566
2651
  this.configs.forEach((km) => {
2567
2652
  const namespace = km.namespace
2568
- this.config.objects.namespaced[km._uuid] = {}
2653
+ this.config.objects.namespaced[km._uuid] = {
2654
+ km: km._uuid
2655
+ }
2569
2656
  const namespacedObjects = this.config.objects.namespaced[km._uuid]
2570
2657
  this.setupNamespace(km)
2571
2658
  // const aw = (word, def) => this.addWord(word, def)
@@ -2603,6 +2690,7 @@ class Config {
2603
2690
  currentConfig: config,
2604
2691
  uuid: config._uuid,
2605
2692
  objects: namespacedObjects,
2693
+ globals: this.config.objects,
2606
2694
  namespace,
2607
2695
  api: config.api
2608
2696
  }))
@@ -2697,6 +2785,13 @@ class Config {
2697
2785
  }
2698
2786
 
2699
2787
  this.hierarchy.edges = this.config.hierarchy
2788
+
2789
+ if (!this.isModule) {
2790
+ if (this.template || !this.expect_template) {
2791
+ await this.fixtures()
2792
+ }
2793
+ }
2794
+
2700
2795
  this.valid()
2701
2796
  this.checks()
2702
2797
  }
@@ -3300,8 +3395,12 @@ class Config {
3300
3395
  if (!skipObjects) {
3301
3396
  // namespaced is special
3302
3397
  const namespaced = this.config.objects.namespaced
3398
+ const server = this.config.objects.server
3303
3399
  Object.assign(this.config[key], more[key])
3304
3400
  this.config.objects.namespaced = namespaced
3401
+ for (let skey in server) {
3402
+ this.config.objects.server[skey] = server[skey]
3403
+ }
3305
3404
  }
3306
3405
  } else if (key === 'associations') {
3307
3406
  const configAssociations = this.config.associations
@@ -81,6 +81,16 @@ const cleanAssign = (dest, ...srcs) => {
81
81
  }
82
82
 
83
83
  const setupArgs = (args, config, logs, hierarchy, uuidForScoping) => {
84
+ if (!args.objects) {
85
+ args.objects = config.get('objects')
86
+ args.getObjects = getObjects(args.objects)
87
+ }
88
+ if (args.uuid) {
89
+ args.objects = args.getObjects(args.uuid)
90
+ }
91
+ if (!hierarchy) {
92
+ hierarchy = config.hierarchy
93
+ }
84
94
  // callId
85
95
  args.calls = new InitCalls(args.isInstance ? `${args.isInstance}#${config.name}` : config.name)
86
96
  if (global.theprogrammablemind && global.theprogrammablemind.loadForTesting) {
@@ -126,6 +136,9 @@ const setupArgs = (args, config, logs, hierarchy, uuidForScoping) => {
126
136
  return config.getGenerators(logs).apply(addAssumed(args, a, { paraphrase: false, isResponse: true }), { ...c, paraphrase: false, isResponse: true })
127
137
  }
128
138
  args.e = (c) => {
139
+ if (!c) {
140
+ return
141
+ }
129
142
  return config.getEvaluator(args.s, args.calls, logs, c)
130
143
  }
131
144
  args.gs = gs(args.g)
@@ -154,6 +167,7 @@ const setupArgs = (args, config, logs, hierarchy, uuidForScoping) => {
154
167
  config.getAddedArgs(args)
155
168
 
156
169
  Object.assign(args, args.getUUIDScoped(uuidForScoping || config.uuid))
170
+ args.apis = args.apis || ((name) => config.getConfig(name).api)
157
171
  /*
158
172
  if (uuidForScoping) {
159
173
  Object.assign(args, args.getUUIDScoped(uuidForScoping))
@@ -241,15 +255,17 @@ const setupContexts = (rawContexts) => {
241
255
  let first = true
242
256
  const contexts = []
243
257
  contexts.push({ marker: 'controlStart', controlRemove: true })
258
+ let previous
244
259
  for (const context of rawContexts) {
245
260
  if (first) {
246
261
  first = false
247
262
  } else {
248
- contexts.push({ marker: 'controlBetween', controlRemove: true })
263
+ contexts.push({ marker: 'controlBetween', controlRemove: true, previous })
249
264
  }
250
265
  contexts.push(context)
266
+ previous = context
251
267
  }
252
- contexts.push({ marker: 'controlEnd', controlRemove: true })
268
+ contexts.push({ marker: 'controlEnd', controlRemove: true, previous })
253
269
 
254
270
  let _index = 0
255
271
  const id = (context) => {
@@ -280,11 +296,14 @@ const processContextsB = async ({ config, hierarchy, semantics, generators, json
280
296
  args.insert = (context) => toDo.unshift(context)
281
297
  let overlap, lastRange
282
298
  config.debugLoops = commandLineArgs && commandLineArgs.debugLoops
299
+ let context_id_counter = 0
283
300
  while (toDo.length > 0) {
284
301
  const context = toDo.shift()
285
302
  args.calls.next()
286
303
  let contextPrime = context
287
304
  context.topLevel = true
305
+ context_id_counter += 1
306
+ context.context_id = context_id_counter
288
307
  try {
289
308
  if (json.has_errors) {
290
309
  throw new Error('There are errors in the logs. Run with the -d flag and grep for Error')
@@ -324,9 +343,9 @@ const processContextsB = async ({ config, hierarchy, semantics, generators, json
324
343
  if (contextPrime.controlRemove) {
325
344
  continue
326
345
  }
327
- let paraphrases = []
328
- let paraphrasesParenthesized = []
329
- let generatedParenthesized = []
346
+ const paraphrases = []
347
+ const paraphrasesParenthesized = []
348
+ const generatedParenthesized = []
330
349
  if (forTemplate) {
331
350
  // noop
332
351
  } else {
package/src/debug.js ADDED
@@ -0,0 +1,78 @@
1
+ const counters = {}
2
+ const hits = {}
3
+
4
+ let db = () => {
5
+ debugger // eslint-disable-line no-debugger
6
+ }
7
+
8
+ const reset = () => {
9
+ Object.keys(counters).forEach(key => delete counters[key])
10
+ Object.keys(hits).forEach(key => delete hits[key])
11
+ db = () => { debugger } // eslint-disable-line no-debugger
12
+ }
13
+
14
+ const getDb = () => {
15
+ return db
16
+ }
17
+
18
+ const setDb = (value) => {
19
+ db = value
20
+ }
21
+
22
+ const hit = (name) => {
23
+ hits[name] = true
24
+ }
25
+
26
+ const unhit = (name) => {
27
+ hits[name] = false
28
+ }
29
+
30
+ const wasHit = (name) => {
31
+ return hits[name]
32
+ }
33
+
34
+ const counter = (name, breakAt = [], debugBreak = true) => {
35
+ if (!counters[name]) {
36
+ counters[name] = 0
37
+ }
38
+ counters[name] += 1
39
+ console.log(`counters[${name}] = ${counters[name]}`)
40
+ unhit(name)
41
+ if (Array.isArray(breakAt) && breakAt.includes(counters[name])) {
42
+ if (debugBreak) {
43
+ db()
44
+ }
45
+ hit(name)
46
+ return true
47
+ } else if (breakAt == counters[name]) {
48
+ if (debugBreak) {
49
+ db()
50
+ }
51
+ hit(name)
52
+ return true
53
+ }
54
+ }
55
+
56
+ const get = (name) => {
57
+ return counters[name]
58
+ }
59
+
60
+ const _break = (name) => {
61
+ if (wasHit(name)) {
62
+ db()
63
+ }
64
+ }
65
+
66
+ module.exports = {
67
+ counter,
68
+ get,
69
+ _break, // break is a keyword
70
+
71
+ // used for tests
72
+ reset,
73
+ hit,
74
+ unhit,
75
+ wasHit,
76
+ getDb,
77
+ setDb
78
+ }
package/src/generators.js CHANGED
@@ -211,7 +211,7 @@ class Generators {
211
211
  lines.setElement(0, 2, generator.toString())
212
212
  lines.newRow()
213
213
  lines.setElement(0, 1, 'TO')
214
- lines.setElement(0, 2, `(HASHCODE ${helpers.hashCode(JSON.stringify(helpers.sortJson(context, { depth: 25 })))})`)
214
+ lines.setElement(0, 2, `context_id: ${context.context_id}`)
215
215
  lines.setElement(1, 2, JSON.stringify(helpers.sortJson(context, { depth: 25 }), null, 2))
216
216
  lines.newRow()
217
217
  lines.setElement(0, 1, 'STACK')
@@ -253,7 +253,7 @@ class Generators {
253
253
  lines.setElement(0, 2, `To debug this use args.callId == '${args.calls.current()}'`)
254
254
  lines.newRow()
255
255
  lines.setElement(0, 1, 'TO')
256
- lines.setElement(0, 2, `(HASHCODE ${helpers.hashCode(JSON.stringify(helpers.sortJson(context, { depth: 25 })))})`)
256
+ lines.setElement(0, 2, `context_id: ${context.context_id}`)
257
257
  lines.setElement(1, 2, JSON.stringify(helpers.sortJson(context, { depth: 25 }), null, 2))
258
258
  this.logs.push(lines.toString())
259
259
  }
package/src/helpers.js CHANGED
@@ -310,7 +310,7 @@ const validProps = (valids, object, type) => {
310
310
  }
311
311
  }
312
312
  if (!okay) {
313
- throw new Error(`Unknown property "${prop}" in the ${type}. Valid properties are ${valids}. The ${type} is ${JSON.stringify(object)}`)
313
+ throw new Error(`Unknown property "${prop}" in the ${type}. Valid properties are ${valids.join(', ')}. The ${type} is ${JSON.stringify(object)}`)
314
314
  }
315
315
  }
316
316
  }
package/src/semantics.js CHANGED
@@ -183,7 +183,16 @@ class Semantics {
183
183
  deferWasCalled = true
184
184
  }
185
185
  args.defer = defer
186
+
187
+ let continueWasCalled = false
188
+ const _continue = () => {
189
+ continueWasCalled = true
190
+ }
191
+ args._continue = _continue
186
192
  contextPrime = await semantic.apply(args, context, s, options)
193
+ if (continueWasCalled) {
194
+ continue
195
+ }
187
196
  if (deferWasCalled) {
188
197
  continue
189
198
  }
@@ -218,7 +227,7 @@ class Semantics {
218
227
  lines.setElement(0, 2, semantic.toString())
219
228
  lines.newRow()
220
229
  lines.setElement(0, 1, 'TO')
221
- lines.setElement(0, 2, `(HASHCODE ${helpers.hashCode(JSON.stringify(helpers.sortJson(context, { depth: 25 })))})`)
230
+ lines.setElement(0, 2, `context_id: ${context.context_id}`)
222
231
  lines.setElement(1, 2, JSON.stringify(helpers.sortJson(context, { depth: 25 }), null, 2))
223
232
  lines.newRow()
224
233
  lines.setElement(0, 1, 'STACK')
@@ -253,7 +262,7 @@ class Semantics {
253
262
  lines.setElement(0, 2, semantic.toString())
254
263
  lines.newRow()
255
264
  lines.setElement(0, 1, 'TO')
256
- lines.setElement(0, 2, `(HASHCODE ${helpers.hashCode(JSON.stringify(helpers.sortJson(context, { depth: 25 })))})`)
265
+ lines.setElement(0, 2, `context_id: ${context.context_id}`)
257
266
  lines.setElement(1, 2, JSON.stringify(helpers.sortJson(context, { depth: 25 }), null, 2))
258
267
  lines.newRow()
259
268
  lines.setElement(0, 1, 'STACK')
@@ -263,7 +272,7 @@ class Semantics {
263
272
  lines.setElement(0, 2, `To debug this use args.callId == '${args.calls.current()}'`)
264
273
  lines.newRow()
265
274
  lines.setElement(0, 1, 'RESULT')
266
- lines.setElement(0, 2, `(HASHCODE ${helpers.hashCode(JSON.stringify(helpers.sortJson(contextPrime, { depth: 25 })))})`)
275
+ lines.setElement(0, 2, `context_id: ${context.context_id}`)
267
276
  lines.setElement(1, 2, JSON.stringify(contextPrime, null, 2))
268
277
  for (const { semantic } of deferred) {
269
278
  lines.setElement(0, 1, 'DEFERRED')
@@ -295,7 +304,7 @@ class Semantics {
295
304
  lines.setElement(0, 2, stack)
296
305
  lines.newRow()
297
306
  lines.setElement(0, 1, 'TO')
298
- lines.setElement(0, 2, `(HASHCODE ${helpers.hashCode(JSON.stringify(helpers.sortJson(context, { depth: 25 })))})`)
307
+ lines.setElement(0, 2, `context_id: ${context.context_id}`)
299
308
  lines.setElement(1, 2, JSON.stringify(helpers.sortJson(context, { depth: 25 }), null, 2))
300
309
  this.logs.push(lines.toString())
301
310
  }