theprogrammablemind 8.9.1-beta.26 → 8.9.1-beta.28

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,7 +12,7 @@ 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 } = require('./src/helpers')
15
+ const { appendNoDups, InitCalls, updateQueries, safeNoDups, stableId, where, suggestAssociationsFix, suggestAssociationsFixFromSummaries } = require('./src/helpers')
16
16
  const runtime = require('./runtime')
17
17
  const sortJson = runtime.sortJson
18
18
 
@@ -35,6 +35,16 @@ const getConfig_getObjectsCheck = (config, testConfig) => {
35
35
  }
36
36
  }
37
37
 
38
+ const getSuggestion = (diff) => {
39
+ return diff.map( (element) => {
40
+ return element.marker
41
+ })
42
+ }
43
+
44
+ const getSuggestionMessage = (suggestion) => {
45
+ return `Try adding this to the associations: { context: ${JSON.stringify(getSuggestion(suggestion))}, choose: <indexOfMainElement> },\n If that does not work look at the logs and check when the operators become wrong during an interation. Deduce the change based on the previous iteration and what operator was applied.`
46
+ }
47
+
38
48
  const getConfig_getContextCheck = (testConfig) => {
39
49
  return (testConfig.checks && testConfig.checks.context) || []
40
50
  }
@@ -148,7 +158,7 @@ const writeTestFile = (fn, tests) => {
148
158
  runtime.fs.writeFileSync(fn, stringify(tests, { space: 2 }), { encoding: 'utf8', flag: 'w+' })
149
159
  }
150
160
 
