theprogrammablemind 7.6.0 → 7.7.0-beta.0
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 +115 -67
- package/package.json +1 -1
- package/runtime.js +1 -0
- package/src/config.js +1 -7
- package/src/flatten.js +3 -0
- package/src/generators.js +112 -122
- package/src/helpers.js +41 -1
- package/src/project.js +3 -1
package/client.js
CHANGED
@@ -173,22 +173,32 @@ const setupArgs = (args, config, logs, hierarchy) => {
|
|
173
173
|
args.theDebugger = {
|
174
174
|
breakOnSemantics: (value) => args.breakOnSemantics = value
|
175
175
|
}
|
176
|
-
args.s = (c) => config.getSemantics(logs).apply(args, c)
|
177
|
-
args.g = (c) => config.getGenerators(logs).apply(args, c)
|
178
|
-
args.gp = (c) => config.getGenerators(logs).apply(args, { ...c, paraphrase: true, isResponse: false, response: false})
|
179
|
-
args.gr = (c) => config.getGenerators(logs).apply(args, { ...c, paraphrase: false, isResponse: true })
|
180
176
|
if (!logs) {
|
181
177
|
debugger
|
182
178
|
}
|
183
|
-
args.e = (c) => config.getEvaluator(args.s, args.calls, logs, c)
|
184
179
|
args.log = (message) => logs.push(message)
|
185
|
-
|
186
|
-
args.
|
187
|
-
|
180
|
+
|
181
|
+
args.addAssumedScoped = (args, assumed) => {
|
182
|
+
args.s = (c) => config.getSemantics(logs).apply(args, c)
|
183
|
+
args.g = (c) => config.getGenerators(logs).apply(args, c)
|
184
|
+
args.gp = (c) => config.getGenerators(logs).apply({...args, assumed: {paraphrase: true, isResponse: false, response: false}}, c, {paraphrase: true, isResponse: false, response: false})
|
185
|
+
args.gr = (c) => config.getGenerators(logs).apply({...args, assumed: {paraphrase: false, isResponse: true}}, { ...c, paraphrase: false, isResponse: true })
|
186
|
+
args.e = (c) => config.getEvaluator(args.s, args.calls, logs, c)
|
187
|
+
args.gs = gs(args.g)
|
188
|
+
args.gsp = gs(args.gp)
|
189
|
+
args.gsr = gs(args.gr)
|
190
|
+
}
|
191
|
+
// for semantics
|
192
|
+
args.addAssumedScoped(args, {})
|
188
193
|
config.getAddedArgs(args)
|
189
194
|
}
|
190
195
|
|
191
196
|
const gs = (g) => (contexts, separator, lastSeparator) => {
|
197
|
+
if (!Array.isArray(contexts)) {
|
198
|
+
debugger
|
199
|
+
throw new Error("Expected a list")
|
200
|
+
}
|
201
|
+
|
192
202
|
let s = ''
|
193
203
|
if (!separator) {
|
194
204
|
separator = ' '
|
@@ -276,8 +286,9 @@ const processContext = (context, { objects = {}, config, logs = [] }) => {
|
|
276
286
|
setupArgs(args, config, logs, hierarchy)
|
277
287
|
|
278
288
|
context = semantics.apply(args, context)
|
279
|
-
const generated = generators.apply(args, context)
|
280
|
-
const
|
289
|
+
const generated = generators.apply(args, context)
|
290
|
+
const assumed = { paraphrase: true, response: false, isResponse: false }
|
291
|
+
const paraphrases = generators.apply({...args, assumed}, context, { paraphrase: true, response: false, isResponse: false })
|
281
292
|
let responses = []
|
282
293
|
if (context.isResponse) {
|
283
294
|
responses = generated
|
@@ -447,37 +458,29 @@ const processContextsB = ({ config, hierarchy, semantics, generators, json, isTe
|
|
447
458
|
continue
|
448
459
|
}
|
449
460
|
let assumed = { isResponse: true };
|
450
|
-
const generated = contextPrime.isResponse ? config.getGenerators(json.logs).apply(args, contextPrime, assumed)
|
461
|
+
const generated = contextPrime.isResponse ? config.getGenerators(json.logs).apply({...args, assumed}, contextPrime, assumed) : ''
|
451
462
|
let generatedParenthesized = []
|
452
463
|
if (generateParenthesized) {
|
453
464
|
config.parenthesized = true
|
454
|
-
generatedParenthesized = contextPrime.isResponse ? config.getGenerators(json.logs).apply(args, contextPrime, assumed)
|
465
|
+
generatedParenthesized = contextPrime.isResponse ? config.getGenerators(json.logs).apply({...args, assumed}, contextPrime, assumed) : ''
|
455
466
|
config.parenthesized = false
|
456
467
|
}
|
457
468
|
// assumed = { paraphrase: true, response: false };
|
458
|
-
assumed = { paraphrase: true };
|
459
|
-
args.g = (c) => config.getGenerators(json.logs).apply(args, c, assumed)
|
460
|
-
args.
|
461
|
-
args.gr = (c) => config.getGenerators(json.logs).apply(args, {...c, paraphrase: false }, assumed)
|
462
|
-
args.gs = gs(args.g)
|
463
|
-
args.gsp = gs(args.gsp)
|
464
|
-
args.gsr = gs(args.gr)
|
469
|
+
assumed = { paraphrase: true, isResponse: false, response: false };
|
470
|
+
// args.g = (c) => config.getGenerators(json.logs).apply({...args, assumed}, c, assumed)
|
471
|
+
// args.gs = gs(args.g)
|
465
472
|
if (generateParenthesized) {
|
466
473
|
config.parenthesized = false
|
467
474
|
}
|
468
|
-
const paraphrases = config.getGenerators(json.logs).apply(args, contextPrime, assumed)
|
475
|
+
const paraphrases = config.getGenerators(json.logs).apply({...args, assumed}, contextPrime, assumed)
|
469
476
|
let paraphrasesParenthesized = []
|
470
477
|
if (generateParenthesized) {
|
471
478
|
config.parenthesized = true
|
472
|
-
paraphrasesParenthesized = config.getGenerators(json.logs).apply(args, contextPrime, assumed)
|
479
|
+
paraphrasesParenthesized = config.getGenerators(json.logs).apply({...args, assumed}, contextPrime, assumed)
|
473
480
|
config.parenthesized = false
|
474
481
|
}
|
475
|
-
args.g = (c) => config.getGenerators(json.logs).apply(args, c)
|
476
|
-
args.
|
477
|
-
args.gr = (c) => config.getGenerators(json.logs).apply(args, {...c, paraphrase: false })
|
478
|
-
args.gs = gs(args.g)
|
479
|
-
args.gsp = gs(args.gp)
|
480
|
-
args.gsr = gs(args.gr)
|
482
|
+
// args.g = (c) => config.getGenerators(json.logs).apply(args, c)
|
483
|
+
// args.gs = gs(args.g)
|
481
484
|
contextsPrime.push(contextPrime)
|
482
485
|
generatedPrime.push(generated)
|
483
486
|
paraphrasesPrime.push(paraphrases)
|
@@ -660,6 +663,7 @@ const _process = async (config, query, { initializer, commandLineArgs, credentia
|
|
660
663
|
opChoices: []
|
661
664
|
},
|
662
665
|
times: 0.0,
|
666
|
+
clientSideTimes: 0.0,
|
663
667
|
trace: '',
|
664
668
|
contexts: [],
|
665
669
|
generated: [],
|
@@ -701,8 +705,16 @@ const _process = async (config, query, { initializer, commandLineArgs, credentia
|
|
701
705
|
if (json.status !== 200) {
|
702
706
|
throw json
|
703
707
|
} else {
|
708
|
+
let clientSideTime
|
709
|
+
if (isTest) {
|
710
|
+
start = runtime.performance.performance.now()
|
711
|
+
}
|
704
712
|
const { contextsPrime, generatedPrime, paraphrasesPrime, paraphrasesParenthesizedPrime, generatedParenthesizedPrime, responsesPrime } =
|
705
713
|
processContextsB({ isTest, config, hierarchy, json, commandLineArgs /*, generators, semantics */ })
|
714
|
+
if (isTest) {
|
715
|
+
end = runtime.performance.performance.now()
|
716
|
+
clientSideTime = end - start
|
717
|
+
}
|
706
718
|
response.associations = json.associations
|
707
719
|
response.learned_contextual_priorities = json.learned_contextual_priorities
|
708
720
|
response.hierarchy = json.hierarchy
|
@@ -713,6 +725,7 @@ const _process = async (config, query, { initializer, commandLineArgs, credentia
|
|
713
725
|
// appendNoDups(response.metadata.priorities, json.metadata.priorities)
|
714
726
|
appendNoDups(response.metadata.opChoices, json.metadata.opChoices)
|
715
727
|
response.times += json.times
|
728
|
+
response.clientSideTimes += clientSideTime
|
716
729
|
response.trace = response.trace.concat(json.trace)
|
717
730
|
response.version = json.version
|
718
731
|
response.explain_priorities = json.explain_priorities
|
@@ -778,10 +791,6 @@ const runTest = async (config, expected, { args, verbose, testConfig, debug }) =
|
|
778
791
|
const test = expected.query
|
779
792
|
// initialize in between test so state is not preserved since the test was adding without state
|
780
793
|
config.rebuild()
|
781
|
-
if (!args.dontAddAssociations) {
|
782
|
-
config.addAssociationsFromTests(config.tests)
|
783
|
-
}
|
784
|
-
// config.addAssocationsFromTests(
|
785
794
|
const errorHandler = (error) => {
|
786
795
|
if (error.metadata) {
|
787
796
|
const priorities = analyzeMetaData(expected.metadata, error.metadata)
|
@@ -806,10 +815,10 @@ const runTest = async (config, expected, { args, verbose, testConfig, debug }) =
|
|
806
815
|
defaultInnerProcess(config, errorHandler, result)
|
807
816
|
}
|
808
817
|
if (verbose) {
|
809
|
-
const widths = [100,
|
818
|
+
const widths = [100, 60]
|
810
819
|
const lines = new Lines(widths)
|
811
820
|
lines.setElement(0, 0, test)
|
812
|
-
lines.setElement(0, 1, `time on server ${result.times.toFixed(2)}`)
|
821
|
+
lines.setElement(0, 1, `time on server: ${result.times.toFixed(2)} client: ${(result.clientSideTimes/1000).toFixed(2)}`)
|
813
822
|
lines.log()
|
814
823
|
}
|
815
824
|
const expected_objects = sortJson(convertToStable(expected.objects), { depth: 25 })
|
@@ -1173,7 +1182,7 @@ const defaultInnerProcess = (config, errorHandler, responses) => {
|
|
1173
1182
|
}
|
1174
1183
|
|
1175
1184
|
if (responses.explain_priorities) {
|
1176
|
-
console.log("Explain Priorities")
|
1185
|
+
console.log("Explain Priorities (listed from lower priority to higher priority)")
|
1177
1186
|
for ([inputss, outpus, reason] of responses.explain_priorities) {
|
1178
1187
|
console.log(` ${JSON.stringify(inputss)} reason: ${reason}`)
|
1179
1188
|
}
|
@@ -1274,6 +1283,7 @@ const rebuildTemplate = async ({ config, target, template, errorHandler = defaul
|
|
1274
1283
|
}
|
1275
1284
|
if (results.contexts.length > 1) {
|
1276
1285
|
console.log(`query "${query.query}". There is ${results.contexts.length} contexts in the results. Make sure its producing the results that you expect.`)
|
1286
|
+
throw new Error(`query "${query.query}". There is ${results.contexts.length} contexts in the results. Make sure its producing the results that you expect.`)
|
1277
1287
|
} else if (results.paraphrases[0] != query.query) {
|
1278
1288
|
console.log(`query "${query.query}". The paraphrase is different from the query "${results.paraphrases[0]}".`)
|
1279
1289
|
} else {
|
@@ -1299,14 +1309,18 @@ const rebuildTemplate = async ({ config, target, template, errorHandler = defaul
|
|
1299
1309
|
// it will just get added to the config
|
1300
1310
|
const extraConfig = queryOrExtraConfig
|
1301
1311
|
console.log('config', extraConfig)
|
1302
|
-
|
1303
|
-
|
1304
|
-
}
|
1305
|
-
|
1306
|
-
|
1312
|
+
if (extraConfig.stop) {
|
1313
|
+
await looper([])
|
1314
|
+
} else {
|
1315
|
+
try {
|
1316
|
+
config.addInternal(_.cloneDeep(extraConfig), { handleCalculatedProps: true } )
|
1317
|
+
} catch ( e ) {
|
1318
|
+
const where = extraConfig.where ? ` ${extraConfig.where}` : ''
|
1319
|
+
throw new Error(`Error processing extra config${where}: ${e.stack}}`)
|
1320
|
+
}
|
1321
|
+
accumulators[property].push({ extraConfig: true, ...extraConfig })
|
1322
|
+
await looper(queries)
|
1307
1323
|
}
|
1308
|
-
accumulators[property].push({ extraConfig: true, ...extraConfig })
|
1309
|
-
await looper(queries)
|
1310
1324
|
}
|
1311
1325
|
}
|
1312
1326
|
|
@@ -1327,6 +1341,7 @@ const rebuildTemplate = async ({ config, target, template, errorHandler = defaul
|
|
1327
1341
|
} else {
|
1328
1342
|
delete result.load_cache_time
|
1329
1343
|
delete result.times
|
1344
|
+
delete result.clientSideTimes
|
1330
1345
|
delete result.memory_free_percent
|
1331
1346
|
delete result.logs
|
1332
1347
|
delete result.version
|
@@ -1366,7 +1381,29 @@ const rebuildTemplate = async ({ config, target, template, errorHandler = defaul
|
|
1366
1381
|
await looper(Object.assign([], todo))
|
1367
1382
|
}
|
1368
1383
|
|
1369
|
-
const
|
1384
|
+
const checkTemplate = (template) => {
|
1385
|
+
return
|
1386
|
+
if (!template) {
|
1387
|
+
return
|
1388
|
+
}
|
1389
|
+
if (template.checks) {
|
1390
|
+
throw new Error("The 'checks' property should be in the 'test' property not the 'template' property")
|
1391
|
+
}
|
1392
|
+
}
|
1393
|
+
|
1394
|
+
const checkTest = (testConfig) => {
|
1395
|
+
if (!testConfig) {
|
1396
|
+
return
|
1397
|
+
}
|
1398
|
+
if (!testConfig.name) {
|
1399
|
+
throw new Error("The 'test' property is missing the 'name' property that contains the name of the '<km>.test.json' file")
|
1400
|
+
}
|
1401
|
+
if (!testConfig.contents) {
|
1402
|
+
throw new Error("The 'test' property is missing the 'contents' property that contains contents of the '<km>.test.json' file")
|
1403
|
+
}
|
1404
|
+
}
|
1405
|
+
|
1406
|
+
const knowledgeModuleImpl = async ({
|
1370
1407
|
module: moduleFromJSFile,
|
1371
1408
|
description,
|
1372
1409
|
section,
|
@@ -1399,9 +1436,10 @@ const knowledgeModule = async ({
|
|
1399
1436
|
if (!description) {
|
1400
1437
|
throw new Error("'description' is a required parameter. The value should the description of the knowledge module.")
|
1401
1438
|
}
|
1402
|
-
if (!
|
1439
|
+
if (!testConfig) {
|
1403
1440
|
throw new Error("'test' is a required parameter. The value should the path to the file used to store the tests of the knowledge module and the contents of the file in the form { name: <filePath>, contexts: <json> }.")
|
1404
1441
|
}
|
1442
|
+
checkTest(testConfig)
|
1405
1443
|
|
1406
1444
|
const isProcess = require.main === moduleFromJSFile
|
1407
1445
|
|
@@ -1466,7 +1504,6 @@ const knowledgeModule = async ({
|
|
1466
1504
|
parser.add_argument('--parenthesized', { action: 'store_true', help: 'Show the generated phrases with parenthesis.' })
|
1467
1505
|
parser.add_argument('-c', '--clean', { help: 'Remove data from the test files. a === association' })
|
1468
1506
|
parser.add_argument('-od', '--objectDiff', { action: 'store_true', help: 'When showing the objects use a colour diff' })
|
1469
|
-
parser.add_argument('-daa', '--dontAddAssociations', { action: 'store_true', help: 'Do not add associations from the tests.' })
|
1470
1507
|
parser.add_argument('-p', '--print', { help: 'Print the specified elements c === config, w === words, b === bridges, o === operators d === objects (d for data), h === hierarchy, g === generators, s === semantics, l === load t=tests ordering p === priorities a == associations j == JSON sent to server. for example --print wb' })
|
1471
1508
|
parser.add_argument('-s', '--save', { action: 'store_true', help: 'When running with the --query flag this will save the current run to the test file. When running without the --query flag all tests will be run and resaved.' })
|
1472
1509
|
parser.add_argument('-sd', '--saveDeveloper', { action: 'store_true', help: 'Same as -s but the query will not show up in the info command.' })
|
@@ -1671,6 +1708,8 @@ const knowledgeModule = async ({
|
|
1671
1708
|
}
|
1672
1709
|
}
|
1673
1710
|
|
1711
|
+
checkTemplate(template)
|
1712
|
+
|
1674
1713
|
if (template) {
|
1675
1714
|
const needsRebuild = config.needsRebuild(template.template, template.instance, options)
|
1676
1715
|
if (needsRebuild) {
|
@@ -1678,17 +1717,21 @@ const knowledgeModule = async ({
|
|
1678
1717
|
options.rebuild = true
|
1679
1718
|
config.config.rebuild = true
|
1680
1719
|
}
|
1681
|
-
|
1682
|
-
|
1720
|
+
try {
|
1721
|
+
config.load(template.template, template.instance, { rebuild: needsRebuild })
|
1722
|
+
} catch( e ) {
|
1723
|
+
debugger
|
1724
|
+
console.error(`Error loading template for ${config.name}. ${e.error ? e.error : e}`)
|
1725
|
+
runtime.process.exit(-1)
|
1726
|
+
}
|
1727
|
+
if (!args.query) {
|
1728
|
+
printConfig()
|
1729
|
+
}
|
1683
1730
|
if (needsRebuild) {
|
1684
1731
|
return
|
1685
1732
|
}
|
1686
1733
|
}
|
1687
1734
|
|
1688
|
-
if (!args.save && !args.rebuildTemplate && !args.dontAddAssociations) {
|
1689
|
-
config.addAssociationsFromTests(config.tests);
|
1690
|
-
}
|
1691
|
-
|
1692
1735
|
if (args.retrain) {
|
1693
1736
|
config.config.retrain = true
|
1694
1737
|
}
|
@@ -1696,7 +1739,6 @@ const knowledgeModule = async ({
|
|
1696
1739
|
if (args.test || args.testVerbose || args.testAllVerbose || args.save) {
|
1697
1740
|
global.transitoryMode = true
|
1698
1741
|
}
|
1699
|
-
|
1700
1742
|
if (!args.query && !args.test && !args.info && (args.save || args.saveDeveloper)) {
|
1701
1743
|
global.transitoryMode = true
|
1702
1744
|
saveTests(config, test, testConfig, args.saveDeveloper)
|
@@ -1718,7 +1760,6 @@ const knowledgeModule = async ({
|
|
1718
1760
|
useTestConfig = config.getConfigs()[args.testModuleName].getTestConfig()
|
1719
1761
|
useTestConfig.testModuleName = args.testModuleName
|
1720
1762
|
test = useTestConfig.name
|
1721
|
-
|
1722
1763
|
}
|
1723
1764
|
runTests(config, test, { args, debug: args.debug, testConfig: useTestConfig, verbose: args.testVerbose || args.testAllVerbose, stopAtFirstError: !args.testAllVerbose }).then((results) => {
|
1724
1765
|
let newError = false
|
@@ -1762,17 +1803,21 @@ const knowledgeModule = async ({
|
|
1762
1803
|
console.log(` actual ${label} `, actual)
|
1763
1804
|
newError = true
|
1764
1805
|
headerShown = true
|
1806
|
+
if (args.vimdiff) {
|
1807
|
+
vimdiff(result.actual.paraphrasesParenthesized, result.expected.paraphrasesParenthesized)
|
1808
|
+
}
|
1765
1809
|
}
|
1766
1810
|
}
|
1767
1811
|
show('paraphrases', result.expected.paraphrases, result.actual.paraphrases)
|
1768
1812
|
if (!args.testNoParenthesized) {
|
1769
1813
|
show('paraphrases parenthesized', result.expected.paraphrasesParenthesized, result.actual.paraphrasesParenthesized)
|
1770
1814
|
}
|
1815
|
+
/*
|
1816
|
+
}
|
1771
1817
|
show('responses', result.expected.responses, result.actual.responses)
|
1772
1818
|
if (!args.testNoParenthesized) {
|
1773
1819
|
show('responses parenthesized', result.expected.generatedParenthesized, result.actual.generatedParenthesized)
|
1774
1820
|
}
|
1775
|
-
/*
|
1776
1821
|
if (JSON.stringify(result.expected.paraphrases) !== JSON.stringify(result.actual.paraphrases)) {
|
1777
1822
|
if (!headerShown) {
|
1778
1823
|
console.log(' Failure')
|
@@ -1798,10 +1843,10 @@ const knowledgeModule = async ({
|
|
1798
1843
|
}
|
1799
1844
|
const widths = [4, 18, 72]
|
1800
1845
|
const lines = new Lines(widths)
|
1801
|
-
lines.setElement(1, 1, 'expected checked')
|
1846
|
+
lines.setElement(1, 1, 'expected checked objects')
|
1802
1847
|
lines.setElement(2, 2, JSON.stringify(result.expected.checked, null, 2))
|
1803
1848
|
lines.log()
|
1804
|
-
lines.setElement(1, 1, 'actual checked')
|
1849
|
+
lines.setElement(1, 1, 'actual checked objects')
|
1805
1850
|
lines.setElement(2, 2, JSON.stringify(result.actual.checked, null, 2))
|
1806
1851
|
lines.log()
|
1807
1852
|
if (args.vimdiff) {
|
@@ -1816,10 +1861,10 @@ const knowledgeModule = async ({
|
|
1816
1861
|
}
|
1817
1862
|
const widths = [4, 18, 72]
|
1818
1863
|
const lines = new Lines(widths)
|
1819
|
-
lines.setElement(1, 1, 'expected
|
1864
|
+
lines.setElement(1, 1, 'expected checked contexts', true)
|
1820
1865
|
lines.setElement(2, 2, JSON.stringify(result.expected.checkedContexts, null, 2))
|
1821
1866
|
lines.log()
|
1822
|
-
lines.setElement(1, 1, 'actual
|
1867
|
+
lines.setElement(1, 1, 'actual checked contexts', true)
|
1823
1868
|
lines.setElement(2, 2, JSON.stringify(result.actual.checkedContexts, null, 2))
|
1824
1869
|
lines.log()
|
1825
1870
|
if (args.vimdiff) {
|
@@ -1836,16 +1881,18 @@ const knowledgeModule = async ({
|
|
1836
1881
|
}
|
1837
1882
|
}
|
1838
1883
|
}
|
1839
|
-
if (
|
1884
|
+
if (hasError) {
|
1885
|
+
if (!headerShown) {
|
1886
|
+
if (!(useTestConfig.check && useTestConfig.check.length > 0)) {
|
1887
|
+
console.log('There are failures due to things other than paraphrases, responses and checked properties being different. They are not shown because you ran -tv or -tva which only shows difference in paraphrase and results. Usually what I do is -s and do a diff to make sure there are no other problems. If the paraphrases or results were different they would have shown here.')
|
1888
|
+
}
|
1889
|
+
}
|
1840
1890
|
if (!(useTestConfig.check && useTestConfig.check.length > 0)) {
|
1841
|
-
console.log('
|
1891
|
+
console.log('use -v arg to write files expected.json and actual.json in the current directory for detailed comparison. Or do -s and then git diff the changes.')
|
1892
|
+
// console.log(JSON.stringify(contexts))
|
1893
|
+
console.log('**************************** ERRORS ************************')
|
1842
1894
|
}
|
1843
1895
|
}
|
1844
|
-
if (!(useTestConfig.check && useTestConfig.check.length > 0)) {
|
1845
|
-
console.log('use -v arg to write files expected.json and actual.json in the current directory for detailed comparison. Or do -s and then git diff the changes.')
|
1846
|
-
// console.log(JSON.stringify(contexts))
|
1847
|
-
console.log('**************************** ERRORS ************************')
|
1848
|
-
}
|
1849
1896
|
}
|
1850
1897
|
// const contexts = { failures: results }
|
1851
1898
|
l(n - 1, hasError || newError)
|
@@ -1939,8 +1986,6 @@ const knowledgeModule = async ({
|
|
1939
1986
|
errorHandler(e)
|
1940
1987
|
}
|
1941
1988
|
}
|
1942
|
-
|
1943
|
-
config.addAssociationsFromTests(config.tests);
|
1944
1989
|
}
|
1945
1990
|
|
1946
1991
|
createConfigExport = () => {
|
@@ -1951,7 +1996,6 @@ const knowledgeModule = async ({
|
|
1951
1996
|
}
|
1952
1997
|
moduleFromJSFile.exports = createConfigExport
|
1953
1998
|
}
|
1954
|
-
|
1955
1999
|
}
|
1956
2000
|
|
1957
2001
|
/*
|
@@ -1999,6 +2043,10 @@ function w(func) {
|
|
1999
2043
|
return func
|
2000
2044
|
}
|
2001
2045
|
|
2046
|
+
const knowledgeModule = async (...args) => {
|
2047
|
+
await knowledgeModuleImpl(...args).catch((e) => console.error(e))
|
2048
|
+
}
|
2049
|
+
|
2002
2050
|
module.exports = {
|
2003
2051
|
process: _process,
|
2004
2052
|
where,
|
package/package.json
CHANGED
package/runtime.js
CHANGED
package/src/config.js
CHANGED
@@ -27,7 +27,7 @@ const config_toServer = (config) => {
|
|
27
27
|
|
28
28
|
const debugPriority = (priority) => {
|
29
29
|
if (global.entodictonDebugPriority) {
|
30
|
-
if (helpers.
|
30
|
+
if (helpers.subPriority(entodictonDebugPriority, priority)) {
|
31
31
|
debugger; // debug hierarchy hit
|
32
32
|
}
|
33
33
|
}
|
@@ -1137,12 +1137,6 @@ class Config {
|
|
1137
1137
|
return this.config.objects.namespaced[this._uuid]
|
1138
1138
|
}
|
1139
1139
|
|
1140
|
-
addAssociationsFromTests(tests = []) {
|
1141
|
-
for (let test of tests) {
|
1142
|
-
this.addAssociations(test.associations || []);
|
1143
|
-
}
|
1144
|
-
}
|
1145
|
-
|
1146
1140
|
addAssociations (associations) {
|
1147
1141
|
for (let association of associations) {
|
1148
1142
|
this.addAssociation(association)
|
package/src/flatten.js
CHANGED
package/src/generators.js
CHANGED
@@ -73,7 +73,8 @@ class Generator {
|
|
73
73
|
return matches
|
74
74
|
}
|
75
75
|
|
76
|
-
apply (baseArgs, objects, g, gs, context, hierarchy, config, response, log, options = {}) {
|
76
|
+
// apply (baseArgs, objects, g, gs, context, hierarchy, config, response, log, options = {}) {
|
77
|
+
apply (baseArgs, objects, context, hierarchy, config, response, log, options = {}) {
|
77
78
|
if (!log) {
|
78
79
|
throw new Error('generators.apply argument log is required')
|
79
80
|
}
|
@@ -103,12 +104,12 @@ class Generator {
|
|
103
104
|
log,
|
104
105
|
global:
|
105
106
|
objects,
|
106
|
-
g,
|
107
|
+
// g,
|
107
108
|
n,
|
108
109
|
hierarchy,
|
109
110
|
context,
|
110
111
|
uuid: this.uuid,
|
111
|
-
gs,
|
112
|
+
// gs,
|
112
113
|
config,
|
113
114
|
response,
|
114
115
|
api: this.getAPI(config),
|
@@ -165,136 +166,125 @@ class Generators {
|
|
165
166
|
this.logs = logs
|
166
167
|
};
|
167
168
|
|
168
|
-
// assumed - properties added to
|
169
|
-
apply (args,
|
169
|
+
// assumed - properties added to context before the generators are called. For setting paraphrase property
|
170
|
+
apply (args, context, assumed = {}, options = {}) {
|
171
|
+
if (Array.isArray(context)) {
|
172
|
+
throw new Error("Expected a context not an array")
|
173
|
+
}
|
174
|
+
if (typeof context !== 'object') {
|
175
|
+
return String(context)
|
176
|
+
}
|
177
|
+
|
170
178
|
const config = args.config
|
171
179
|
const objects = args.objects
|
172
180
|
const hierarchy = args.hierarchy
|
173
181
|
const response = args.response
|
174
|
-
if (Array.isArray(contexts)) {
|
175
|
-
// no-op
|
176
|
-
} else if (typeof contexts === 'object') {
|
177
|
-
contexts = [contexts]
|
178
|
-
} else {
|
179
|
-
return String(contexts)
|
180
|
-
}
|
181
182
|
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
const
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
const help = 'The error has a retryCall property that will recall the function that failed.'
|
211
|
-
if (e.stack && e.message) {
|
212
|
-
const info = `${generator.notes ? generator.notes : ''}${generator.where ? generator.where : ''}`
|
213
|
-
errorMessage = `Error applying generator '${info}. Error is ${e.toString()} stack is ${e.stack}. Generator is ${generator.toString()}. ${help}`
|
214
|
-
} else if (e.error) {
|
215
|
-
const info = `${generator.notes ? generator.notes : ''}${generator.where ? generator.where : ''}`
|
216
|
-
errorMessage = `Error applying generator '${info}. Error is ${e.error.join()}. Generator is ${generator.toString()}. ${help}`
|
217
|
-
} else {
|
218
|
-
errorMessage = e.toString()
|
219
|
-
}
|
183
|
+
|
184
|
+
// args = { ...args, ...args.getAssumedScoped(assumed) }
|
185
|
+
args.addAssumedScoped(args, assumed)
|
186
|
+
context = Object.assign({}, context, args.assumed)
|
187
|
+
let generated = ''
|
188
|
+
let applied = false
|
189
|
+
const stack = args.calls.push()
|
190
|
+
for (let igenerator = 0; igenerator < this.generators.length; ++igenerator) {
|
191
|
+
const generator = this.generators[igenerator]
|
192
|
+
if (generator.matches(args, objects, context, hierarchy, config, options)) {
|
193
|
+
const log = (message) => { this.logs.push(message) }
|
194
|
+
// this.logs.push(`Generators: applied ${generator.toString()}\n to\n ${JSON.stringify(context)}`)
|
195
|
+
let errorMessage = 'The apply function did not return a value'
|
196
|
+
try {
|
197
|
+
generated= generator.apply(args, objects, context, hierarchy, config, response, log)
|
198
|
+
} catch( e ) {
|
199
|
+
// the next if handle this
|
200
|
+
generated = null
|
201
|
+
e.retryCall = () => generator.apply(args, objects, context, hierarchy, config, response, log)
|
202
|
+
const help = 'The error has a retryCall property that will recall the function that failed.'
|
203
|
+
if (e.stack && e.message) {
|
204
|
+
const info = `${generator.notes ? generator.notes : ''}${generator.where ? generator.where : ''}`
|
205
|
+
errorMessage = `Error applying generator '${info}. Error is ${e.toString()} stack is ${e.stack}. Generator is ${generator.toString()}. ${help}`
|
206
|
+
} else if (e.error) {
|
207
|
+
const info = `${generator.notes ? generator.notes : ''}${generator.where ? generator.where : ''}`
|
208
|
+
errorMessage = `Error applying generator '${info}. Error is ${e.error.join()}. Generator is ${generator.toString()}. ${help}`
|
209
|
+
} else {
|
210
|
+
errorMessage = e.toString()
|
220
211
|
}
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
}
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
}
|
257
|
-
lines.newRow()
|
258
|
-
lines.setElement(0, 1, 'APPLIED')
|
212
|
+
}
|
213
|
+
if (!generated && generated !== '') {
|
214
|
+
const widths = [10, 10, 90]
|
215
|
+
const lines = new Lines(widths)
|
216
|
+
lines.setElement(0, 0, 'Generator')
|
217
|
+
const source = `${generator.km}/#${generator.index}`
|
218
|
+
lines.setElement(0, 2, `ERROR while applying (${source}) ${generator.toLabel()}`)
|
219
|
+
lines.newRow()
|
220
|
+
lines.setElement(0, 2, generator.toString())
|
221
|
+
lines.newRow()
|
222
|
+
lines.setElement(0, 1, 'TO')
|
223
|
+
lines.setElement(0, 2, `(HASHCODE ${helpers.hashCode(JSON.stringify(helpers.sortJson(context, { depth: 25 })))})`)
|
224
|
+
lines.setElement(1, 2, JSON.stringify(helpers.sortJson(context, { depth: 25 }), null, 2))
|
225
|
+
lines.newRow()
|
226
|
+
lines.setElement(0, 1, 'STACK')
|
227
|
+
lines.setElement(0, 2, stack)
|
228
|
+
lines.newRow()
|
229
|
+
lines.setElement(0, 1, 'DEBUG')
|
230
|
+
lines.setElement(0, 2, `To debug this use args.callId == '${args.calls.current()}'`)
|
231
|
+
lines.newRow()
|
232
|
+
lines.setElement(0, 1, 'ERROR')
|
233
|
+
lines.setElement(0, 2, errorMessage)
|
234
|
+
this.logs.push(lines.toString())
|
235
|
+
const message = `ERROR while applying (${source}) ${generator.toLabel()}\n to\n ${JSON.stringify(context, null, 2)}.\n${errorMessage}'`
|
236
|
+
// this.logs.push(message)
|
237
|
+
// return [message]
|
238
|
+
args.calls.pop()
|
239
|
+
throw { error: [message], logs: this.logs }
|
240
|
+
}
|
241
|
+
if (((config || {}).config || {}).debug) {
|
242
|
+
const widths = [10, 10, 90]
|
243
|
+
const lines = new Lines(widths)
|
244
|
+
lines.setElement(0, 0, 'Generator')
|
245
|
+
if (generator.index > -1 && generator.km) {
|
246
|
+
// lines.setElement(0, 2, `KM '${generator.km}' ordinal: ${generator.index}`)
|
259
247
|
lines.setElement(0, 2, generator.toLabel())
|
260
|
-
lines.newRow()
|
261
|
-
lines.setElement(0, 2, generator.toString())
|
262
|
-
lines.newRow()
|
263
|
-
lines.setElement(0, 1, 'RESULT')
|
264
|
-
lines.setElement(0, 2, generated)
|
265
|
-
lines.newRow()
|
266
|
-
lines.setElement(0, 1, 'STACK')
|
267
|
-
lines.setElement(0, 2, stack)
|
268
|
-
lines.newRow()
|
269
|
-
lines.setElement(0, 1, 'DEBUG')
|
270
|
-
lines.setElement(0, 2, `To debug this use args.callId == '${args.calls.current()}'`)
|
271
|
-
lines.newRow()
|
272
|
-
lines.setElement(0, 1, 'TO')
|
273
|
-
lines.setElement(0, 2, `(HASHCODE ${helpers.hashCode(JSON.stringify(helpers.sortJson(context, { depth: 25 })))})`)
|
274
|
-
lines.setElement(1, 2, JSON.stringify(helpers.sortJson(context, { depth: 25 }), null, 2))
|
275
|
-
this.logs.push(lines.toString())
|
276
248
|
}
|
277
|
-
|
278
|
-
|
249
|
+
lines.newRow()
|
250
|
+
lines.setElement(0, 1, 'APPLIED')
|
251
|
+
lines.setElement(0, 2, generator.toLabel())
|
252
|
+
lines.newRow()
|
253
|
+
lines.setElement(0, 2, generator.toString())
|
254
|
+
lines.newRow()
|
255
|
+
lines.setElement(0, 1, 'RESULT')
|
256
|
+
lines.setElement(0, 2, generated)
|
257
|
+
lines.newRow()
|
258
|
+
lines.setElement(0, 1, 'STACK')
|
259
|
+
lines.setElement(0, 2, stack)
|
260
|
+
lines.newRow()
|
261
|
+
lines.setElement(0, 1, 'DEBUG')
|
262
|
+
lines.setElement(0, 2, `To debug this use args.callId == '${args.calls.current()}'`)
|
263
|
+
lines.newRow()
|
264
|
+
lines.setElement(0, 1, 'TO')
|
265
|
+
lines.setElement(0, 2, `(HASHCODE ${helpers.hashCode(JSON.stringify(helpers.sortJson(context, { depth: 25 })))})`)
|
266
|
+
lines.setElement(1, 2, JSON.stringify(helpers.sortJson(context, { depth: 25 }), null, 2))
|
267
|
+
this.logs.push(lines.toString())
|
279
268
|
}
|
269
|
+
applied = true
|
270
|
+
break
|
280
271
|
}
|
281
|
-
args.calls.pop()
|
282
|
-
if (!applied && ((config || {}).config || {}).debug) {
|
283
|
-
const widths = [10, 10, 90]
|
284
|
-
const lines = new Lines(widths)
|
285
|
-
lines.setElement(0, 0, 'Generator')
|
286
|
-
lines.setElement(0, 2, 'No generator applied')
|
287
|
-
lines.newRow()
|
288
|
-
lines.setElement(0, 1, 'STACK')
|
289
|
-
lines.setElement(0, 2, stack)
|
290
|
-
lines.newRow()
|
291
|
-
lines.setElement(0, 1, 'TO')
|
292
|
-
lines.setElement(0, 2, JSON.stringify(context, null, 2))
|
293
|
-
this.logs.push(lines.toString())
|
294
|
-
}
|
295
|
-
contextsPrime.push((config || {}).parenthesized ? "(" + generated + ")" : generated)
|
296
272
|
}
|
297
|
-
|
273
|
+
args.calls.pop()
|
274
|
+
if (!applied && ((config || {}).config || {}).debug) {
|
275
|
+
const widths = [10, 10, 90]
|
276
|
+
const lines = new Lines(widths)
|
277
|
+
lines.setElement(0, 0, 'Generator')
|
278
|
+
lines.setElement(0, 2, 'No generator applied')
|
279
|
+
lines.newRow()
|
280
|
+
lines.setElement(0, 1, 'STACK')
|
281
|
+
lines.setElement(0, 2, stack)
|
282
|
+
lines.newRow()
|
283
|
+
lines.setElement(0, 1, 'TO')
|
284
|
+
lines.setElement(0, 2, JSON.stringify(context, null, 2))
|
285
|
+
this.logs.push(lines.toString())
|
286
|
+
}
|
287
|
+
return ((config || {}).parenthesized ? "(" + generated + ")" : generated)
|
298
288
|
}
|
299
289
|
}
|
300
290
|
|
package/src/helpers.js
CHANGED
@@ -334,6 +334,45 @@ const ecatch = (where, call) => {
|
|
334
334
|
}
|
335
335
|
}
|
336
336
|
|
337
|
+
const equalKey = (key1, key2) => {
|
338
|
+
return key1[0] == key2[0] && key1[1] == key2[1]
|
339
|
+
}
|
340
|
+
|
341
|
+
// matches for { context: ..., [ordered], choose: ... } exactely OR
|
342
|
+
// [ <id1>, <id2> ] - where id1 is chosen
|
343
|
+
const subPriority = (sub, sup) => {
|
344
|
+
if (Array.isArray(sub)) {
|
345
|
+
const subChoosen = sub[0]
|
346
|
+
const subOther = sub[1]
|
347
|
+
const hasChoosen = sup.choose.find( (index) => equalKey(sup.context[index], subChoosen)) != undefined
|
348
|
+
const hasOtherChosen = sup.choose.find( (index) => equalKey(sup.context[index], subOther)) != undefined
|
349
|
+
const hasOther = sup.context.find( (other) => equalKey(other, subOther) ) !== undefined
|
350
|
+
return !!(hasChoosen && hasOther) && !hasOtherChosen
|
351
|
+
}
|
352
|
+
|
353
|
+
if (!safeEquals([...sub.choose].sort(), [...sup.choose].sort())) {
|
354
|
+
return false
|
355
|
+
}
|
356
|
+
|
357
|
+
const choose = (priority) => {
|
358
|
+
const chosen = []
|
359
|
+
for (const i of priority.choose) {
|
360
|
+
chosen.push(priority.context[i])
|
361
|
+
}
|
362
|
+
return chosen
|
363
|
+
}
|
364
|
+
const chosen1 = choose(sub)
|
365
|
+
const chosen2 = choose(sup)
|
366
|
+
const sameId = (id1, id2) => id1[0] == id2[0] && id1[1] == id2[1]
|
367
|
+
// same length so only need one way
|
368
|
+
const missing1 = chosen1.find( (id1) => !chosen2.find( (id2) => sameId(id1, id2)) )
|
369
|
+
if (missing1) {
|
370
|
+
return false
|
371
|
+
}
|
372
|
+
|
373
|
+
return true
|
374
|
+
}
|
375
|
+
|
337
376
|
module.exports = {
|
338
377
|
ecatch,
|
339
378
|
functionsToStrings,
|
@@ -354,5 +393,6 @@ module.exports = {
|
|
354
393
|
isCompound,
|
355
394
|
InitCalls,
|
356
395
|
hashCode,
|
357
|
-
sortJson
|
396
|
+
sortJson,
|
397
|
+
subPriority,
|
358
398
|
}
|
package/src/project.js
CHANGED
@@ -16,6 +16,9 @@ const project = (object, filter) => {
|
|
16
16
|
return object.map( element => project(element, filter) )
|
17
17
|
} else {
|
18
18
|
for (let properties of filter) {
|
19
|
+
if (typeof properties == 'function') {
|
20
|
+
properties = properties(object)
|
21
|
+
}
|
19
22
|
if (typeof properties == 'object') {
|
20
23
|
if (properties.propertyLists) {
|
21
24
|
for (const propertyList in properties.propertyLists) {
|
@@ -45,7 +48,6 @@ const project = (object, filter) => {
|
|
45
48
|
if (properties.property) {
|
46
49
|
const property = properties.property
|
47
50
|
if (properties.isPropertyList) {
|
48
|
-
debugger
|
49
51
|
if (!Array.isArray(object[property])) {
|
50
52
|
return projection
|
51
53
|
}
|