theprogrammablemind_4wp 9.5.1-beta.1 → 9.5.1-beta.10

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
@@ -316,6 +316,7 @@ const _process = async (config, query, { initializer, commandLineArgs, credentia
316
316
  }
317
317
 
318
318
  let startCounter = 0
319
+ let contextIdCounter = 0
319
320
  while (true) {
320
321
  if (queries.length === 0) {
321
322
  break
@@ -356,8 +357,9 @@ const _process = async (config, query, { initializer, commandLineArgs, credentia
356
357
  }
357
358
  const summary = { summaries: json.summaries, length: json.contexts.length }
358
359
  summaries.push(summary)
359
- const { contextsPrime, generatedPrime, paraphrasesPrime, paraphrasesParenthesizedPrime, generatedParenthesizedPrime, responsesPrime } =
360
- await processContextsB({ isTest, isProcess, isModule, rebuildingTemplate, config, hierarchy, json, commandLineArgs /*, generators, semantics */ })
360
+ const { updatedContextIdCounter, contextsPrime, generatedPrime, paraphrasesPrime, paraphrasesParenthesizedPrime, generatedParenthesizedPrime, responsesPrime } =
361
+ await processContextsB({ contextIdCounter, isTest, isProcess, isModule, rebuildingTemplate, config, hierarchy, json, commandLineArgs /*, generators, semantics */ })
362
+ contextIdCounter = updatedContextIdCounter
361
363
  if (isTest) {
362
364
  const end = runtime.performance.performance.now()
363
365
  clientSideTime = end - start
@@ -475,6 +477,7 @@ const runTest = async (config, expected, { args, verbose, testConfig, debug, tim
475
477
  return
476
478
  }
477
479
  // initialize in between test so state is not preserved since the test was adding without state
480
+ config.testConfig.testModuleName = testConfig.testModuleName
478
481
  await config.rebuild()
479
482
  const errorHandler = (error) => {
480
483
  if (error.metadata) {
package/lines.js CHANGED
@@ -5,6 +5,13 @@ class Lines {
5
5
  this.rows = []
6
6
  }
7
7
 
8
+ static SCREEN_WIDTH = 132
9
+
10
+ static addRemainder(widths) {
11
+ const sum = widths.reduce((a, b) => a + b)
12
+ return [...widths, Lines.SCREEN_WIDTH - sum]
13
+ }
14
+
8
15
  addLine () {
9
16
  this.lines.push(this.widths.map((width) => ''.padEnd(width)))
10
17
  }
package/package.json CHANGED
@@ -3,14 +3,14 @@
3
3
  "@eslint/js": "^9.21.0",
4
4
  "@typescript-eslint/eslint-plugin": "^4.28.4",
5
5
  "@typescript-eslint/parser": "^4.28.4",
6
+ "argparse": "^2.0.1",
6
7
  "eslint": "^7.32.0",
7
8
  "eslint-config-standard": "^16.0.3",
8
9
  "eslint-plugin-import": "^2.23.4",
9
10
  "eslint-plugin-node": "^11.1.0",
10
11
  "eslint-plugin-promise": "^5.1.0",
11
12
  "globals": "^16.0.0",
12
- "jest": "^29.7.0",
13
- "argparse": "^2.0.1"
13
+ "jest": "^30.2.0"
14
14
  },
15
15
  "scripts": {
16
16
  "to:debug": "node inspect node_modules/.bin/jest --runInBand -t NEO23",
@@ -45,6 +45,7 @@
45
45
  "runtime.js",
46
46
  "src/helpers.js",
47
47
  "src/flatten.js",
48
+ "src/fragments.js",
48
49
  "src/unflatten.js",
49
50
  "src/config.js",
50
51
  "src/configHelpers.js",
@@ -61,6 +62,7 @@
61
62
  "dependencies": {
62
63
  "base-64": "^1.0.0",
63
64
  "deep-equal": "^2.0.4",
65
+ "flatted": "^3.3.3",
64
66
  "fs": "0.0.1-security",
65
67
  "json-diff": "^1.0.3",
66
68
  "json-stable-stringify": "^1.0.1",
@@ -71,6 +73,6 @@
71
73
  "sort-json": "^2.0.0",
72
74
  "uuid": "^8.3.2"
73
75
  },
74
- "version": "9.5.1-beta.1",
76
+ "version": "9.5.1-beta.10",
75
77
  "license": "UNLICENSED"
76
78
  }
package/src/config.js CHANGED
@@ -10,6 +10,7 @@ const { ecatch } = require('./helpers')
10
10
  const runtime = require('../runtime')
11
11
  const _ = require('lodash')
12
12
  const db = require('./debug')
13
+ const { fragmentInstantiator } = require('./fragments')
13
14
 
14
15
  const debugBreak = () => {
15
16
  // debugger
@@ -289,11 +290,9 @@ const priority_valid = (cp) => {
289
290
  const handleBridgeProps = (config, bridge, { addFirst, uuid } = {}) => {
290
291
  ecatch(`While processing the bridge for ${bridge.id}#${bridge.level}`,
291
292
  () => {
292
- /*
293
- if (bridge.development && config.isModule) {
293
+ if (bridge.scope && config.isModule) {
294
294
  return
295
295
  }
296
- */
297
296
  if (false && !bridge.bridge) {
298
297
  bridge.bridge = '{ ...next(operator) }'
299
298
  }
@@ -1109,54 +1108,21 @@ class Config {
1109
1108
  return instance
1110
1109
  }
1111
1110
 
1112
- fragmentInstantiator (args, contexts) {
1113
- return new Object({
1114
- contexts: () => contexts,
1115
- instantiate: async (mappings) => {
1116
- const instantiated = _.cloneDeep(contexts)
1117
- // const todo = [...instantiated]
1118
- // const todo = [...instantiated]
1119
- const todo = _.clone(instantiated)
1120
- args = { ...args }
1121
- while (todo.length > 0) {
1122
- const context = todo.pop()
1123
- args.context = context
1124
- for (const mapping of mappings) {
1125
- if (await mapping.match(args)) {
1126
- await mapping.apply(args)
1127
- }
1128
- }
1129
- for (const key of Object.keys(context)) {
1130
- // if (['number', 'string', 'boolean'].includes(typeof (context[key]))) {
1131
- if (!helpers.isCompound(context[key])) {
1132
- continue
1133
- }
1134
- if (context[key].instantiated) {
1135
- continue
1136
- }
1137
- todo.push(context[key])
1138
- }
1139
- }
1140
- return instantiated
1141
- }
1142
- })
1143
- }
1144
-
1145
1111
  fragment (args, query) {
1146
1112
  for (const instance of (this.instances || [])) {
1147
1113
  for (const fragment of (instance.fragments || [])) {
1148
1114
  if (fragment.query === query) {
1149
- return this.fragmentInstantiator(args, fragment.contexts)
1115
+ return fragmentInstantiator(args, fragment.contexts)
1150
1116
  }
1151
1117
  }
1152
1118
  for (const fragment of (instance.resultss || [])) {
1153
1119
  if (fragment.isFragment && fragment.query === query) {
1154
- return this.fragmentInstantiator(args, fragment.contexts)
1120
+ return fragmentInstantiator(args, fragment.contexts)
1155
1121
  }
1156
1122
  }
1157
1123
  for (const fragment of (this.fragmentsBeingBuilt || [])) {
1158
1124
  if (fragment.query === query) {
1159
- return this.fragmentInstantiator(args, fragment.contexts)
1125
+ return fragmentInstantiator(args, fragment.contexts)
1160
1126
  }
1161
1127
  }
1162
1128
  }
@@ -1913,12 +1879,15 @@ class Config {
1913
1879
  } else if (this.scope == 'development') {
1914
1880
  new_result = !(element.scope === 'testing')
1915
1881
  }
1882
+ /*
1916
1883
  if (global.GORDO && old_result !== new_result) {
1917
1884
  global.GORDO = false
1918
1885
  console.log("THERE WAS A DIFFERENCE ------------------------------------------------")
1919
1886
  debugger // greg23old
1920
1887
  }
1921
- return old_result
1888
+ */
1889
+ // return old_result
1890
+ return new_result
1922
1891
  }
1923
1892
 
1924
1893
  config.operators = config.operators.filter((element) => keep(element))
@@ -133,6 +133,9 @@ const setupArgs = (args, config, logs, hierarchy, uuidForScoping) => {
133
133
  args.addPattern = (pattern, def) => config.addPattern(pattern, args.uuid)
134
134
  args.addGenerator = (generator) => config.addGenerator(generator, args.uuid, config.name)
135
135
 
136
+ if (config.testConfig?.testModuleName) {
137
+ args.testModuleName = config.testConfig.testModuleName
138
+ }
136
139
  args.addAssumedScoped = (args, assumed) => {
137
140
  const addAssumed = (args, ...moreAssumed) => {
138
141
  return { ...args, assumed: Object.assign({}, assumed, (args.assumed || {}), ...moreAssumed) }
@@ -291,7 +294,7 @@ const setupContexts = (rawContexts) => {
291
294
  return contexts
292
295
  }
293
296
 
294
- const processContextsB = async ({ config, hierarchy, semantics, generators, json, isTest, isProcess, isModule, rebuildingTemplate, isInstance, instance, query, data, retries, url, commandLineArgs, forTemplate }) => {
297
+ const processContextsB = async ({ config, hierarchy, semantics, generators, json, isTest, isProcess, isModule, rebuildingTemplate, isInstance, instance, query, data, retries, url, commandLineArgs, forTemplate, contextIdCounter }) => {
295
298
  // TODO fix this name to contextsPrime
296
299
  const contextsPrime = []
297
300
  const generatedPrime = []
@@ -311,14 +314,13 @@ const processContextsB = async ({ config, hierarchy, semantics, generators, json
311
314
  args.insert = (context) => toDo.unshift(context)
312
315
  let overlap, lastRange
313
316
  config.debugLoops = commandLineArgs && commandLineArgs.debugLoops
314
- let context_id_counter = 0
315
317
  while (toDo.length > 0) {
316
318
  const context = toDo.shift()
317
319
  args.calls.next()
318
320
  let contextPrime = context
319
321
  context.topLevel = true
320
- context_id_counter += 1
321
- context.context_id = context_id_counter
322
+ contextIdCounter += 1
323
+ context.context_id = contextIdCounter
322
324
  try {
323
325
  if (json.has_errors) {
324
326
  throw new Error('There are errors in the logs. Run with the -d flag and grep for Error')
@@ -328,6 +330,9 @@ const processContextsB = async ({ config, hierarchy, semantics, generators, json
328
330
  const semantics = config.getSemantics(json.logs)
329
331
  try {
330
332
  contextPrime = await semantics.apply(args, context)
333
+ // contextPrime.greg = 'yes'
334
+ // console.log("context_id", context.context_id)
335
+ // console.log("semantics.apply", JSON.stringify(contextPrime, null, 2))
331
336
  } catch (e) {
332
337
  if (e.message == 'Maximum call stack size exceeded') {
333
338
  const mostCalled = semantics.getMostCalled()
@@ -421,7 +426,7 @@ const processContextsB = async ({ config, hierarchy, semantics, generators, json
421
426
  throw e
422
427
  }
423
428
  }
424
- return { contextsPrime, generatedPrime, paraphrasesPrime, paraphrasesParenthesizedPrime, generatedParenthesizedPrime, responsesPrime }
429
+ return { contextsPrime, generatedPrime, paraphrasesPrime, paraphrasesParenthesizedPrime, generatedParenthesizedPrime, responsesPrime, updatedContextIdCounter: contextIdCounter }
425
430
  }
426
431
 
427
432
  // instance template loadTemplate
@@ -479,6 +484,9 @@ const loadInstance = async (config, instance) => {
479
484
  args.isModule = true
480
485
  args.isProcess = false
481
486
  }
487
+ if (instance.name == config.testConfig.testModuleName) {
488
+ args.isTesting = true
489
+ }
482
490
  await results.apply(args)
483
491
  } else if (results.isFragment) {
484
492
  } else {
@@ -490,6 +498,9 @@ const loadInstance = async (config, instance) => {
490
498
  args.instance = ''
491
499
  args.isProcess = !config.isModule
492
500
  args.isModule = !!config.isModule
501
+ if (instance.name == config.testConfig.testModuleName) {
502
+ args.isTesting = true
503
+ }
493
504
  await processContextsB(args)
494
505
  if (results.skipSemantics) {
495
506
  config.config.skipSemantics = null
@@ -0,0 +1,77 @@
1
+ const _ = require('lodash')
2
+ const helpers = require('./helpers')
3
+
4
+ function fragmentInstantiator (args, contexts) {
5
+ return new Object({
6
+ contexts: () => contexts,
7
+ instantiate: async (mappings) => {
8
+ const instantiated = _.cloneDeep(contexts)
9
+ const todo = [{ context: instantiated, path: [] }]
10
+ args = { ...args }
11
+ while (todo.length > 0) {
12
+ const { context, path } = todo.pop()
13
+ args.context = context
14
+ args.path = path
15
+ for (const mapping of mappings) {
16
+ if (await mapping.match(args)) {
17
+ await mapping.apply(args)
18
+ }
19
+ }
20
+ for (const key of Object.keys(context)) {
21
+ // if (['number', 'string', 'boolean'].includes(typeof (context[key]))) {
22
+ if (!helpers.isCompound(context[key])) {
23
+ continue
24
+ }
25
+ if (context[key].instantiated) {
26
+ continue
27
+ }
28
+ todo.push({ context: context[key], path: [...path, key] })
29
+ }
30
+ }
31
+ return instantiated
32
+ }
33
+ })
34
+ }
35
+
36
+ async function fragmentMapperInstantiator(values, modelFrom, modelTo) {
37
+ const paths = {}
38
+ for (const value of values) {
39
+ paths[value] = { value }
40
+ }
41
+
42
+ {
43
+ const fi = fragmentInstantiator({paths}, modelFrom)
44
+ await fi.instantiate([
45
+ {
46
+ match: ({context, path}) => values.includes(context.value),
47
+ apply: ({context, path}) => paths[context.value].from = path
48
+ },
49
+ ])
50
+ }
51
+
52
+ {
53
+ const fi = fragmentInstantiator({paths}, modelTo)
54
+ await fi.instantiate([
55
+ {
56
+ match: ({context, path}) => values.includes(context.value),
57
+ apply: ({context, path}) => paths[context.value].to = path
58
+ },
59
+ ])
60
+ }
61
+ return {
62
+ instantiate: (actualFrom) => {
63
+ const actualTo = structuredClone(modelTo)
64
+ for (const value in paths) {
65
+ const { from, to } = paths[value]
66
+ const actualValue = helpers.getByPath(actualFrom, from, null)
67
+ helpers.setByPath(actualTo, to, actualValue)
68
+ }
69
+ return actualTo
70
+ }
71
+ }
72
+ }
73
+
74
+ module.exports = {
75
+ fragmentInstantiator,
76
+ fragmentMapperInstantiator,
77
+ }
package/src/generators.js CHANGED
@@ -1,3 +1,4 @@
1
+ const { stringify } = require('flatted');
1
2
  const { args: contextArgs, normalizeGenerator } = require('./helpers')
2
3
  const Lines = require('../lines')
3
4
  const helpers = require('./helpers')
@@ -182,7 +183,7 @@ class Generators {
182
183
  const generator = this.generators[igenerator]
183
184
  if (await generator.matches(args, objects, context, hierarchy, config, options)) {
184
185
  const log = (message) => { this.logs.push(message) }
185
- // this.logs.push(`Generators: applied ${generator.toString()}\n to\n ${JSON.stringify(context)}`)
186
+ // this.logs.push(`Generators: applied ${generator.toString()}\n to\n ${stringify(context)}`)
186
187
  let errorMessage = 'The apply function did not return a value'
187
188
  try {
188
189
  generated = await generator.apply(args, objects, context, hierarchy, config, response, log)
@@ -202,7 +203,7 @@ class Generators {
202
203
  }
203
204
  }
204
205
  if (!generated && generated !== '') {
205
- const widths = [10, 10, 90]
206
+ const widths = Lines.addRemainder([10, 10])
206
207
  const lines = new Lines(widths)
207
208
  lines.setElement(0, 0, 'Generator')
208
209
  const source = `${generator.km}/#${generator.index}`
@@ -212,7 +213,7 @@ class Generators {
212
213
  lines.newRow()
213
214
  lines.setElement(0, 1, 'TO')
214
215
  lines.setElement(0, 2, `context_id: ${context.context_id}`)
215
- lines.setElement(1, 2, JSON.stringify(helpers.sortJson(context, { depth: 25 }), null, 2))
216
+ lines.setElement(1, 2, stringify(helpers.sortJson(context, { depth: 10 }), null, 2))
216
217
  lines.newRow()
217
218
  lines.setElement(0, 1, 'STACK')
218
219
  lines.setElement(0, 2, stack)
@@ -223,14 +224,14 @@ class Generators {
223
224
  lines.setElement(0, 1, 'ERROR')
224
225
  lines.setElement(0, 2, errorMessage)
225
226
  this.logs.push(lines.toString())
226
- const message = `ERROR while applying (${source}) ${generator.toLabel()}\n to\n ${JSON.stringify(context, null, 2)}.\n${errorMessage}'`
227
+ const message = `ERROR while applying (${source}) ${generator.toLabel()}\n to\n ${stringify(context, null, 2)}.\n${errorMessage}'`
227
228
  // this.logs.push(message)
228
229
  // return [message]
229
230
  args.calls.pop()
230
231
  throw { error: [message], logs: this.logs }
231
232
  }
232
233
  if (((config || {}).config || {}).debug) {
233
- const widths = [10, 10, 90]
234
+ const widths = Lines.addRemainder([10, 10])
234
235
  const lines = new Lines(widths)
235
236
  lines.setElement(0, 0, 'Generator')
236
237
  if (generator.index > -1 && generator.km) {
@@ -254,7 +255,7 @@ class Generators {
254
255
  lines.newRow()
255
256
  lines.setElement(0, 1, 'TO')
256
257
  lines.setElement(0, 2, `context_id: ${context.context_id}`)
257
- lines.setElement(1, 2, JSON.stringify(helpers.sortJson(context, { depth: 25 }), null, 2))
258
+ lines.setElement(1, 2, stringify(helpers.sortJson(context, { depth: 25 }), null, 2))
258
259
  this.logs.push(lines.toString())
259
260
  }
260
261
  applied = true
@@ -263,7 +264,7 @@ class Generators {
263
264
  }
264
265
  args.calls.pop()
265
266
  if (!applied && ((config || {}).config || {}).debug) {
266
- const widths = [10, 10, 90]
267
+ const widths = Lines.addRemainder([10, 10])
267
268
  const lines = new Lines(widths)
268
269
  lines.setElement(0, 0, 'Generator')
269
270
  lines.setElement(0, 2, 'No generator applied')
@@ -272,7 +273,7 @@ class Generators {
272
273
  lines.setElement(0, 2, stack)
273
274
  lines.newRow()
274
275
  lines.setElement(0, 1, 'TO')
275
- lines.setElement(0, 2, JSON.stringify(context, null, 2))
276
+ lines.setElement(0, 2, stringify(context, null, 2))
276
277
  this.logs.push(lines.toString())
277
278
  }
278
279
  return ((config || {}).parenthesized ? '(' + generated + ')' : generated)
package/src/helpers.js CHANGED
@@ -436,6 +436,63 @@ const stableId = (tag) => {
436
436
  return id
437
437
  }
438
438
 
439
+ function getByPath(obj, path, defaultValue) {
440
+ let current = obj;
441
+ for (const key of path) {
442
+ if (current === null || current === undefined) return defaultValue;
443
+ if (typeof current !== 'object') return defaultValue;
444
+ current = current[key];
445
+ }
446
+ return current === undefined ? defaultValue : current;
447
+ }
448
+
449
+ /**
450
+ * Set a value in an object by path array.
451
+ * Automatically creates missing objects {} or arrays [] as needed.
452
+ *
453
+ * @param {Object} obj - The root object to modify
454
+ * @param {Array<string|number>} path - Array of keys/indices
455
+ * @param {*} value - Value to set
456
+ * @returns {*} The set value (for chaining)
457
+ */
458
+ function setByPath(obj, path, value) {
459
+ if (!Array.isArray(path) || path.length === 0) {
460
+ throw new Error('Path must be a non-empty array');
461
+ }
462
+
463
+ let current = obj;
464
+
465
+ for (let i = 0; i < path.length; i++) {
466
+ const key = path[i];
467
+ const isLast = i === path.length - 1;
468
+
469
+ if (isLast) {
470
+ // Final step — just assign
471
+ current[key] = value;
472
+ } else {
473
+ // Not last — ensure next level exists
474
+ const nextKey = path[i + 1];
475
+
476
+ if (current[key] == null) {
477
+ // Auto-create: array if next key is number, otherwise object
478
+ current[key] = typeof nextKey === 'number' || String(nextKey >>> 0) === nextKey
479
+ ? []
480
+ : {};
481
+ } else if (Array.isArray(current[key]) && typeof nextKey !== 'number') {
482
+ // Safety: if current is array but next key isn't a valid index → convert to object
483
+ current[key] = { ...current[key] };
484
+ } else if (!Array.isArray(current[key]) && typeof nextKey === 'number') {
485
+ // If next expects array but current is object → convert
486
+ current[key] = Object.values(current[key]);
487
+ }
488
+
489
+ current = current[key];
490
+ }
491
+ }
492
+
493
+ return value;
494
+ }
495
+
439
496
  module.exports = {
440
497
  stableId,
441
498
  ecatch,
@@ -463,4 +520,6 @@ module.exports = {
463
520
  w,
464
521
  suggestAssociationsFix,
465
522
  suggestAssociationsFixFromSummaries,
523
+ getByPath,
524
+ setByPath,
466
525
  }
package/src/semantics.js CHANGED
@@ -218,7 +218,7 @@ class Semantics {
218
218
  errorMessage = e.toString()
219
219
  }
220
220
 
221
- const widths = [10, 10, 90]
221
+ const widths = Lines.addRemainder([10, 10])
222
222
  const lines = new Lines(widths)
223
223
  lines.setElement(0, 0, 'Semantic')
224
224
  const source = `${semantic.km}/#${semantic.index}`
@@ -248,7 +248,7 @@ class Semantics {
248
248
  args.calls.touch(contextPrime)
249
249
  // this.logs.push(`Semantics: applied ${semantic.toString()}\n to\n ${JSON.stringify(context)}\n the result was ${JSON.stringify(contextPrime)}\n`)
250
250
  if (((config || {}).config || {}).debug) {
251
- const widths = [10, 10, 132]
251
+ const widths = Lines.addRemainder([10, 10])
252
252
  const lines = new Lines(widths)
253
253
  lines.setElement(0, 0, 'Semantic')
254
254
  if (semantic.index > -1 && semantic.km) {
@@ -295,7 +295,7 @@ class Semantics {
295
295
  }
296
296
  args.calls.pop()
297
297
  if (!applied && ((config || {}).config || {}).debug) {
298
- const widths = [10, 10, 90]
298
+ const widths = Lines.addRemainder([10, 10])
299
299
  const lines = new Lines(widths)
300
300
  lines.setElement(0, 0, 'Semantic')
301
301
  lines.setElement(0, 2, 'No semantic applied')