151
- const writeTest = (fn, query, objects, generated, paraphrases, responses, contexts, associations, metadata, config, saveDeveloper, paraphrasesParenthesized, generatedParenthesized) => {
161
+ const writeTest = (fn, query, objects, generated, paraphrases, responses, contexts, associations, metadata, config, saveDeveloper, paraphrasesParenthesized, generatedParenthesized, summaries) => {
152
162
  let tests = []
153
163
  if (runtime.fs.existsSync(fn)) {
154
164
  tests = JSON.parse(runtime.fs.readFileSync(fn))
@@ -160,6 +170,7 @@ const writeTest = (fn, query, objects, generated, paraphrases, responses, contex
160
170
  // tests[query] = sortJson({ paraphrases, responses, contexts, objects: convertToStable(objects), associations, metadata, config, developerTest: saveDeveloper }, { depth: 25 })
161
171
  const results = sortJson({
162
172
  query,
173
+ summaries,
163
174
  paraphrases,
164
175
  responses,
165
176
  contexts,
@@ -276,7 +287,7 @@ const _process = async (config, query, { initializer, commandLineArgs, credentia
276
287
  data.errors_ignore_contextual_priorities_non_existant_ops = true
277
288
  }
278
289
  let queries = query.split('\\n')
279
-
290
+ let summaries = [] // for error
280
291
  try {
281
292
  const response = {
282
293
  hierarchy: [],
@@ -294,7 +305,8 @@ const _process = async (config, query, { initializer, commandLineArgs, credentia
294
305
  paraphrasesParenthesized: [],
295
306
  generatedParenthesized: [],
296
307
  responses: [],
297
- associations: []
308
+ associations: [],
309
+ summaries: []
298
310
  }
299
311
 
300
312
  let startCounter = 0
@@ -335,6 +347,8 @@ const _process = async (config, query, { initializer, commandLineArgs, credentia
335
347
  if (isTest) {
336
348
  start = runtime.performance.performance.now()
337
349
  }
350
+ const summary = { summaries: json.summaries, length: json.contexts.length }
351
+ summaries.push(summary)
338
352
  const { contextsPrime, generatedPrime, paraphrasesPrime, paraphrasesParenthesizedPrime, generatedParenthesizedPrime, responsesPrime } =
339
353
  await processContextsB({ isTest, rebuildingTemplate, config, hierarchy, json, commandLineArgs /*, generators, semantics */ })
340
354
  if (isTest) {
@@ -363,6 +377,7 @@ const _process = async (config, query, { initializer, commandLineArgs, credentia
363
377
  response.paraphrasesParenthesized = response.paraphrasesParenthesized.concat(paraphrasesParenthesizedPrime)
364
378
  response.generatedParenthesized = response.generatedParenthesized.concat(generatedParenthesizedPrime)
365
379
  response.responses = response.responses.concat(responsesPrime)
380
+ response.summaries.push(summary)
366
381
  queries = queries.slice(1)
367
382
  }
368
383
  }
@@ -374,11 +389,12 @@ const _process = async (config, query, { initializer, commandLineArgs, credentia
374
389
  for (const km of config.configs) {
375
390
  saveObjects.nameToUUID[km.name] = km.uuid
376
391
  }
377
- writeTest(testsFN, query, saveObjects, response.generated, response.paraphrases, response.responses, response.contexts, response.associations, response.metadata, actual_config, saveDeveloper, response.paraphrasesParenthesized, response.generatedParenthesized)
392
+ writeTest(testsFN, query, saveObjects, response.generated, response.paraphrases, response.responses, response.contexts, response.associations, response.metadata, actual_config, saveDeveloper, response.paraphrasesParenthesized, response.generatedParenthesized, response.summaries)
378
393
  }
379
394
 
380
395
  return response
381
396
  } catch (error) {
397
+ error.summaries = summaries
382
398
  error.query = query
383
399
  errorHandler(error)
384
400
  }
@@ -538,7 +554,8 @@ const runTest = async (config, expected, { args, verbose, testConfig, debug, tim
538
554
  checked: expected_checked,
539
555
  checkedContexts: pickedExpectedContexts,
540
556
  objects: expected_objects,
541
- config: expected.config
557
+ config: expected.config,
558
+ summaries: expected.summaries,
542
559
  },
543
560
  actual: {
544
561
  responses: result.responses,
@@ -549,7 +566,8 @@ const runTest = async (config, expected, { args, verbose, testConfig, debug, tim
549
566
  checked: actual_checked,
550
567
  checkedContexts: pickedResultContexts,
551
568
  objects: actual_objects,
552
- config: actual_config
569
+ config: actual_config,
570
+ summaries: result.summaries,
553
571
  }
554
572
  }
555
573
  }
@@ -608,7 +626,7 @@ const saveTest = async (testFile, config, test, expected, testConfig, saveDevelo
608
626
  for (const km of config.configs) {
609
627
  saveObjects.nameToUUID[km.name] = km.uuid
610
628
  }
611
- writeTest(testFile, test, saveObjects, result.generated, result.paraphrases, result.responses, result.contexts, result.associations, result.metadata, actualConfig, saveDeveloper, result.paraphrasesParenthesized, result.generatedParenthesized)
629
+ writeTest(testFile, test, saveObjects, result.generated, result.paraphrases, result.responses, result.contexts, result.associations, result.metadata, actualConfig, saveDeveloper, result.paraphrasesParenthesized, result.generatedParenthesized, result.summaries)
612
630
  }
613
631
 
614
632
  const saveTestsHelper = async (testFile, config, tests, todo, testConfig, saveDeveloper) => {
@@ -903,12 +921,13 @@ const defaultProcess = ({ config, errorHandler }) => async (promise) => {
903
921
  }
904
922
 
905
923
  // builtTemplate saveInstance
906
- const rebuildTemplate = async ({ config, target, previousResultss, startOfChanges, template, errorHandler = defaultErrorHandler }) => {
924
+ const rebuildTemplate = async ({ config, instance, target, previousResultss, rebuild, startOfChanges, template, errorHandler = defaultErrorHandler }) => {
907
925
  const accumulators = {
908
926
  resultss: [],
909
927
  fragments: [],
910
928
  semantics: [],
911
929
  associations: [],
930
+ summaries: [],
912
931
  learned_contextual_priorities: []
913
932
  }
914
933
  config.fragmentsBeingBuilt = []
@@ -942,12 +961,29 @@ const rebuildTemplate = async ({ config, target, previousResultss, startOfChange
942
961
  try {
943
962
  let results
944
963
  let prMessage = ''
945
- if (previousResults && previousResults.query == query.query) {
964
+ const suggestFix = (newSummaries) => {
965
+ if (!previousResults) {
966
+ return
967
+ }
968
+ const suggestion = suggestAssociationsFixFromSummaries(previousResults.summaries, newSummaries)
969
+ if (suggestion.length > 0) {
970
+ console.log(getSuggestionMessage(suggestion))
971
+ }
972
+ }
973
+ if (!rebuild && previousResults && previousResults.query == query.query) {
946
974
  results = previousResults
947
975
  prMessage = ' Using previous results. use -rtf for a hard rebuild of everything on the server side.'
948
976
  await loadInstance(config, { resultss: [results] })
949
977
  } else {
950
- results = await _process(config, query.query, { initializer, rebuildingTemplate: true })
978
+ try {
979
+ results = await _process(config, query.query, { initializer, rebuildingTemplate: true })
980
+ } catch (e) {
981
+ debugger
982
+ if (e.summaries && e.summaries.length > 0) {
983
+ suggestFix(e.summaries)
984
+ }
985
+ throw e
986
+ }
951
987
  }
952
988
  if (config.config.debug) {
953
989
  // TODO pass in the error handler like the other ones
@@ -955,9 +991,11 @@ const rebuildTemplate = async ({ config, target, previousResultss, startOfChange
955
991
  }
956
992
  if (results.contexts.length > 1) {
957
993
  console.log(`query "${query.query}". There is ${results.contexts.length} contexts in the results. Make sure its producing the results that you expect.`)
994
+ suggestFix(results.summaries)
958
995
  throw new Error(`query "${query.query}". There is ${results.contexts.length} contexts in the results. Make sure its producing the results that you expect.`)
959
996
  } else if (results.paraphrases[0].toLowerCase() !== query.query.toLowerCase()) {
960
997
  console.log(`query "${query.query}". The paraphrase is different from the query "${results.paraphrases[0]}".${prMessage}`)
998
+ // suggestFix(results.summaries)
961
999
  } else {
962
1000
  console.log(`query ${isFragment ? 'fragment' : ''}"${query.query}".${prMessage}`)
963
1001
  }
@@ -972,6 +1010,7 @@ const rebuildTemplate = async ({ config, target, previousResultss, startOfChange
972
1010
  if (isFragment) {
973
1011
  config.fragmentsBeingBuilt.push({ query: query.query, contexts: results.contexts })
974
1012
  }
1013
+ accumulators.summaries = accumulators.summaries.concat(results.summaries)
975
1014
  accumulators.associations = accumulators.associations.concat(results.associations)
976
1015
  accumulators.learned_contextual_priorities = accumulators.learned_contextual_priorities.concat(results.learned_contextual_priorities)
977
1016
  await looper(configs)
@@ -1064,16 +1103,31 @@ const rebuildTemplate = async ({ config, target, previousResultss, startOfChange
1064
1103
  }
1065
1104
  let todo = []
1066
1105
  todo = todo.concat((template.initializers || []).map((query) => { return { initializer: true, property: 'resultss', query, skipSemantics: false || query.skipSemantics } }))
1106
+ /*
1067
1107
  todo = todo.concat((template.configs || []).map((query, index) => {
1068
1108
  let pr
1069
- if (index < startOfChanges) {
1109
+ if (index < startOfChanges || (!startOfChanges && index < previousResultss.length)) {
1070
1110
  pr = previousResultss[index]
1071
1111
  }
1072
1112
  return { property: 'resultss', query, previousResults: pr, skipSemantics: false || query.skipSemantics }
1073
1113
  }))
1074
- todo = todo.concat((template.fragments || []).map((query) => { return Object.assign({}, toProperties(query), { property: 'fragments', skipSemantics: false }) }))
1075
- todo = todo.concat((template.semantics || []).map((definition) => { return { property: 'semantics', query: `${definition.from}\n${definition.to}`, skipSemantics: true } }))
1076
- await looper(Object.assign([], todo))
1114
+ */
1115
+ if (template.configs) {
1116
+ for (let configsIndex = 0; configsIndex < template.configs.length; ++configsIndex) {
1117
+ const query = template.configs[configsIndex]
1118
+ // account for things for example associations being added to the config while debugginer
1119
+ const pr = previousResultss.find((pr) => pr.query == query)
1120
+ todo.push({ property: 'resultss', query, previousResults: pr, skipSemantics: false || query.skipSemantics })
1121
+ }
1122
+ }
1123
+ todo = todo.concat((template.fragments || []).map((query, index) => {
1124
+ const pr = instance.fragments[index]
1125
+ return Object.assign({}, toProperties(query), { property: 'fragments', previousResults: pr, skipSemantics: false })
1126
+ }))
1127
+ todo = todo.concat((template.semantics || []).map((definition) => {
1128
+ return { property: 'semantics', query: `${definition.from}\n${definition.to}`, skipSemantics: true }
1129
+ }))
1130
+ await looper([...todo])
1077
1131
  }
1078
1132
 
1079
1133
  const checkTemplate = (template) => {
@@ -1571,13 +1625,18 @@ const knowledgeModuleImpl = async ({
1571
1625
  console.log('**************************** ERRORS ************************')
1572
1626
  for (const result of results) {
1573
1627
  console.log('Utterance: ', result.utterance)
1574
- const show = (label, expected, actual) => {
1628
+ if (!result.hasError) {
1629
+ continue
1630
+ }
1631
+ const show = (label, expected, actual, { console_log=true } = {}) => {
1575
1632
  if (JSON.stringify(expected) !== JSON.stringify(actual)) {
1576
- if (!headerShown) {
1577
- console.log(' Failure')
1633
+ if (console_log) {
1634
+ if (!headerShown) {
1635
+ console.log(' Failure')
1636
+ }
1637
+ console.log(` expected ${label}`, expected)
1638
+ console.log(` actual ${label} `, actual)
1578
1639
  }
1579
- console.log(` expected ${label}`, expected)
1580
- console.log(` actual ${label} `, actual)
1581
1640
  newError = true
1582
1641
  headerShown = true
1583
1642
  if (args.vimdiff) {
@@ -1586,6 +1645,44 @@ const knowledgeModuleImpl = async ({
1586
1645
  result.hasError = true
1587
1646
  }
1588
1647
  }
1648
+ if (!deepEqual(result.expected.summaries, result.actual.summaries)) {
1649
+ /*
1650
+ const suggestion = suggestAssociationsFix(result.expected.summaries, result.actual.summaries)
1651
+ let suggestedFix
1652
+ if (suggestion) {
1653
+ suggestedFix = suggestion
1654
+ console.log(`Try adding this to the associations: { context: ${JSON.stringify(getSuggestion(suggestedFix))}, choose: <indexOfMainElement> }`)
1655
+ }
1656
+ */
1657
+
1658
+ const checkForFix = () => {
1659
+ for (let iDiff = 0; iDiff < result.expected.paraphrases.length; ++iDiff) {
1660
+ if (result.expected.paraphrases[iDiff] !== result.actual.paraphrases[iDiff]) {
1661
+ // const context = result.expected.contexts[iDiff]
1662
+ let lengths = 0
1663
+ // just check where the results differ since earlier summaries can be different but dont matter if the result is the same
1664
+ for (let iSummaries = 0; iSummaries < result.expected.summaries.length; ++iSummaries) {
1665
+ const summary = result.expected.summaries[iSummaries]
1666
+ lengths += summary.length
1667
+ if (lengths > iDiff) {
1668
+ const suggestion = suggestAssociationsFix(result.expected.summaries[iSummaries].summaries, result.actual.summaries[iSummaries].summaries)
1669
+ if (suggestion) {
1670
+ suggestedFix = suggestion
1671
+ // console.log(`Try adding this to the associations: { context: ${JSON.stringify(getSuggestion(suggestedFix))}, choose: <indexOfMainElement> },`)
1672
+ console.log(getSuggestionMessage(suggestedFix))
1673
+ return
1674
+ }
1675
+ }
1676
+ }
1677
+ }
1678
+ }
1679
+ }
1680
+ checkForFix()
1681
+
1682
+ // find the context where the different is
1683
+ // select the first diff that has a different operator in the range
1684
+ // show that
1685
+ }
1589
1686
  show('paraphrases', result.expected.paraphrases, result.actual.paraphrases)
1590
1687
  if (!args.testNoParenthesized) {
1591
1688
  show('paraphrases parenthesized', result.expected.paraphrasesParenthesized, result.actual.paraphrasesParenthesized)
@@ -1749,7 +1846,6 @@ const knowledgeModuleImpl = async ({
1749
1846
  const initConfig = async (config) => {
1750
1847
  if (template) {
1751
1848
  if (config.needsRebuild(template.template, template.instance, { isModule: !isProcess }).needsRebuild) {
1752
- debugger
1753
1849
  config.needsRebuild(template.template, template.instance, { isModule: !isProcess })
1754
1850
  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.`
1755
1851
  throw new Error(error)
package/package.json CHANGED
@@ -67,6 +67,6 @@
67
67
  "sort-json": "^2.0.0",
68
68
  "uuid": "^8.3.2"
69
69
  },
70
- "version": "8.9.1-beta.26",
70
+ "version": "8.9.1-beta.28",
71
71
  "license": "UNLICENSED"
72
72
  }
package/src/config.js CHANGED
@@ -119,19 +119,35 @@ const debugConfigProps = (config) => {
119
119
  }
120
120
  const checkProps = [
121
121
  { property: 'priorities', check: (v) => debugPriority(v) },
122
- { property: 'association', check: (v) => debugAssociation(v) },
123
- { property: 'words', check: (v) => debugAssociation(v) },
122
+ { property: 'associations', check: (v) => debugAssociation(v) },
123
+ // TODO implement debugWords
124
+ { property: 'words', check: (v) => debugWords(v) },
124
125
  { property: 'hierarchy', check: (v) => debugHierarchy(v) },
125
126
  { property: 'operators', check: (v) => debugOperator(v) },
126
127
  { property: 'bridges', check: (v) => debugBridge(v) }
127
128
  ]
128
129
  for (const { property, check } of checkProps) {
129
- if (property == 'words') {
130
+ if (property == 'associations') {
131
+ if (config[property]) {
132
+ if (config[property].negative) {
133
+ for (const value of config[property].negative) {
134
+ check(value)
135
+ }
136
+ }
137
+ if (config[property].positive) {
138
+ for (const value of config[property].positive) {
139
+ check(value)
140
+ }
141
+ }
142
+ }
143
+ } else if (property == 'words') {
144
+ /*
130
145
  if (config[property]) {
131
- for (const value in config[property].literals) {
146
+ for (const value of config[property].literals) {
132
147
  check(value)
133
148
  }
134
149
  }
150
+ */
135
151
  } else if (config[property]) {
136
152
  for (const value of config[property]) {
137
153
  check(value)
@@ -173,6 +189,13 @@ const validConfigProps = (config) => {
173
189
  'eqClasses'
174
190
  ]
175
191
  helpers.validProps(valid, config, 'config')
192
+
193
+ // TODO add more type checks
194
+ if (config.associations) {
195
+ if (!config.associations.positive && !config.associations.negative) {
196
+ throw new Error(`Expected the 'associations' property to be a hash with 'positive' and or 'negative' properties`)
197
+ }
198
+ }
176
199
  }
177
200
 
178
201
  const setupInitializerFNArgs = (config, args) => {
@@ -261,7 +284,7 @@ const handleBridgeProps = (config, bridge, { addFirst, uuid } = {}) => {
261
284
  if (bridge.development && config.isModule) {
262
285
  return
263
286
  }
264
- if (!bridge.bridge) {
287
+ if (false && !bridge.bridge) {
265
288
  bridge.bridge = '{ ...next(operator) }'
266
289
  }
267
290
  if (!bridge.level) {
@@ -561,7 +584,7 @@ const normalizeConfig = (config) => {
561
584
  if (!bridge.level) {
562
585
  bridge.level = 0
563
586
  }
564
- if (!bridge.bridge) {
587
+ if (false && !bridge.bridge) {
565
588
  bridge.bridge = '{ ...next(operator) }'
566
589
  }
567
590
  }
@@ -1172,7 +1195,7 @@ class Config {
1172
1195
  delete bridge.evaluators
1173
1196
  delete bridge.semantic
1174
1197
  delete bridge.semantics
1175
- if (!bridge.bridge) {
1198
+ if (false && !bridge.bridge) {
1176
1199
  bridge.bridge = '{ ...next(operator) }'
1177
1200
  }
1178
1201
  return bridge
@@ -1305,7 +1328,7 @@ class Config {
1305
1328
  // TODO fix beforeQuery
1306
1329
  template = { fragments: [], configs: [], ...template }
1307
1330
  template.fragments = template.fragments.concat(this.dynamicFragments)
1308
- await rebuildTemplate({ config: this, target: this.name, previousResultss: options.previousResultss, startOfChanges: options.startOfChanges, beforeQuery: () => {}, template, ...options })
1331
+ await rebuildTemplate({ config: this, instance, target: this.name, startOfChanges: options.startOfChanges, beforeQuery: () => {}, template, ...options, previousResultss: options.previousResultss || instance.resultss })
1309
1332
  } else {
1310
1333
  // no change
1311
1334
  // this.initInstances.push({ ...instance, name: config.name })
package/src/helpers.js CHANGED
@@ -27,6 +27,28 @@ function where (goUp = 2) {
27
27
  }
28
28
  }
29
29
 
30
+ function suggestAssociationsFix(esummary, asummary) {
31
+ for (let isummary = 0; isummary < esummary.length; ++isummary) {
32
+ if (!deepEqual(esummary[isummary], asummary[isummary])) {
33
+ return esummary[isummary].operators
34
+ }
35
+ }
36
+ return []
37
+ }
38
+
39
+ function suggestAssociationsFixFromSummaries(esummaries, asummaries) {
40
+ for (let isummaries = 0; isummaries < esummaries.length; ++isummaries) {
41
+ const esummary = esummaries[isummaries].summaries
42
+ const asummary = asummaries[isummaries].summaries
43
+ for (let isummary = 0; isummary < esummary.length; ++isummary) {
44
+ if (!deepEqual(esummary[isummary], asummary[isummary])) {
45
+ return esummary[isummary].operators
46
+ }
47
+ }
48
+ }
49
+ return []
50
+ }
51
+
30
52
  function w (func) {
31
53
  func.where = where(3)
32
54
  return func
@@ -437,5 +459,7 @@ module.exports = {
437
459
  sortJson,
438
460
  subPriority,
439
461
  where,
440
- w
462
+ w,
463
+ suggestAssociationsFix,
464
+ suggestAssociationsFixFromSummaries,
441
465
  }