theprogrammablemind 8.0.0-beta.6 → 8.0.0-beta.60

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
@@ -1,5 +1,7 @@
1
1
  const { Semantics, Semantic } = require('./src/semantics')
2
2
  const { Generators, Generator } = require('./src/generators')
3
+ const { Config } = require('./src/config')
4
+ const { loadInstance, ErrorReason, listable, setupArgs, gs, processContext, getObjects, setupProcessB, processContextsB } = require('./src/configHelpers')
3
5
  const DigraphInternal = require('./src/digraph_internal')
4
6
  const Digraph = require('./src/digraph')
5
7
  const { project } = require('./src/project')
@@ -10,36 +12,10 @@ const _ = require('lodash')
10
12
  const stringify = require('json-stable-stringify')
11
13
  const Lines = require('./lines')
12
14
  const flattens = require('./src/flatten')
13
- const { appendNoDups, InitCalls, updateQueries, safeNoDups, stableId } = require('./src/helpers')
15
+ const { appendNoDups, InitCalls, updateQueries, safeNoDups, stableId, where } = require('./src/helpers')
14
16
  const runtime = require('./runtime')
15
17
  const sortJson = runtime.sortJson
16
18
 
17
- function where (goUp = 2) {
18
- const e = new Error()
19
- const regexForm1 = /\((.*):(\d+):(\d+)\)$/
20
- const regexForm2 = /at (.*):(\d+):(\d+)$/
21
- const lines = e.stack.split('\n')
22
- let line
23
- let match
24
- for (line of lines.slice(1)) {
25
- // if (!(line.includes('config.js:') || line.includes('client.js:') || line.includes('<anonymous>'))) {
26
- if (!(line.includes('config.js:') || line.includes('client.js:'))) {
27
- match = regexForm1.exec(line) || regexForm2.exec(line)
28
- if (!match) {
29
- continue
30
- }
31
- break
32
- }
33
- }
34
- // const line = e.stack.split("\n")[goUp];
35
- // const match = regexForm1.exec(line) || regexForm2.exec(line)
36
- if (match) {
37
- return `${match[1]}:${match[2]}`
38
- } else {
39
- return 'running in browser'
40
- }
41
- }
42
-
43
19
  const getConfig_getObjectsCheck = (config, testConfig) => {
44
20
  let testConfigName = config.name
45
21
  if (testConfig.testModuleName) {
@@ -108,164 +84,6 @@ const vimdiff = (actualJSON, expectedJSON, title) => {
108
84
  }
109
85
  }
110
86
 
111
- const listable = (hierarchy) => (c, type) => {
112
- if (!c) {
113
- return false
114
- }
115
- if (hierarchy.isA(c.marker, type)) {
116
- return true
117
- }
118
- if (c.marker === 'list') {
119
- for (const t of c.types) {
120
- if (hierarchy.isA(t, type)) {
121
- return true
122
- }
123
- }
124
- }
125
- return false
126
- }
127
-
128
- const isA = (hierarchy) => (child, parent) => {
129
- if (!child || !parent) {
130
- return false
131
- }
132
- if (child.marker) {
133
- child = child.marker
134
- }
135
- if (parent.marker) {
136
- parent = parent.marker
137
- }
138
- return hierarchy.isA(child, parent)
139
- }
140
-
141
- const asList = (context) => {
142
- if (context.marker === 'list') {
143
- return context
144
- }
145
- return {
146
- marker: 'list',
147
- types: [context.marker],
148
- value: [context]
149
- }
150
- }
151
-
152
- class ErrorReason extends Error {
153
- constructor (context) {
154
- super(JSON.stringify(context))
155
- this.reason = context
156
- }
157
- }
158
-
159
- const setupArgs = (args, config, logs, hierarchy, uuidForScoping) => {
160
-
161
- // callId
162
- args.calls = new InitCalls(args.isInstance ? `${args.isInstance}#${config.name}` : config.name)
163
- if (global.theprogrammablemind && global.theprogrammablemind.loadForTesting) {
164
- args.calls = new InitCalls(Object.keys(global.theprogrammablemind.loadForTesting)[0])
165
- }
166
- args.km = (name) => config.getConfig(name)
167
- args.api = (name) => config.getConfig(name).api
168
- args.error = (context) => {
169
- throw new ErrorReason(context)
170
- }
171
- args.kms = config.getConfigs()
172
- args.config = config
173
- args.hierarchy = hierarchy
174
- args.isA = isA(hierarchy)
175
- args.listable = listable(hierarchy)
176
- args.asList = asList
177
- args.retry = () => { throw new RetryError() }
178
- args.fragments = (query) => config.fragment(query)
179
- args.breakOnSemantics = false
180
- args.theDebugger = {
181
- breakOnSemantics: (value) => args.breakOnSemantics = value
182
- }
183
- if (!logs) {
184
- }
185
- args.log = (message) => logs.push(message)
186
-
187
- args.addAssumedScoped = (args, assumed) => {
188
- const addAssumed = (args, ...moreAssumed) => {
189
- return { ...args, assumed: Object.assign({}, assumed, (args.assumed || {}), ...moreAssumed) }
190
- }
191
-
192
- args.s = (c) => config.getSemantics(logs).apply(args, c)
193
- args.g = (c, a = {}) => {
194
- return config.getGenerators(logs).apply(addAssumed(args, a), c, a)
195
- }
196
- args.gp = (c, a = {}) => {
197
- return config.getGenerators(logs).apply(addAssumed(args, a, { paraphrase: true, isResponse: false, response: false }), c, { paraphrase: true, isResponse: false, response: false })
198
- }
199
- args.gr = (c, a = {}) => {
200
- return config.getGenerators(logs).apply(addAssumed(args, a, { paraphrase: false, isResponse: true }), { ...c, paraphrase: false, isResponse: true })
201
- }
202
- args.e = (c) => {
203
- return config.getEvaluator(args.s, args.calls, logs, c)
204
- }
205
- args.gs = gs(args.g)
206
- args.gsp = gs(args.gp)
207
- args.gsr = gs(args.gr)
208
- }
209
- // for semantics
210
- args.addAssumedScoped(args, {})
211
-
212
- const getAPI = (uuid) => {
213
- if (config && config.getAPI) {
214
- return config.getAPI(uuid)
215
- }
216
- }
217
- const getAPIs = (uuid) => {
218
- if (config && config.getAPIs) {
219
- return config.getAPIs(uuid)
220
- }
221
- }
222
- args.getUUIDScoped = (uuid) => {
223
- return {
224
- api: getAPI(uuid),
225
- apis: getAPIs(uuid)
226
- }
227
- }
228
- config.getAddedArgs(args)
229
-
230
- Object.assign(args, args.getUUIDScoped(uuidForScoping || config.uuid))
231
- /*
232
- if (uuidForScoping) {
233
- Object.assign(args, args.getUUIDScoped(uuidForScoping))
234
- }
235
- */
236
- // sets args for all the API. that make a copy so the args must be fully setup by here except for scoped
237
- config.setArgs(args)
238
- }
239
-
240
- const gs = (g) => (contexts, separator, lastSeparator) => {
241
- if (!Array.isArray(contexts)) {
242
- debugger
243
- throw new Error('Expected a list')
244
- }
245
-
246
- let s = ''
247
- if (!separator) {
248
- separator = ' '
249
- }
250
- if (!lastSeparator) {
251
- lastSeparator = separator
252
- }
253
- let nextSeparator = ''
254
- for (let i = 0; i < contexts.length; ++i) {
255
- const context = contexts[i]
256
- const value = g(context)
257
- if (i > 0) {
258
- if (i === contexts.length - 1) {
259
- nextSeparator = lastSeparator
260
- } else {
261
- nextSeparator = separator
262
- }
263
- }
264
- s += nextSeparator + value
265
- }
266
- return s
267
- }
268
-
269
87
  const matching = (actual, expected) => {
270
88
  if (!deepEqual(stringify(sortJson(actual, { depth: 25 })), stringify(sortJson(expected, { depth: 25 })))) {
271
89
  return false
@@ -290,56 +108,18 @@ const analyzeMetaData = (right, wrong) => {
290
108
  return []
291
109
  }
292
110
 
293
- const processContexts = (contexts, params) => {
111
+ const processContexts = async (contexts, params) => {
294
112
  const contextsPrime = []
295
113
  const generated = []
296
114
  const logs = []
297
115
  for (const context of contexts) {
298
- const result = processContext(context, Object.assign({}, params, { logs }))
116
+ const result = await processContext(context, Object.assign({}, params, { logs }))
299
117
  contextsPrime.push(result.context)
300
118
  generated.push(result.generated)
301
119
  }
302
120
  return { contexts: contextsPrime, generated, logs }
303
121
  }
304
122
 
305
- const getObjects = (objects) => {
306
- return (uuid) => {
307
- if (objects && objects.namespaced) {
308
- return objects.namespaced[uuid]
309
- }
310
- return objects
311
- }
312
- }
313
-
314
- const processContext = (context, { objects = {}, config, logs = [] }) => {
315
- const generators = config.getGenerators(logs)
316
- const semantics = config.getSemantics(logs)
317
-
318
- // map to hash
319
- config = config || {}
320
- if (config.config) {
321
- config = config
322
- }
323
-
324
- const response = {} // NA but passed in
325
- // generators = new Generators(generators.map((g) => new Generator(normalizeGenerator(g))))
326
- // semantics = new Semantics(semantics.map((g) => new Semantic(normalizeSemantic(g))))
327
- const hierarchy = new DigraphInternal((config.config || {}).hierarchy || [])
328
-
329
- const args = { objects, response, getObjects: getObjects(objects) }
330
- setupArgs(args, config, logs, hierarchy)
331
-
332
- context = semantics.apply(args, context)
333
- const generated = generators.apply(args, context)
334
- const assumed = { paraphrase: true, response: false, isResponse: false }
335
- const paraphrases = generators.apply({ ...args, assumed }, context, { paraphrase: true, response: false, isResponse: false })
336
- let responses = []
337
- if (context.isResponse) {
338
- responses = generated
339
- }
340
- return { context, generated, paraphrases, responses }
341
- }
342
-
343
123
  const convertToStable = (objects) => {
344
124
  if (true) {
345
125
  return objects
@@ -431,139 +211,6 @@ const overlaps = (r1, context) => {
431
211
  return false
432
212
  }
433
213
 
434
- const setupContexts = (rawContexts) => {
435
- let first = true
436
- const contexts = []
437
- contexts.push({ marker: 'controlStart', controlRemove: true })
438
- for (const context of rawContexts) {
439
- if (first) {
440
- first = false
441
- } else {
442
- contexts.push({ marker: 'controlBetween', controlRemove: true })
443
- }
444
- contexts.push(context)
445
- }
446
- contexts.push({ marker: 'controlEnd', controlRemove: true })
447
- return contexts
448
- }
449
-
450
- const processContextsB = ({ config, hierarchy, semantics, generators, json, isTest, rebuildingTemplate, isInstance, instance, query, data, retries, url, commandLineArgs }) => {
451
- // TODO fix this name to contextsPrime
452
- const contextsPrime = []
453
- const generatedPrime = []
454
- const paraphrasesPrime = []
455
- const paraphrasesParenthesizedPrime = []
456
- const generatedParenthesizedPrime = []
457
- const responsesPrime = []
458
- const contexts = setupContexts(json.contexts)
459
-
460
- const objects = config.get('objects')
461
- const args = { objects, isResponse: true, response: json, isTest, isInstance, getObjects: getObjects(objects), instance }
462
- if (!json.logs) {
463
- json.logs = []
464
- }
465
- setupArgs(args, config, json.logs, hierarchy)
466
- const toDo = [...contexts]
467
- args.insert = (context) => toDo.unshift(context)
468
- let overlap, lastRange
469
- config.debugLoops = commandLineArgs && commandLineArgs.debugLoops
470
- while (toDo.length > 0) {
471
- const context = toDo.shift()
472
- args.calls.next()
473
- let contextPrime = context
474
- context.topLevel = true
475
- try {
476
- if (json.has_errors) {
477
- throw new Error('There are errors in the logs. Run with the -d flag and grep for Error')
478
- }
479
- const generateParenthesized = isTest || (commandLineArgs && commandLineArgs.save)
480
- if (!config.get('skipSemantics')) {
481
- const semantics = config.getSemantics(json.logs)
482
- try {
483
- contextPrime = semantics.apply(args, context)
484
- } catch (e) {
485
- if (e.message == 'Maximum call stack size exceeded') {
486
- const mostCalled = semantics.getMostCalled()
487
- e.message += `\nThe most called semantic was:\nnotes: ${mostCalled.notes}\nmatch: ${mostCalled.matcher.toString()}\napply: ${mostCalled._apply.toString()}\n`
488
- }
489
- // contextPrime = semantics.apply(args, { marker: 'error', context, error: e })
490
- if (isInstance) {
491
- console.log('error', e.error)
492
- }
493
- contextPrime = semantics.apply(args, {
494
- marker: 'error',
495
- context,
496
- text: e ? e.toString() : 'not available',
497
- reason: e.reason,
498
- error: e.stack || e.error
499
- })
500
- if (rebuildingTemplate) {
501
- throw e
502
- }
503
- }
504
- }
505
- if (contextPrime.controlRemove) {
506
- continue
507
- }
508
- let assumed = { isResponse: true }
509
- const generated = contextPrime.isResponse ? config.getGenerators(json.logs).apply({ ...args, assumed }, contextPrime, assumed) : ''
510
- let generatedParenthesized = []
511
- if (generateParenthesized) {
512
- config.parenthesized = true
513
- generatedParenthesized = contextPrime.isResponse ? config.getGenerators(json.logs).apply({ ...args, assumed }, contextPrime, assumed) : ''
514
- config.parenthesized = false
515
- }
516
- // assumed = { paraphrase: true, response: false };
517
- assumed = { paraphrase: true, isResponse: false, response: false }
518
- if (generateParenthesized) {
519
- config.parenthesized = false
520
- }
521
- const paraphrases = config.getGenerators(json.logs).apply({ ...args, assumed }, contextPrime, assumed)
522
- let paraphrasesParenthesized = []
523
- if (generateParenthesized) {
524
- config.parenthesized = true
525
- paraphrasesParenthesized = config.getGenerators(json.logs).apply({ ...args, assumed }, contextPrime, assumed)
526
- config.parenthesized = false
527
- }
528
- contextsPrime.push(contextPrime)
529
- generatedPrime.push(generated)
530
- paraphrasesPrime.push(paraphrases)
531
- if (generateParenthesized) {
532
- paraphrasesParenthesizedPrime.push(paraphrasesParenthesized)
533
- generatedParenthesizedPrime.push(generatedParenthesized)
534
- }
535
- if (contextPrime.isResponse) {
536
- responsesPrime.push(generated)
537
- } else {
538
- responsesPrime.push('')
539
- }
540
-
541
- // add results to processed list
542
- config.config.objects.processed = config.config.objects.processed || []
543
- config.config.objects.processed = config.config.objects.processed.slice(0, 5)
544
- config.config.objects.processed.unshift({ context: contextPrime, paraphrases: paraphrases, paraphrasesParenthesized, generatedParenthesized, responses: responsesPrime })
545
- } catch (e) {
546
- if (Array.isArray(e)) {
547
- e = {
548
- errors: e
549
- }
550
- }
551
- e.context = contextPrime
552
- if (e.logs) {
553
- e.logs = e.logs.concat(json.logs)
554
- } else {
555
- e.logs = json.logs
556
- }
557
- e.metadata = json.metadata
558
- if (json.trace) {
559
- e.trace = json.trace
560
- }
561
- throw e
562
- }
563
- }
564
- return { contextsPrime, generatedPrime, paraphrasesPrime, paraphrasesParenthesizedPrime, generatedParenthesizedPrime, responsesPrime }
565
- }
566
-
567
214
  const doWithRetries = async (n, url, queryParams, data) => {
568
215
  if (!queryParams) {
569
216
  queryParams = ''
@@ -598,93 +245,6 @@ const doWithRetries = async (n, url, queryParams, data) => {
598
245
  }
599
246
  }
600
247
 
601
- const setupProcessB = ({ config, initializer, allowDelta = false } = {}) => {
602
- const key = config._key
603
-
604
- const data = Object.assign({ key, version: '3' }, { uuid: config._uuid })
605
- if (allowDelta && config.allowDelta && config.hasDelta()) {
606
- // console.log('config', config)
607
- data.delta = config.delta()
608
- } else {
609
- config.toData(data)
610
- // Object.assign(data, config.config)
611
- }
612
-
613
- // config.toServer(data)
614
-
615
- if (data.namespaces) {
616
- for (const uuid of Object.keys(data.namespaces)) {
617
- const km = config.configs.find((km) => km.uuid === uuid)
618
- data.namespaces[uuid].name = km.name
619
- }
620
- }
621
-
622
- // const generators = new Generators((data.generators || []).map((g) => new Generator(normalizeGenerator(g))))
623
- delete data.generators
624
- // const semantics = new Semantics((data.semantics || []).map((g) => new Semantic(normalizeSemantic(g))))
625
- delete data.semantics
626
- const hierarchy = new DigraphInternal((config.config || {}).hierarchy || [])
627
-
628
- return {
629
- data,
630
- // generators,
631
- // semantics,
632
- hierarchy
633
- }
634
- }
635
-
636
- // instance template loadTemplate
637
- const loadInstance = (config, instance) => {
638
- const transitoryMode = global.transitoryMode
639
- global.transitoryMode = false
640
-
641
- if (instance && (instance.associations || instance.learned_contextual_priorities)) {
642
- if (!config.config.retrain) {
643
- if (instance.associations) {
644
- config.addAssociations(instance.associations)
645
- }
646
- if (instance.learned_contextual_priorities && instance.learned_contextual_priorities.length > 0) {
647
- config.addPriorities(instance.learned_contextual_priorities)
648
- }
649
- }
650
- }
651
-
652
- const { /* data, generators, semantics, */ hierarchy } = setupProcessB({ config })
653
- // for (const results of (instance.resultss || [])) {
654
- for (const i in (instance.resultss || [])) {
655
- const results = instance.resultss[i]
656
- if (results.extraConfig) {
657
- // config.addInternal(results, useOldVersion = true, skipObjects = false, includeNamespaces = true, allowNameToBeNull = false)
658
- const uuid = config.nameToUUID(instance.name)
659
- // used to do a CLONE
660
- config.addInternal(instance.template.configs[i], { uuid, addFirst: true, handleCalculatedProps: true })
661
- } else if (results.apply) {
662
- const objects = config.get('objects')
663
- const args = { objects, getObjects: getObjects(objects) }
664
- if (instance.configs) {
665
- args.isInstance = `instance${i}`
666
- args.instance = instance.configs[i]
667
- }
668
-
669
- const uuid = config.nameToUUID(instance.name)
670
- setupArgs(args, config, config.logs, hierarchy, uuid)
671
- results.apply(args)
672
- } else {
673
- if (results.skipSemantics) {
674
- config.config.skipSemantics = results.skipSemantics
675
- }
676
- const args = { config, hierarchy, json: results, commandLineArgs: {} }
677
- args.isInstance = `instance${i}`
678
- args.instance = ''
679
- processContextsB(args)
680
- if (results.skipSemantics) {
681
- config.config.skipSemantics = null
682
- }
683
- }
684
- }
685
- global.transitoryMode = transitoryMode
686
- }
687
-
688
248
  const throwErrorHandler = (error) => {
689
249
  throw error
690
250
  }
@@ -701,7 +261,7 @@ const _process = async (config, query, { initializer, commandLineArgs, credentia
701
261
  // ensure same start state
702
262
  try {
703
263
  if (writeTests) {
704
- config.rebuild()
264
+ await config.rebuild()
705
265
  const objects = getObjects(config.config.objects)(config.uuid)
706
266
  }
707
267
  } catch (error) {
@@ -773,7 +333,7 @@ const _process = async (config, query, { initializer, commandLineArgs, credentia
773
333
  start = runtime.performance.performance.now()
774
334
  }
775
335
  const { contextsPrime, generatedPrime, paraphrasesPrime, paraphrasesParenthesizedPrime, generatedParenthesizedPrime, responsesPrime } =
776
- processContextsB({ isTest, rebuildingTemplate, config, hierarchy, json, commandLineArgs /*, generators, semantics */ })
336
+ await processContextsB({ isTest, rebuildingTemplate, config, hierarchy, json, commandLineArgs /*, generators, semantics */ })
777
337
  if (isTest) {
778
338
  end = runtime.performance.performance.now()
779
339
  clientSideTime = end - start
@@ -865,8 +425,12 @@ const getConfigForTest = (config, testConfig) => {
865
425
 
866
426
  const runTest = async (config, expected, { args, verbose, testConfig, debug }) => {
867
427
  const test = expected.query
428
+ if (args.query && args.query != test) {
429
+ // no run this
430
+ return
431
+ }
868
432
  // initialize in between test so state is not preserved since the test was adding without state
869
- config.rebuild()
433
+ await config.rebuild()
870
434
  const errorHandler = (error) => {
871
435
  if (error.metadata) {
872
436
  const priorities = analyzeMetaData(expected.metadata, error.metadata)
@@ -1012,7 +576,7 @@ const runTests = async (config, testFile, juicyBits) => {
1012
576
  }
1013
577
 
1014
578
  const saveTest = async (testFile, config, test, expected, testConfig, saveDeveloper) => {
1015
- config.rebuild()
579
+ await config.rebuild()
1016
580
  const objects = getObjects(config.config.objects)(config.uuid)
1017
581
  console.log(test)
1018
582
  const result = await _process(config, test, { isTest: true })
@@ -1033,11 +597,11 @@ const saveTestsHelper = async (testFile, config, tests, todo, testConfig, saveDe
1033
597
  return
1034
598
  }
1035
599
  const test = todo.pop()
1036
- config.rebuild()
600
+ await config.rebuild()
1037
601
  const result = await saveTest(testFile, config, test, tests[test], testConfig, saveDeveloper)
1038
602
  // initialize in between test so state is not preserved since the test was adding without state
1039
603
  // config.initialize({force: true})
1040
- config.rebuild()
604
+ await config.rebuild()
1041
605
  return saveTestsHelper(testFile, config, tests, todo, testConfig, saveDeveloper)
1042
606
  }
1043
607
 
@@ -1324,6 +888,7 @@ const rebuildTemplate = async ({ config, target, previousResultss, startOfChange
1324
888
  associations: [],
1325
889
  learned_contextual_priorities: []
1326
890
  }
891
+ config.fragmentsBeingBuilt = []
1327
892
  const looper = async (configs) => {
1328
893
  if (configs.length === 0) {
1329
894
  finish()
@@ -1331,14 +896,15 @@ const rebuildTemplate = async ({ config, target, previousResultss, startOfChange
1331
896
  }
1332
897
  const { property, hierarchy, query: queryOrExtraConfig, previousResults, initializer, skipSemantics } = configs.shift()
1333
898
  // queries are strings or { query: "blah", development: true/false }
1334
- if (typeof queryOrExtraConfig === 'string' || queryOrExtraConfig.query) {
899
+ if (typeof queryOrExtraConfig === 'string' || queryOrExtraConfig.query || queryOrExtraConfig.isFragment) {
1335
900
  let query = queryOrExtraConfig
901
+ let isFragment = queryOrExtraConfig.isFragment
1336
902
  if (typeof queryOrExtraConfig === 'string') {
1337
903
  query = { query }
1338
904
  }
1339
- config.config.skipSemantics = skipSemantics
905
+ config.config.skipSemantics = skipSemantics && !isFragment
1340
906
  const transitoryMode = global.transitoryMode
1341
- if (property == 'fragments') {
907
+ if (isFragment || property == 'fragments') {
1342
908
  global.transitoryMode = true
1343
909
  }
1344
910
  if (hierarchy) {
@@ -1356,7 +922,7 @@ const rebuildTemplate = async ({ config, target, previousResultss, startOfChange
1356
922
  if (previousResults && previousResults.query == query.query) {
1357
923
  results = previousResults
1358
924
  prMessage = ' Using previous results. use -rtf for a hard rebuild of everything on the server side.'
1359
- loadInstance(config, { resultss: [results] })
925
+ await loadInstance(config, { resultss: [results] })
1360
926
  } else {
1361
927
  results = await _process(config, query.query, { initializer, rebuildingTemplate: true })
1362
928
  }
@@ -1370,15 +936,19 @@ const rebuildTemplate = async ({ config, target, previousResultss, startOfChange
1370
936
  } else if (results.paraphrases[0] != query.query) {
1371
937
  console.log(`query "${query.query}". The paraphrase is different from the query "${results.paraphrases[0]}".${prMessage}`)
1372
938
  } else {
1373
- console.log(`query "${query.query}".${prMessage}`)
939
+ console.log(`query ${isFragment ? 'fragment' : ''}"${query.query}".${prMessage}`)
1374
940
  }
1375
941
  global.transitoryMode = transitoryMode
1376
942
  config.config.skipSemantics = null
1377
943
  results.query = query.query
944
+ results.isFragment = isFragment
1378
945
  results.skipSemantics = skipSemantics
1379
946
  results.development = query.development
1380
947
  results.key = { query: query.query, hierarchy }
1381
948
  accumulators[property].push(results)
949
+ if (isFragment) {
950
+ config.fragmentsBeingBuilt.push({ query: query.query, contexts: results.contexts })
951
+ }
1382
952
  accumulators.associations = accumulators.associations.concat(results.associations)
1383
953
  accumulators.learned_contextual_priorities = accumulators.learned_contextual_priorities.concat(results.learned_contextual_priorities)
1384
954
  await looper(configs)
@@ -1392,7 +962,7 @@ const rebuildTemplate = async ({ config, target, previousResultss, startOfChange
1392
962
  const initFunction = queryOrExtraConfig
1393
963
  const objects = config.get('objects')
1394
964
  const args = { objects, getObjects: getObjects(objects) }
1395
- setupArgs(args, config, config.logs, hierarchy)
965
+ setupArgs(args, config, config.logs, config.hierarchy)
1396
966
  initFunction(args)
1397
967
  accumulators[property].push({ apply: queryOrExtraConfig })
1398
968
  await looper(configs)
@@ -1417,6 +987,7 @@ const rebuildTemplate = async ({ config, target, previousResultss, startOfChange
1417
987
  }
1418
988
 
1419
989
  const finish = () => {
990
+ config.fragmentsBeingBuilt = []
1420
991
  const instanceName = `${target}.instance.json`
1421
992
  console.log(`Writing instance file ${instanceName}`)
1422
993
  const stabilizeAssociations = (associations) => {
@@ -1505,11 +1076,15 @@ const checkTest = (testConfig) => {
1505
1076
  }
1506
1077
 
1507
1078
  const knowledgeModuleImpl = async ({
1079
+ includes,
1080
+ config : configStruct,
1081
+ api,
1082
+ initializer,
1083
+ multiApiInitializer,
1084
+
1508
1085
  module: moduleFromJSFile,
1509
1086
  description,
1510
1087
  section,
1511
- // config, createConfig,
1512
- createConfig,
1513
1088
  newWay,
1514
1089
  demo,
1515
1090
  test,
@@ -1517,7 +1092,6 @@ const knowledgeModuleImpl = async ({
1517
1092
  errorHandler = defaultErrorHandler,
1518
1093
  process: processResults = defaultProcess,
1519
1094
  stopAtFirstFailure = true,
1520
- acceptsAdditionalConfig = false,
1521
1095
  ...rest
1522
1096
  } = {}) => {
1523
1097
  const unknownArgs = Object.keys(rest)
@@ -1530,10 +1104,28 @@ const knowledgeModuleImpl = async ({
1530
1104
  if (!moduleFromJSFile) {
1531
1105
  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.")
1532
1106
  }
1533
- // if (!config && !createConfig) {
1534
- if (!createConfig) {
1107
+
1108
+ if (!configStruct) {
1535
1109
  throw new Error("'config' or 'createConfig' is a required parameter. The value should the config that defines the knowledge module.")
1536
1110
  }
1111
+
1112
+ const createConfig = async () => {
1113
+ const config = new Config(configStruct, moduleFromJSFile, _process)
1114
+ config.stop_auto_rebuild()
1115
+ await config.add(...(includes || []))
1116
+ if (api) {
1117
+ config.setApi(api)
1118
+ }
1119
+ if (multiApiInitializer) {
1120
+ await config.setMultiApi(multiApiInitializer)
1121
+ }
1122
+ if (initializer) {
1123
+ config.initializer(initializer)
1124
+ }
1125
+ await config.restart_auto_rebuild()
1126
+ return config
1127
+ }
1128
+
1537
1129
  if (!description) {
1538
1130
  throw new Error("'description' is a required parameter. The value should the description of the knowledge module.")
1539
1131
  }
@@ -1582,7 +1174,7 @@ const knowledgeModuleImpl = async ({
1582
1174
  parser.add_argument('-t', '--test', { action: 'store_true', help: 'Run the tests. Create tests by running with the --query + --save flag' })
1583
1175
  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' })
1584
1176
  // parser.add_argument('-ttr', '--testToRun', { help: 'Only the specified test will be run' })
1585
- 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' })
1177
+ 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. if -q is specified the tests will be run for just the specified query.' })
1586
1178
  parser.add_argument('-tnp', '--testNoParenthesized', { action: 'store_true', help: 'Don\' check parenthesized differences for the tests' })
1587
1179
  parser.add_argument('-n', '--count', { help: 'Number of times to run the tests. Default is one. Use this to check for flakey test. If possible the system will print out a message with the word "hint" suggesting how to fix the problem' })
1588
1180
  // parser.add_argument('-b', '--build', { help: 'Specify the template file name of the form <kmName>. There should be a file called <baseKmName>.<kmName>.template.json with the queries to run. For example { queries: [...] }. The template file will be run and generate an instantiation called <baseKmName>.<kmName>.instance.json and a file called <kmName>.js that will load the template file (this is file generated only if not already existing) and a test file called <KmName>.tests.json. This can then be loaded into an instance of the current knowledge module to setup initial conditions.' })
@@ -1628,7 +1220,7 @@ const knowledgeModuleImpl = async ({
1628
1220
  global.pauseDebugging = true
1629
1221
  }
1630
1222
 
1631
- const config = createConfig()
1223
+ const config = await createConfig()
1632
1224
  setupConfig(config)
1633
1225
  processResults = processResults({ config, errorHandler })
1634
1226
 
@@ -1663,7 +1255,7 @@ const knowledgeModuleImpl = async ({
1663
1255
  throw new Error('Error for the checkForLoop argument. Expected a JSON array of operator keys of the form "[<id>, <level>]"')
1664
1256
  }
1665
1257
  } catch (e) {
1666
- throw new Error(`Error parsing JSON of the checkForLoop argument. ${e}`)
1258
+ throw new Error('Error for the checkForLoop argument. Expected a JSON array of operator keys of the form "[<id>, <level>]"')
1667
1259
  }
1668
1260
  } else {
1669
1261
  if (process.argv.includes('--checkForLoop') || process.argv.includes('-cl')) {
@@ -1773,7 +1365,7 @@ const knowledgeModuleImpl = async ({
1773
1365
  // { literals: Object, patterns: Array(2), hierarchy: Array(97) }
1774
1366
  console.log('literals')
1775
1367
  for (const word in config.config.words.literals) {
1776
- console.log(' ' + word.concat(' ', ...config.config.words.literals[word].map((def) => JSON.stringify(def))))
1368
+ console.log(' ' + word.concat(...config.config.words.literals[word].map((def, i) => ((i > 0) ? ' '.repeat(4+word.length) : ' ') + JSON.stringify(def) + '\n')))
1777
1369
  }
1778
1370
  console.log('patterns')
1779
1371
  for (const pattern of config.config.words.patterns) {
@@ -1860,7 +1452,7 @@ const knowledgeModuleImpl = async ({
1860
1452
  config.config.rebuild = true
1861
1453
  }
1862
1454
  try {
1863
- config.load(template.template, template.instance, { rebuild: needsRebuild.needsRebuild || options.rebuild, previousResultss: needsRebuild.previousResultss, startOfChanges: needsRebuild.startOfChanges })
1455
+ await config.load(rebuildTemplate, template.template, template.instance, { rebuild: needsRebuild.needsRebuild || options.rebuild, previousResultss: needsRebuild.previousResultss, startOfChanges: needsRebuild.startOfChanges })
1864
1456
  } catch (e) {
1865
1457
  console.error(`Error loading template for ${config.name}. ${e.error ? e.error : e}${e.stack ? e.stack : ''}`)
1866
1458
  runtime.process.exit(-1)
@@ -1877,6 +1469,9 @@ const knowledgeModuleImpl = async ({
1877
1469
  config.config.retrain = true
1878
1470
  }
1879
1471
 
1472
+ if (args.saveDeveloper) {
1473
+ args.save = true
1474
+ }
1880
1475
  if (args.test || args.testVerbose || args.testAllVerbose || args.save) {
1881
1476
  global.transitoryMode = true
1882
1477
  }
@@ -1994,7 +1589,7 @@ const knowledgeModuleImpl = async ({
1994
1589
  lines.setElement(2, 2, JSON.stringify(result.actual.checked, null, 2))
1995
1590
  lines.log()
1996
1591
  if (args.vimdiff) {
1997
- vimdiff(result.actual.checked, result.expected.checked)
1592
+ show('checked properties for objects', result.expected.checked, result.actual.checked)
1998
1593
  }
1999
1594
  newError = true
2000
1595
  headerShown = true
@@ -2012,7 +1607,7 @@ const knowledgeModuleImpl = async ({
2012
1607
  lines.setElement(2, 2, JSON.stringify(result.actual.checkedContexts, null, 2))
2013
1608
  lines.log()
2014
1609
  if (args.vimdiff) {
2015
- vimdiff(result.actual.checkedContexts, result.expected.checkedContexts)
1610
+ show('checked properties for context', result.expected.checkedContexts, result.actual.checkedContexts)
2016
1611
  }
2017
1612
  newError = true
2018
1613
  headerShown = true
@@ -2105,9 +1700,11 @@ const knowledgeModuleImpl = async ({
2105
1700
  }
2106
1701
  printConfig()
2107
1702
  } else {
2108
- const initConfig = (config) => {
1703
+ const initConfig = async (config) => {
2109
1704
  if (template) {
2110
1705
  if (config.needsRebuild(template.template, template.instance, { isModule: !isProcess }).needsRebuild) {
1706
+ debugger
1707
+ config.needsRebuild(template.template, template.instance, { isModule: !isProcess })
2111
1708
  const error = `This module "${config.name}" cannot be used because the instance file needs rebuilding. Run on the command line with no arguments or the -rt argument to rebuild.`
2112
1709
  throw new Error(error)
2113
1710
  }
@@ -2140,24 +1737,21 @@ const knowledgeModuleImpl = async ({
2140
1737
 
2141
1738
  if (template) {
2142
1739
  try {
2143
- config.load(template.template, template.instance)
1740
+ await config.load(rebuildTemplate, template.template, template.instance)
2144
1741
  } catch (e) {
2145
1742
  errorHandler(e)
2146
1743
  }
2147
1744
  }
2148
1745
  }
2149
1746
 
2150
- createConfigExport = (additionalConfig) => {
2151
- if (createConfig.cached) {
1747
+ // no cache 21 minutes + rebuild fails "node tester_rebuild -m colors"
1748
+ // cache okay
1749
+ createConfigExport = async () => {
1750
+ if (false && createConfig.cached) {
2152
1751
  return createConfig.cached
2153
1752
  }
2154
- const config = createConfig(acceptsAdditionalConfig ? additionalConfig : null)
2155
- if (!acceptsAdditionalConfig && additionalConfig) {
2156
- config.stop_auto_rebuild()
2157
- additionalConfig(config)
2158
- config.restart_auto_rebuild()
2159
- }
2160
- initConfig(config)
1753
+ const config = await createConfig()
1754
+ await initConfig(config)
2161
1755
  // config.rebuild({ isModule: true })
2162
1756
  createConfig.cached = config
2163
1757
  return createConfig.cached
@@ -2186,11 +1780,6 @@ const ensureTestFile = (module, name, type) => {
2186
1780
  }
2187
1781
  }
2188
1782
 
2189
- function w (func) {
2190
- func.where = where(3)
2191
- return func
2192
- }
2193
-
2194
1783
  const knowledgeModule = async (...args) => {
2195
1784
  await knowledgeModuleImpl(...args).catch((e) => {
2196
1785
  console.error(e)
@@ -2201,9 +1790,6 @@ const knowledgeModule = async (...args) => {
2201
1790
  module.exports = {
2202
1791
  process: _process,
2203
1792
  stableId,
2204
- where,
2205
- w,
2206
- // submitBug,
2207
1793
  ensureTestFile,
2208
1794
  rebuildTemplate,
2209
1795
  processContext,