theprogrammablemind 7.5.8-beta.9 → 7.5.8-beta.90
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 +367 -280
- package/index.js +1 -0
- package/lines.js +2 -2
- package/package.json +2 -1
- package/src/config.js +559 -262
- package/src/flatten.js +9 -1
- package/src/helpers.js +16 -5
- package/src/project.js +81 -0
- package/src/semantics.js +6 -1
package/client.js
CHANGED
@@ -2,6 +2,7 @@ const { Semantics, Semantic } = require('./src/semantics')
|
|
2
2
|
const { Generators, Generator } = require('./src/generators')
|
3
3
|
const DigraphInternal = require('./src/digraph_internal')
|
4
4
|
const Digraph = require('./src/digraph')
|
5
|
+
const { project } = require('./src/project')
|
5
6
|
const fetch = require('node-fetch')
|
6
7
|
const base64 = require('base-64')
|
7
8
|
const deepEqual = require('deep-equal')
|
@@ -9,20 +10,38 @@ const _ = require('lodash')
|
|
9
10
|
const stringify = require('json-stable-stringify')
|
10
11
|
const Lines = require('./lines')
|
11
12
|
const flattens = require('./src/flatten')
|
12
|
-
const { appendNoDups, InitCalls, updateQueries } = require('./src/helpers')
|
13
|
+
const { appendNoDups, InitCalls, updateQueries, safeNoDups } = require('./src/helpers')
|
13
14
|
const runtime = require('./runtime')
|
14
15
|
const sortJson = runtime.sortJson
|
15
16
|
|
17
|
+
const getConfig_getObjectsCheck = (testConfig) => {
|
18
|
+
return (testConfig.checks && testConfig.checks.objects) || []
|
19
|
+
}
|
20
|
+
|
21
|
+
const getConfig_getContextCheck = (testConfig) => {
|
22
|
+
return (testConfig.checks && testConfig.checks.context) || []
|
23
|
+
}
|
24
|
+
|
25
|
+
const pickContext = (testConfig) => (context) => {
|
26
|
+
return project(context, getConfig_getContextCheck(testConfig))
|
27
|
+
}
|
28
|
+
|
29
|
+
const pickObjects = (testConfig, objects) => {
|
30
|
+
return project(objects, getConfig_getObjectsCheck(testConfig))
|
31
|
+
}
|
32
|
+
|
16
33
|
const getAsk = (config) => (uuid) => (asks) => {
|
17
34
|
for (let ask of asks) {
|
18
|
-
config.
|
35
|
+
config.addSemantic({
|
19
36
|
uuid,
|
37
|
+
oneShot: true,
|
20
38
|
match: (args) => ask.matchr(args),
|
21
39
|
apply: (args) => ask.applyr(args)
|
22
40
|
})
|
23
41
|
}
|
24
|
-
config.
|
42
|
+
config.addSemantic({
|
25
43
|
uuid,
|
44
|
+
oneShot: true,
|
26
45
|
match: ({context}) => context.marker == 'controlEnd' || context.marker == 'controlBetween',
|
27
46
|
apply: (args) => {
|
28
47
|
for (let ask of asks) {
|
@@ -37,7 +56,7 @@ const getAsk = (config) => (uuid) => (asks) => {
|
|
37
56
|
}
|
38
57
|
}
|
39
58
|
if (matchq(args)) {
|
40
|
-
args.context.motivationKeep = true
|
59
|
+
// args.context.motivationKeep = true
|
41
60
|
args.context.verbatim = applyq(args)
|
42
61
|
args.context.isResponse = true;
|
43
62
|
delete args.context.controlRemove;
|
@@ -49,6 +68,12 @@ const getAsk = (config) => (uuid) => (asks) => {
|
|
49
68
|
})
|
50
69
|
}
|
51
70
|
|
71
|
+
const sameJSON = (json1, json2) => {
|
72
|
+
const sjson1 = sortJson(json1, { depth: 25 })
|
73
|
+
const sjson2 = sortJson(json2, { depth: 25 })
|
74
|
+
return JSON.stringify(sjson1) == JSON.stringify(sjson2)
|
75
|
+
}
|
76
|
+
|
52
77
|
const vimdiff = (actualJSON, expectedJSON) => {
|
53
78
|
const path = '.'
|
54
79
|
const actual = sortJson(actualJSON, { depth: 25 })
|
@@ -58,7 +83,6 @@ const vimdiff = (actualJSON, expectedJSON) => {
|
|
58
83
|
// console.log(`vimdiff ${path}/actual.json ${path}/expected.json`)
|
59
84
|
{
|
60
85
|
const editor = runtime.process.env.EDITOR || 'vimdiff'
|
61
|
-
debugger
|
62
86
|
// const child = runtime.child_process.spawn(editor, [`${path}/expected.json`, `${path}/actual.json`], { stdio: 'inherit' })
|
63
87
|
console.log(`${editor} ${path}/expected.json ${path}/actual.json`)
|
64
88
|
runtime.child_process.execSync(`${editor} ${path}/expected.json ${path}/actual.json`, {stdio: 'inherit'})
|
@@ -109,11 +133,12 @@ class ErrorReason extends Error {
|
|
109
133
|
|
110
134
|
const setupArgs = (args, config, logs, hierarchy) => {
|
111
135
|
config.setArgs(args)
|
112
|
-
args.calls = new InitCalls(config.name)
|
136
|
+
args.calls = new InitCalls(args.isInstance ? `${args.isInstance}#${config.name}` : config.name)
|
113
137
|
if (global.theprogrammablemind && global.theprogrammablemind.loadForTesting) {
|
114
138
|
args.calls = new InitCalls(Object.keys(global.theprogrammablemind.loadForTesting)[0])
|
115
139
|
}
|
116
140
|
args.km = (name) => config.getConfig(name)
|
141
|
+
args.api = (name) => config.getConfig(name).api
|
117
142
|
args.error = (context) => {
|
118
143
|
throw new ErrorReason(context)
|
119
144
|
}
|
@@ -124,6 +149,7 @@ const setupArgs = (args, config, logs, hierarchy) => {
|
|
124
149
|
args.listable = listable(hierarchy)
|
125
150
|
args.asList = asList
|
126
151
|
args.retry = () => { throw new RetryError() }
|
152
|
+
args.fragments = (query) => config.fragment(query)
|
127
153
|
const scopedAsk = getAsk(config)
|
128
154
|
|
129
155
|
const getAPI = (uuid) => {
|
@@ -143,7 +169,6 @@ const setupArgs = (args, config, logs, hierarchy) => {
|
|
143
169
|
apis: getAPIs(uuid)
|
144
170
|
}
|
145
171
|
}
|
146
|
-
args.motivation = (m) => config.addMotivation(m)
|
147
172
|
args.breakOnSemantics = false
|
148
173
|
args.theDebugger = {
|
149
174
|
breakOnSemantics: (value) => args.breakOnSemantics = value
|
@@ -157,10 +182,10 @@ const setupArgs = (args, config, logs, hierarchy) => {
|
|
157
182
|
}
|
158
183
|
args.e = (c) => config.getEvaluator(args.s, args.calls, logs, c)
|
159
184
|
args.log = (message) => logs.push(message)
|
160
|
-
// config.getAddedArgs(args)
|
161
185
|
args.gs = gs(args.g)
|
162
186
|
args.gsp = gs(args.gp)
|
163
187
|
args.gsr = gs(args.gr)
|
188
|
+
config.getAddedArgs(args)
|
164
189
|
}
|
165
190
|
|
166
191
|
const gs = (g) => (contexts, separator, lastSeparator) => {
|
@@ -298,7 +323,6 @@ const writeTest = (fn, query, objects, generated, paraphrases, responses, contex
|
|
298
323
|
}
|
299
324
|
associations.sort()
|
300
325
|
// tests[query] = sortJson({ paraphrases, responses, contexts, objects: convertToStable(objects), associations, metadata, config, developerTest: saveDeveloper }, { depth: 25 })
|
301
|
-
debugger
|
302
326
|
results = sortJson({
|
303
327
|
query,
|
304
328
|
paraphrases,
|
@@ -367,7 +391,7 @@ const setupContexts = (rawContexts) => {
|
|
367
391
|
return contexts
|
368
392
|
}
|
369
393
|
|
370
|
-
const processContextsB = ({ config, hierarchy, semantics, generators, json, isTest, query, data, retries, url, commandLineArgs }) => {
|
394
|
+
const processContextsB = ({ config, hierarchy, semantics, generators, json, isTest, isInstance, instance, query, data, retries, url, commandLineArgs }) => {
|
371
395
|
// TODO fix this name to contextsPrime
|
372
396
|
const contextsPrime = []
|
373
397
|
const generatedPrime = []
|
@@ -378,7 +402,7 @@ const processContextsB = ({ config, hierarchy, semantics, generators, json, isTe
|
|
378
402
|
const contexts = setupContexts(json.contexts)
|
379
403
|
|
380
404
|
const objects = config.get('objects')
|
381
|
-
const args = { objects, isResponse: true, response: json, isTest, getObjects: getObjects(objects) }
|
405
|
+
const args = { objects, isResponse: true, response: json, isTest, isInstance, getObjects: getObjects(objects), instance }
|
382
406
|
if (!json.logs) {
|
383
407
|
json.logs = []
|
384
408
|
}
|
@@ -389,28 +413,6 @@ const processContextsB = ({ config, hierarchy, semantics, generators, json, isTe
|
|
389
413
|
config.debugLoops = commandLineArgs && commandLineArgs.debugLoops
|
390
414
|
while (toDo.length > 0) {
|
391
415
|
const context = toDo.shift()
|
392
|
-
/*
|
393
|
-
if (false && query) {
|
394
|
-
if (config.wasChanged()) {
|
395
|
-
// process contexts that overlap
|
396
|
-
overlap = lastRange
|
397
|
-
} else {
|
398
|
-
config.watch()
|
399
|
-
}
|
400
|
-
if (overlap) {
|
401
|
-
if (overlaps(overlap, context)) {
|
402
|
-
// okay
|
403
|
-
query = query.slice(overlap.end+1)
|
404
|
-
data.utterance = query
|
405
|
-
const json = await doWithRetries(retries, url, data)
|
406
|
-
toDo = setupContexts(json.contexts).slice(1) // take off the start context
|
407
|
-
}
|
408
|
-
overlap = undefined
|
409
|
-
}
|
410
|
-
lastRange = context.range
|
411
|
-
}
|
412
|
-
*/
|
413
|
-
|
414
416
|
args.calls.next()
|
415
417
|
let contextPrime = context
|
416
418
|
context.topLevel = true
|
@@ -418,19 +420,27 @@ const processContextsB = ({ config, hierarchy, semantics, generators, json, isTe
|
|
418
420
|
if (json.has_errors) {
|
419
421
|
throw new Error('There are errors in the logs. Run with the -d flag and grep for Error')
|
420
422
|
}
|
423
|
+
const generateParenthesized = isTest || (commandLineArgs && commandLineArgs.save)
|
421
424
|
if (!config.get('skipSemantics')) {
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
425
|
+
const semantics = config.getSemantics(json.logs)
|
426
|
+
try {
|
427
|
+
contextPrime = semantics.apply(args, context)
|
428
|
+
} catch( e ) {
|
429
|
+
if (e.message == 'Maximum call stack size exceeded') {
|
430
|
+
const mostCalled = semantics.getMostCalled()
|
431
|
+
e.message += `\nThe most called semantic was:\nnotes: ${mostCalled.notes}\nmatch: ${mostCalled.matcher.toString()}\napply: ${mostCalled._apply.toString()}\n`
|
432
|
+
}
|
433
|
+
// contextPrime = semantics.apply(args, { marker: 'error', context, error: e })
|
434
|
+
if (isInstance) {
|
435
|
+
console.log('error', e.error)
|
433
436
|
}
|
437
|
+
contextPrime = semantics.apply(args, {
|
438
|
+
marker: 'error',
|
439
|
+
context,
|
440
|
+
text: e ? e.toString() : 'not available',
|
441
|
+
reason: e.reason,
|
442
|
+
error: e.stack || e.error
|
443
|
+
})
|
434
444
|
}
|
435
445
|
}
|
436
446
|
if (contextPrime.controlRemove) {
|
@@ -439,7 +449,7 @@ const processContextsB = ({ config, hierarchy, semantics, generators, json, isTe
|
|
439
449
|
let assumed = { isResponse: true };
|
440
450
|
const generated = contextPrime.isResponse ? config.getGenerators(json.logs).apply(args, contextPrime, assumed)[0] : ''
|
441
451
|
let generatedParenthesized = []
|
442
|
-
if (
|
452
|
+
if (generateParenthesized) {
|
443
453
|
config.parenthesized = true
|
444
454
|
generatedParenthesized = contextPrime.isResponse ? config.getGenerators(json.logs).apply(args, contextPrime, assumed)[0] : ''
|
445
455
|
config.parenthesized = false
|
@@ -452,12 +462,12 @@ const processContextsB = ({ config, hierarchy, semantics, generators, json, isTe
|
|
452
462
|
args.gs = gs(args.g)
|
453
463
|
args.gsp = gs(args.gsp)
|
454
464
|
args.gsr = gs(args.gr)
|
455
|
-
if (
|
465
|
+
if (generateParenthesized) {
|
456
466
|
config.parenthesized = false
|
457
467
|
}
|
458
468
|
const paraphrases = config.getGenerators(json.logs).apply(args, contextPrime, assumed)[0]
|
459
469
|
let paraphrasesParenthesized = []
|
460
|
-
if (
|
470
|
+
if (generateParenthesized) {
|
461
471
|
config.parenthesized = true
|
462
472
|
paraphrasesParenthesized = config.getGenerators(json.logs).apply(args, contextPrime, assumed)[0]
|
463
473
|
config.parenthesized = false
|
@@ -471,7 +481,7 @@ const processContextsB = ({ config, hierarchy, semantics, generators, json, isTe
|
|
471
481
|
contextsPrime.push(contextPrime)
|
472
482
|
generatedPrime.push(generated)
|
473
483
|
paraphrasesPrime.push(paraphrases)
|
474
|
-
if (
|
484
|
+
if (generateParenthesized) {
|
475
485
|
paraphrasesParenthesizedPrime.push(paraphrasesParenthesized)
|
476
486
|
generatedParenthesizedPrime.push(generatedParenthesized)
|
477
487
|
}
|
@@ -549,8 +559,11 @@ const setupProcessB = ({ config, initializer, allowDelta=false } = {}) => {
|
|
549
559
|
// console.log('config', config)
|
550
560
|
data.delta = config.delta()
|
551
561
|
} else {
|
552
|
-
|
562
|
+
config.toData(data)
|
563
|
+
// Object.assign(data, config.config)
|
553
564
|
}
|
565
|
+
|
566
|
+
// config.toServer(data)
|
554
567
|
|
555
568
|
if (data.namespaces) {
|
556
569
|
for (const uuid of Object.keys(data.namespaces)) {
|
@@ -573,10 +586,22 @@ const setupProcessB = ({ config, initializer, allowDelta=false } = {}) => {
|
|
573
586
|
}
|
574
587
|
}
|
575
588
|
|
576
|
-
// instance template
|
577
|
-
const
|
589
|
+
// instance template loadTemplate
|
590
|
+
const loadInstance = (config, instance) => {
|
578
591
|
const transitoryMode = global.transitoryMode
|
579
592
|
global.transitoryMode = false
|
593
|
+
|
594
|
+
if (instance && (instance.associations || instance.learned_contextual_priorities)) {
|
595
|
+
if (!config.config.retrain) {
|
596
|
+
if (instance.associations) {
|
597
|
+
config.addAssociations(instance.associations)
|
598
|
+
}
|
599
|
+
if (instance.learned_contextual_priorities && instance.learned_contextual_priorities.length > 0) {
|
600
|
+
config.addPriorities(instance.learned_contextual_priorities)
|
601
|
+
}
|
602
|
+
}
|
603
|
+
}
|
604
|
+
|
580
605
|
const { /* data, generators, semantics, */ hierarchy } = setupProcessB({ config })
|
581
606
|
// for (const results of (instance.resultss || [])) {
|
582
607
|
for (const i in (instance.resultss || [])) {
|
@@ -584,15 +609,21 @@ const processInstance = (config, instance) => {
|
|
584
609
|
if (results.extraConfig) {
|
585
610
|
// config.addInternal(results, useOldVersion = true, skipObjects = false, includeNamespaces = true, allowNameToBeNull = false)
|
586
611
|
// config.addInternal(config.template.queries[i], { handleCalculatedProps: true } )
|
587
|
-
config.addInternal(instance.template.queries[i], { handleCalculatedProps: true } )
|
612
|
+
config.addInternal(instance.template.queries[i], { addFirst: true, handleCalculatedProps: true } )
|
588
613
|
} else {
|
589
|
-
|
614
|
+
if (results.skipSemantics) {
|
615
|
+
config.config.skipSemantics = results.skipSemantics
|
616
|
+
}
|
617
|
+
processContextsB({ config, hierarchy, json: results/*, generators, semantics */, commandLineArgs: {}, isInstance: `instance${i}`, instance: instance.queries[i] })
|
618
|
+
if (results.skipSemantics) {
|
619
|
+
config.config.skipSemantics = null
|
620
|
+
}
|
590
621
|
}
|
591
622
|
}
|
592
623
|
global.transitoryMode = transitoryMode
|
593
624
|
}
|
594
625
|
|
595
|
-
const _process = async (config, query, { initializer, commandLineArgs, credentials, writeTests, isTest, saveDeveloper, testConfig, testsFN, errorHandler = defaultErrorHandler } = {}) => {
|
626
|
+
const _process = async (config, query, { initializer, commandLineArgs, credentials, writeTests, isTest, saveDeveloper, rebuildingTemplate, testConfig, testsFN, errorHandler = defaultErrorHandler } = {}) => {
|
596
627
|
if (credentials) {
|
597
628
|
config.server(credentials.server, credentials.key)
|
598
629
|
}
|
@@ -606,7 +637,6 @@ const _process = async (config, query, { initializer, commandLineArgs, credentia
|
|
606
637
|
if (writeTests) {
|
607
638
|
config.rebuild()
|
608
639
|
const objects = getObjects(config.config.objects)(config.uuid)
|
609
|
-
config.beforeQuery({ query, isModule: false, objects })
|
610
640
|
}
|
611
641
|
} catch(error) {
|
612
642
|
throw error
|
@@ -614,7 +644,10 @@ const _process = async (config, query, { initializer, commandLineArgs, credentia
|
|
614
644
|
|
615
645
|
let { data, /* generators, semantics, */ hierarchy } = setupProcessB({ config, initializer, allowDelta: true })
|
616
646
|
if (commandLineArgs && commandLineArgs.checkForLoop) {
|
617
|
-
data.checkForLoop =
|
647
|
+
data.checkForLoop = commandLineArgs.checkForLoop
|
648
|
+
}
|
649
|
+
if (rebuildingTemplate) {
|
650
|
+
data.errors_ignore_contextual_priorities_non_existant_ops = true
|
618
651
|
}
|
619
652
|
let queries = query.split('\\n')
|
620
653
|
|
@@ -671,6 +704,7 @@ const _process = async (config, query, { initializer, commandLineArgs, credentia
|
|
671
704
|
const { contextsPrime, generatedPrime, paraphrasesPrime, paraphrasesParenthesizedPrime, generatedParenthesizedPrime, responsesPrime } =
|
672
705
|
processContextsB({ isTest, config, hierarchy, json, commandLineArgs /*, generators, semantics */ })
|
673
706
|
response.associations = json.associations
|
707
|
+
response.learned_contextual_priorities = json.learned_contextual_priorities
|
674
708
|
response.hierarchy = json.hierarchy
|
675
709
|
response.load_cache_time += json.load_cache_time
|
676
710
|
appendNoDups(response.logs, json.logs)
|
@@ -681,6 +715,7 @@ const _process = async (config, query, { initializer, commandLineArgs, credentia
|
|
681
715
|
response.times += json.times
|
682
716
|
response.trace = response.trace.concat(json.trace)
|
683
717
|
response.version = json.version
|
718
|
+
response.explain_priorities = json.explain_priorities
|
684
719
|
|
685
720
|
response.contexts = response.contexts.concat(contextsPrime)
|
686
721
|
response.generated = response.generated.concat(generatedPrime)
|
@@ -694,7 +729,12 @@ const _process = async (config, query, { initializer, commandLineArgs, credentia
|
|
694
729
|
|
695
730
|
if (writeTests) {
|
696
731
|
const actual_config = getConfigForTest(config, testConfig)
|
697
|
-
|
732
|
+
const saveObjects = {...config.config.objects}
|
733
|
+
saveObjects.nameToUUID = {}
|
734
|
+
for (let km of config.configs) {
|
735
|
+
saveObjects.nameToUUID[km.name] = km.uuid
|
736
|
+
}
|
737
|
+
writeTest(testsFN, query, saveObjects, response.generated, response.paraphrases, response.responses, response.contexts, response.associations, response.metadata, actual_config, saveDeveloper, response.paraphrasesParenthesized, response.generatedParenthesized)
|
698
738
|
}
|
699
739
|
|
700
740
|
return response
|
@@ -734,7 +774,7 @@ const getConfigForTest = (config, testConfig) => {
|
|
734
774
|
return configForTest
|
735
775
|
}
|
736
776
|
|
737
|
-
const runTest = async (config, expected, { args, verbose,
|
777
|
+
const runTest = async (config, expected, { args, verbose, testConfig, debug }) => {
|
738
778
|
const test = expected.query
|
739
779
|
// initialize in between test so state is not preserved since the test was adding without state
|
740
780
|
config.rebuild()
|
@@ -759,8 +799,6 @@ const runTest = async (config, expected, { args, verbose, afterTest, testConfig,
|
|
759
799
|
objects = getObjects(config.config.objects)(config.getConfigs()[testConfig.testModuleName].uuid)
|
760
800
|
testConfigName = testConfig.testModuleName
|
761
801
|
}
|
762
|
-
config.beforeQuery({ query: test, isModule: false, objects })
|
763
|
-
// config.resetMotivations()
|
764
802
|
try {
|
765
803
|
const result = await _process(config, test, { errorHandler, isTest: true })
|
766
804
|
result.query = test
|
@@ -778,38 +816,29 @@ const runTest = async (config, expected, { args, verbose, afterTest, testConfig,
|
|
778
816
|
delete expected_objects.nameToUUID
|
779
817
|
const actual_objects = sortJson(convertToStable(config.config.objects), { depth: 25 })
|
780
818
|
const failed_paraphrases = !matching(result.paraphrases, expected.paraphrases)
|
781
|
-
|
782
|
-
|
819
|
+
let failed_paraphrasesParenthesized = !matching(result.paraphrasesParenthesized, expected.paraphrasesParenthesized)
|
820
|
+
let failed_generatedParenthesized = !matching(result.generatedParenthesized, expected.generatedParenthesized)
|
821
|
+
// TODO fix the naming conventions: camelcase + use actual instead of result
|
783
822
|
const failed_responses = !matching(result.responses, expected.responses)
|
784
823
|
const failed_contexts = !matching(result.contexts, expected.contexts)
|
785
824
|
const failed_objects = !matching(actual_objects, expected_objects)
|
786
825
|
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
if (prop.km) {
|
791
|
-
c = config.getConfig(prop.km)
|
792
|
-
o = getObjects(prop.km)
|
793
|
-
picked[prop.km] = {}
|
794
|
-
for (let p of c.testConfig.check) {
|
795
|
-
if (p.km) {
|
796
|
-
continue
|
797
|
-
}
|
798
|
-
picked[p] = o[p]
|
799
|
-
}
|
800
|
-
} else {
|
801
|
-
picked[prop] = getObjects(testConfigName)[prop]
|
802
|
-
}
|
803
|
-
}
|
804
|
-
return picked
|
826
|
+
if (args.testNoParenthesized) {
|
827
|
+
failed_paraphrasesParenthesized = false
|
828
|
+
failed_generatedParenthesized = false
|
805
829
|
}
|
830
|
+
|
831
|
+
const pickedResultContexts = result.contexts.map(pickContext(testConfig))
|
832
|
+
const pickedExpectedContexts = expected.contexts.map(pickContext(testConfig))
|
833
|
+
const failedCheckedContexts = !matching(pickedResultContexts, pickedExpectedContexts)
|
834
|
+
|
806
835
|
const expectedGetObjects = (name) => {
|
807
836
|
if (!name) {
|
808
837
|
name = config.name
|
809
838
|
}
|
810
839
|
return expected.objects.namespaced[expected.objects.nameToUUID[name]]
|
811
840
|
}
|
812
|
-
const expected_checked = sortJson(
|
841
|
+
const expected_checked = sortJson(pickObjects(testConfig, objects), { depth: 25 })
|
813
842
|
const actualGetObjects = (name) => {
|
814
843
|
if (!name) {
|
815
844
|
name = config.name
|
@@ -817,45 +846,14 @@ const runTest = async (config, expected, { args, verbose, afterTest, testConfig,
|
|
817
846
|
const km = config.configs.find( (km) => km.name == name )
|
818
847
|
return config.config.objects.namespaced[km.uuid]
|
819
848
|
}
|
820
|
-
const actual_checked = sortJson(
|
849
|
+
const actual_checked = sortJson(pickObjects(testConfig, actualGetObjects(testConfigName)), { depth: 25 })
|
821
850
|
const failed_checked = !matching(actual_objects, expected_objects)
|
822
851
|
|
823
852
|
const failed_checks = !matching(actual_objects, expected_objects)
|
824
853
|
const actual_config = sortJson(convertToStable(getConfigForTest(config, testConfig)), { depth: 25 })
|
825
854
|
const expected_config = sortJson(convertToStable(expected.config), { depth: 25 })
|
826
855
|
const failed_config = !matching(actual_config, expected_config)
|
827
|
-
let failed = failed_paraphrases || failed_paraphrasesParenthesized || failed_generatedParenthesized || failed_responses || failed_contexts || failed_objects || failed_config || failed_checked
|
828
|
-
if (!failed) {
|
829
|
-
if (config.afterTest) {
|
830
|
-
failed = config.afterTest({ query: test, expected, actual: result, config })
|
831
|
-
if (failed) {
|
832
|
-
return {
|
833
|
-
utterance: test,
|
834
|
-
errorFromAfterTest: failed,
|
835
|
-
expected: {
|
836
|
-
responses: expected.responses,
|
837
|
-
paraphrases: expected.paraphrases,
|
838
|
-
paraphrasesParenthesized: expected.paraphrasesParenthesized,
|
839
|
-
generatedParenthesized: expected.generatedParenthesized,
|
840
|
-
results: expected.contexts,
|
841
|
-
checked: expected_checked,
|
842
|
-
objects: expected_objects,
|
843
|
-
config: expected.config
|
844
|
-
},
|
845
|
-
actual: {
|
846
|
-
responses: result.responses,
|
847
|
-
paraphrases: result.paraphrases,
|
848
|
-
paraphrasesParenthesized: result.paraphrasesParenthesized,
|
849
|
-
generatedParenthesized: result.generatedParenthesized,
|
850
|
-
results: result.contexts,
|
851
|
-
checked: actual_checked,
|
852
|
-
objects: actual_objects,
|
853
|
-
config: actual_config
|
854
|
-
}
|
855
|
-
}
|
856
|
-
}
|
857
|
-
}
|
858
|
-
}
|
856
|
+
let failed = failed_paraphrases || failed_paraphrasesParenthesized || failed_generatedParenthesized || failed_responses || failed_contexts || failed_objects || failed_config || failed_checked || failedCheckedContexts
|
859
857
|
|
860
858
|
if (expected.metadata && result.metadata && failed) {
|
861
859
|
const priorities = analyzeMetaData(expected.metadata, result.metadata)
|
@@ -874,6 +872,7 @@ const runTest = async (config, expected, { args, verbose, afterTest, testConfig,
|
|
874
872
|
generatedParenthesized: expected.generatedParenthesized,
|
875
873
|
results: expected.contexts,
|
876
874
|
checked: expected_checked,
|
875
|
+
checkedContexts: pickedExpectedContexts,
|
877
876
|
objects: expected_objects,
|
878
877
|
config: expected.config
|
879
878
|
},
|
@@ -884,6 +883,7 @@ const runTest = async (config, expected, { args, verbose, afterTest, testConfig,
|
|
884
883
|
generatedParenthesized: result.generatedParenthesized,
|
885
884
|
results: result.contexts,
|
886
885
|
checked: actual_checked,
|
886
|
+
checkedContexts: pickedResultContexts,
|
887
887
|
objects: actual_objects,
|
888
888
|
config: actual_config
|
889
889
|
}
|
@@ -923,20 +923,16 @@ const runTestsHelper = async (config, tests, failed, juicyBits) => {
|
|
923
923
|
|
924
924
|
const runTests = async (config, testFile, juicyBits) => {
|
925
925
|
const tests = JSON.parse(runtime.fs.readFileSync(testFile))
|
926
|
-
config.beforeTests()
|
927
926
|
if (juicyBits.verbose) {
|
928
927
|
console.log('\n', testFile, '-----------------------------------------------', '\n')
|
929
928
|
}
|
930
929
|
const v = await runTestsHelper(config, [...tests], [], juicyBits)
|
931
|
-
config.afterTests()
|
932
930
|
return v
|
933
931
|
}
|
934
932
|
|
935
933
|
const saveTest = async (testFile, config, test, expected, testConfig, saveDeveloper) => {
|
936
934
|
config.rebuild()
|
937
935
|
const objects = getObjects(config.config.objects)(config.uuid)
|
938
|
-
//config.resetMotivations()
|
939
|
-
config.beforeQuery({ query: test, isModule: false, objects })
|
940
936
|
console.log(test)
|
941
937
|
const result = await _process(config, test, { isTest: true })
|
942
938
|
// const actualObjects = config.config.objects
|
@@ -1118,10 +1114,11 @@ const defaultErrorHandler = async (error) => {
|
|
1118
1114
|
doErrorExit = true
|
1119
1115
|
}
|
1120
1116
|
|
1121
|
-
if (doErrorExit) {
|
1117
|
+
if (typeof runtime.process.exit == 'function' && doErrorExit) {
|
1122
1118
|
runtime.process.exit(-1)
|
1123
1119
|
}
|
1124
|
-
|
1120
|
+
|
1121
|
+
throw error
|
1125
1122
|
}
|
1126
1123
|
|
1127
1124
|
const defaultInnerProcess = (config, errorHandler, responses) => {
|
@@ -1131,6 +1128,13 @@ const defaultInnerProcess = (config, errorHandler, responses) => {
|
|
1131
1128
|
}
|
1132
1129
|
console.log("KM's loaded", config.configs.map((c) => c.name))
|
1133
1130
|
console.log('This is the global objects from running semantics:\n', config.objects)
|
1131
|
+
if (!_.isEmpty(responses.learned_contextual_priorities)) {
|
1132
|
+
console.log('\nThe learned contextual priorties are :\n')
|
1133
|
+
for (const lcp of responses.learned_contextual_priorities) {
|
1134
|
+
console.log(` ${JSON.stringify(lcp)},\n`)
|
1135
|
+
}
|
1136
|
+
console.log("\n")
|
1137
|
+
}
|
1134
1138
|
if (responses.logs) {
|
1135
1139
|
console.log('Logs')
|
1136
1140
|
responses.logs.forEach((log) => console.log(` ${log}`))
|
@@ -1142,6 +1146,50 @@ const defaultInnerProcess = (config, errorHandler, responses) => {
|
|
1142
1146
|
} else {
|
1143
1147
|
console.log('objects', runtime.util.inspect(config.get('objects'), { depth: Infinity, sorted: true }))
|
1144
1148
|
}
|
1149
|
+
|
1150
|
+
const pickEm = () => {
|
1151
|
+
const picked = {}
|
1152
|
+
const namespaced = config.get('objects')['namespaced']
|
1153
|
+
for (let prop of getConfig_getObjectCheck(config.testConfig)) {
|
1154
|
+
if (prop.km) {
|
1155
|
+
/*
|
1156
|
+
const objects = namespaced[prop.km]]
|
1157
|
+
picked[prop.km] = {}
|
1158
|
+
for (let p of c.testConfig.check) {
|
1159
|
+
if (p.km) {
|
1160
|
+
continue
|
1161
|
+
}
|
1162
|
+
picked[p] = objects[p]
|
1163
|
+
}
|
1164
|
+
*/
|
1165
|
+
console.log('TODO implement this if needed')
|
1166
|
+
} else {
|
1167
|
+
const objects = namespaced[config.uuid]
|
1168
|
+
picked[prop] = objects[prop]
|
1169
|
+
}
|
1170
|
+
}
|
1171
|
+
return picked
|
1172
|
+
}
|
1173
|
+
|
1174
|
+
if (responses.explain_priorities) {
|
1175
|
+
console.log("Explain Priorities")
|
1176
|
+
for ([inputss, outpus, reason] of responses.explain_priorities) {
|
1177
|
+
console.log(` ${JSON.stringify(inputss)} reason: ${reason}`)
|
1178
|
+
}
|
1179
|
+
}
|
1180
|
+
const objects = config.get('objects').namespaced[config.uuid]
|
1181
|
+
const picked = sortJson(pickObjects(config.testConfig, objects), { depth: 25 })
|
1182
|
+
if (!_.isEmpty(picked)) {
|
1183
|
+
console.log('--- Object showing only the checked values ---')
|
1184
|
+
console.log(JSON.stringify(picked, null, 2))
|
1185
|
+
}
|
1186
|
+
|
1187
|
+
const pickedResultContexts = responses.contexts.map(pickContext(config.testConfig))
|
1188
|
+
if (pickedResultContexts.some( (context) => Object.keys(context).length > 0 )) {
|
1189
|
+
console.log('--- Contexts showing only the checked values ---')
|
1190
|
+
console.log(JSON.stringify(pickedResultContexts, null, 2))
|
1191
|
+
}
|
1192
|
+
|
1145
1193
|
console.log('--- The contexts are ----------')
|
1146
1194
|
console.log(JSON.stringify(sortJson(responses.contexts, { depth: 25 }), null, 2))
|
1147
1195
|
console.log('')
|
@@ -1182,37 +1230,14 @@ const defaultProcess = ({ config, errorHandler }) => async (promise) => {
|
|
1182
1230
|
}
|
1183
1231
|
}
|
1184
1232
|
|
1185
|
-
|
1186
|
-
const
|
1187
|
-
`const entodicton = require('entodicton')
|
1188
|
-
const base = require('./${kmBaseName}').copy()
|
1189
|
-
const ${kmName}_tests = require('./${kmName}.test.json')
|
1190
|
-
const ${kmName}_instance = require('./${kmBaseName}.${kmName}.instance.json')
|
1191
|
-
|
1192
|
-
const config = new entodicton.Config({ name: '${kmName}' })
|
1193
|
-
config.add(base)
|
1194
|
-
kirk_instance.base = '${kmBaseName}'
|
1195
|
-
config.load(${kmName}_instance)
|
1196
|
-
|
1197
|
-
entodicton.knowledgeModule( {
|
1198
|
-
module,
|
1199
|
-
description: '${kmName} related concepts',
|
1200
|
-
section,
|
1201
|
-
config,
|
1202
|
-
test: {
|
1203
|
-
name: './${kmName}.test.json',
|
1204
|
-
contents: ${kmName}_tests
|
1205
|
-
},
|
1206
|
-
})
|
1207
|
-
`
|
1208
|
-
*/
|
1209
|
-
|
1210
|
-
const build = async ({ config, target, template, errorHandler = defaultErrorHandler }) => {
|
1233
|
+
// builtTemplate saveInstance
|
1234
|
+
const rebuildTemplate = async ({ config, target, template, errorHandler = defaultErrorHandler }) => {
|
1211
1235
|
const accumulators = {
|
1212
1236
|
resultss: [],
|
1213
1237
|
fragments: [],
|
1214
1238
|
semantics: [],
|
1215
1239
|
associations: [],
|
1240
|
+
learned_contextual_priorities: [],
|
1216
1241
|
}
|
1217
1242
|
const looper = async (queries) => {
|
1218
1243
|
if (queries.length === 0) {
|
@@ -1231,8 +1256,6 @@ const build = async ({ config, target, template, errorHandler = defaultErrorHand
|
|
1231
1256
|
if (property == 'fragments') {
|
1232
1257
|
global.transitoryMode = true
|
1233
1258
|
}
|
1234
|
-
// greg32
|
1235
|
-
// config.addInternal( query )
|
1236
1259
|
if (hierarchy) {
|
1237
1260
|
for (let edge of hierarchy) {
|
1238
1261
|
if (Array.isArray(edge)) {
|
@@ -1242,9 +1265,8 @@ const build = async ({ config, target, template, errorHandler = defaultErrorHand
|
|
1242
1265
|
}
|
1243
1266
|
}
|
1244
1267
|
}
|
1245
|
-
|
1246
1268
|
try {
|
1247
|
-
const results = await _process(config, query.query, {initializer})
|
1269
|
+
const results = await _process(config, query.query, {initializer, rebuildingTemplate: true})
|
1248
1270
|
if (config.config.debug) {
|
1249
1271
|
// TODO pass in the error handler like the other ones
|
1250
1272
|
defaultInnerProcess(config, defaultErrorHandler, results)
|
@@ -1259,10 +1281,12 @@ const build = async ({ config, target, template, errorHandler = defaultErrorHand
|
|
1259
1281
|
global.transitoryMode = transitoryMode
|
1260
1282
|
config.config.skipSemantics = null
|
1261
1283
|
results.query = query.query
|
1284
|
+
results.skipSemantics = skipSemantics
|
1262
1285
|
results.development = query.development
|
1263
1286
|
results.key = { query: query.query, hierarchy }
|
1264
1287
|
accumulators[property].push(results)
|
1265
1288
|
accumulators.associations = accumulators.associations.concat(results.associations)
|
1289
|
+
accumulators.learned_contextual_priorities = accumulators.learned_contextual_priorities.concat(results.learned_contextual_priorities)
|
1266
1290
|
await looper(queries)
|
1267
1291
|
} catch(e) {
|
1268
1292
|
const error = { errors: [e], query: query.query };
|
@@ -1274,6 +1298,12 @@ const build = async ({ config, target, template, errorHandler = defaultErrorHand
|
|
1274
1298
|
// it will just get added to the config
|
1275
1299
|
const extraConfig = queryOrExtraConfig
|
1276
1300
|
console.log('config', extraConfig)
|
1301
|
+
try {
|
1302
|
+
config.addInternal(_.cloneDeep(extraConfig), { handleCalculatedProps: true } )
|
1303
|
+
} catch ( e ) {
|
1304
|
+
const where = extraConfig.where ? ` ${extraConfig.where}` : ''
|
1305
|
+
throw new Error(`Error processing extra config${where}: ${e.stack}}`)
|
1306
|
+
}
|
1277
1307
|
accumulators[property].push({ extraConfig: true, ...extraConfig })
|
1278
1308
|
await looper(queries)
|
1279
1309
|
}
|
@@ -1301,6 +1331,7 @@ const build = async ({ config, target, template, errorHandler = defaultErrorHand
|
|
1301
1331
|
delete result.version
|
1302
1332
|
result.hierarchy.sort()
|
1303
1333
|
stabilizeAssociations(result.associations)
|
1334
|
+
result.learned_contextual_priorities = safeNoDups(result.learned_contextual_priorities)
|
1304
1335
|
}
|
1305
1336
|
}
|
1306
1337
|
}
|
@@ -1321,14 +1352,14 @@ const build = async ({ config, target, template, errorHandler = defaultErrorHand
|
|
1321
1352
|
|
1322
1353
|
const toProperties = (queryStringOrProperties) => {
|
1323
1354
|
if (typeof queryStringOrProperties == 'string') {
|
1324
|
-
return { query: queryStringOrProperties}
|
1355
|
+
return { query: queryStringOrProperties }
|
1325
1356
|
} else {
|
1326
1357
|
return queryStringOrProperties
|
1327
1358
|
}
|
1328
1359
|
}
|
1329
1360
|
let todo = []
|
1330
|
-
todo = todo.concat((template.initializers || []).map((query) => { return { initializer: true, property: 'resultss', query, skipSemantics: false } }))
|
1331
|
-
todo = todo.concat((template.queries || []).map((query) => { return { property: 'resultss', query, skipSemantics: false } }))
|
1361
|
+
todo = todo.concat((template.initializers || []).map((query) => { return { initializer: true, property: 'resultss', query, skipSemantics: false || query.skipSemantics } }))
|
1362
|
+
todo = todo.concat((template.queries || []).map((query) => { return { property: 'resultss', query, skipSemantics: false || query.skipSemantics} }))
|
1332
1363
|
todo = todo.concat((template.fragments || []).map((query) => { return Object.assign({}, toProperties(query), { property: 'fragments', skipSemantics: false }) }))
|
1333
1364
|
todo = todo.concat((template.semantics || []).map((definition) => { return { property: 'semantics', query: `${definition.from}\n${definition.to}`, skipSemantics: true } }))
|
1334
1365
|
await looper(Object.assign([], todo))
|
@@ -1338,36 +1369,31 @@ const knowledgeModule = async ({
|
|
1338
1369
|
module: moduleFromJSFile,
|
1339
1370
|
description,
|
1340
1371
|
section,
|
1341
|
-
config,
|
1372
|
+
// config, createConfig,
|
1373
|
+
createConfig,
|
1374
|
+
newWay,
|
1342
1375
|
demo,
|
1343
1376
|
test,
|
1344
1377
|
template,
|
1345
1378
|
errorHandler = defaultErrorHandler,
|
1346
1379
|
process: processResults = defaultProcess,
|
1347
1380
|
stopAtFirstFailure = true,
|
1348
|
-
|
1349
|
-
beforeTests = () => {},
|
1350
|
-
afterTests = () => {},
|
1351
|
-
beforeTest = () => {},
|
1352
|
-
afterTest = () => {}
|
1381
|
+
...rest
|
1353
1382
|
} = {}) => {
|
1354
1383
|
|
1355
|
-
|
1356
|
-
|
1357
|
-
|
1358
|
-
|
1359
|
-
config.afterTest = afterTest
|
1384
|
+
const unknownArgs = Object.keys(rest)
|
1385
|
+
if (unknownArgs.length > 0) {
|
1386
|
+
throw new Error(`Unknown arguments to knowledgeModule: ${unknownArgs.join()}`)
|
1387
|
+
}
|
1360
1388
|
|
1361
1389
|
const testConfig = test
|
1362
1390
|
|
1363
1391
|
if (!moduleFromJSFile) {
|
1364
1392
|
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.")
|
1365
1393
|
}
|
1366
|
-
if (!config) {
|
1367
|
-
|
1368
|
-
|
1369
|
-
if (!config.name) {
|
1370
|
-
throw new Error("config must have 'name' set to the knowledge module name.")
|
1394
|
+
// if (!config && !createConfig) {
|
1395
|
+
if (!createConfig) {
|
1396
|
+
throw new Error("'config' or 'createConfig' is a required parameter. The value should the config that defines the knowledge module.")
|
1371
1397
|
}
|
1372
1398
|
if (!description) {
|
1373
1399
|
throw new Error("'description' is a required parameter. The value should the description of the knowledge module.")
|
@@ -1377,86 +1403,52 @@ const knowledgeModule = async ({
|
|
1377
1403
|
}
|
1378
1404
|
|
1379
1405
|
const isProcess = require.main === moduleFromJSFile
|
1380
|
-
|
1381
|
-
|
1382
|
-
if (
|
1383
|
-
|
1406
|
+
|
1407
|
+
const setupConfig = (config) => {
|
1408
|
+
if (!config.name) {
|
1409
|
+
throw new Error("config must have 'name' set to the knowledge module name.")
|
1384
1410
|
}
|
1385
|
-
}
|
1386
1411
|
|
1387
|
-
|
1388
|
-
|
1389
|
-
|
1390
|
-
|
1391
|
-
|
1392
|
-
} else {
|
1393
|
-
return true
|
1394
|
-
}
|
1395
|
-
})
|
1396
|
-
config.config.bridges = config.config.bridges.filter( (bridge) => {
|
1397
|
-
if (bridge.development) {
|
1398
|
-
return false
|
1399
|
-
} else {
|
1400
|
-
return true
|
1412
|
+
config.description = description
|
1413
|
+
if (typeof test === 'object') {
|
1414
|
+
if (test.contents) {
|
1415
|
+
config.tests = test.contents
|
1416
|
+
test = test.name
|
1401
1417
|
}
|
1402
|
-
})
|
1403
|
-
}
|
1404
|
-
|
1405
|
-
let module
|
1406
|
-
if (_.isFunction(moduleFromJSFile)) {
|
1407
|
-
module = moduleFromJSFile
|
1408
|
-
} else {
|
1409
|
-
module = () => {
|
1410
|
-
config.rebuild({ isModule: true })
|
1411
|
-
moduleFromJSFile.exports = config
|
1412
|
-
}
|
1413
|
-
}
|
1414
|
-
processResults = processResults({ config, errorHandler })
|
1415
|
-
config.description = description
|
1416
|
-
config.demo = demo
|
1417
|
-
if (typeof test === 'object') {
|
1418
|
-
if (test.contents) {
|
1419
|
-
config.tests = test.contents
|
1420
|
-
test = test.name
|
1421
|
-
}
|
1422
|
-
} else {
|
1423
|
-
if (runtime.fs && runtime.fs.existsSync(test)) {
|
1424
|
-
config.tests = JSON.parse(runtime.fs.readFileSync(test))
|
1425
1418
|
} else {
|
1426
|
-
|
1427
|
-
|
1428
|
-
|
1429
|
-
|
1430
|
-
|
1431
|
-
if (!isProcess) {
|
1432
|
-
if (template) {
|
1433
|
-
if (config.needsRebuild(template.template, template.instance)) {
|
1434
|
-
throw new Error(`This module "${config.name}" cannot be used because the instance file needs rebuilding. Run on the command line with no arguements or the -rt argument to rebuild.`)
|
1435
|
-
}
|
1436
|
-
try {
|
1437
|
-
config.load(template.template, template.instance)
|
1438
|
-
} catch( e ) {
|
1439
|
-
errorHandler(e)
|
1419
|
+
if (runtime.fs && runtime.fs.existsSync(test)) {
|
1420
|
+
config.tests = JSON.parse(runtime.fs.readFileSync(test))
|
1421
|
+
} else {
|
1422
|
+
config.tests = []
|
1440
1423
|
}
|
1441
1424
|
}
|
1425
|
+
config.setTestConfig(testConfig)
|
1442
1426
|
}
|
1427
|
+
|
1428
|
+
|
1443
1429
|
if (isProcess) {
|
1430
|
+
const config = createConfig()
|
1431
|
+
setupConfig(config)
|
1432
|
+
processResults = processResults({ config, errorHandler })
|
1444
1433
|
// setup();
|
1445
1434
|
const parser = new runtime.ArgumentParser({
|
1446
1435
|
description: 'Entodicton knowledge module'
|
1447
1436
|
})
|
1448
1437
|
|
1449
|
-
const helpDebugAssociation = 'In order to get a debug break when a specific association is created set the DEBUG_ASSOCIATION environment variable to the JSON of the association to break on. For example DEBUG_ASSOCIATION=\'["the
|
1450
|
-
const helpDebugHierarchy = 'In order to get a debug break when a specific hierarchy is created set the DEBUG_HIERARCHY environment variable to the JSON of the child-parent pair to break on. For example DEBUG_HIERARCHY=\'["cat
|
1451
|
-
const helpDebugPriority = 'In order to get a debug break when a specific set of priorities is created set set DEBUG_PRIORITY environment variable to the JSON of the priorities that you want to break on. For example DEBUG_PRIORITY=\'["verb
|
1452
|
-
const
|
1453
|
-
const
|
1438
|
+
const helpDebugAssociation = 'In order to get a debug break when a specific association is created set the DEBUG_ASSOCIATION environment variable to the JSON of the association to break on. For example DEBUG_ASSOCIATION=\'[["the", 0], ["mammal", 1]]\''
|
1439
|
+
const helpDebugHierarchy = 'In order to get a debug break when a specific hierarchy is created set the DEBUG_HIERARCHY environment variable to the JSON of the child-parent pair to break on. For example DEBUG_HIERARCHY=\'[["cat", 1], ["mammel", 1]]\''
|
1440
|
+
const helpDebugPriority = 'In order to get a debug break when a specific set of priorities is created set set DEBUG_PRIORITY environment variable to the JSON of the priorities that you want to break on. For example DEBUG_PRIORITY=\'[["verb", 0], ["article", 0]]\''
|
1441
|
+
const helpDebugContextualPriority = 'In order to get a debug break when a specific set of contextual priorities is created set set DEBUG_CONTEXTUAL_PRIORITY environment variable to the JSON of the priorities that you want to break on. For example DEBUG_CONTEXTUAL_PRIORITY=\'{ context: [["verb", 0], ["article", 0], select: 1}\''
|
1442
|
+
const helpDebugBridge = 'In order to get a debug break when a specific bridge is created set the DEBUG_BRIDGE environment variable to id/level to break on. For example DEBUG_BRIDGE=\'id#level\''
|
1443
|
+
const helpDebugOperator = 'In order to get a debug break when a specific hierarcy is created set the DEBUG_OPERATOR environment variable to debug any config loaded. For example DEBUG_OPERATOR=\'([operator] ([arg]))\''
|
1454
1444
|
|
1455
1445
|
|
1456
1446
|
parser.add_argument('-tmn', '--testModuleName', { help: 'When running tests instead of using the current modules tests use the specified modules tests' })
|
1457
1447
|
parser.add_argument('-t', '--test', { action: 'store_true', help: 'Run the tests. Create tests by running with the --query + --save flag' })
|
1458
1448
|
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' })
|
1449
|
+
// parser.add_argument('-ttr', '--testToRun', { help: 'Only the specified test will be run' })
|
1459
1450
|
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' })
|
1451
|
+
parser.add_argument('-tnp', '--testNoParenthesized', { action: 'store_true', help: 'Don\' check parenthesized differences for the tests' })
|
1460
1452
|
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' })
|
1461
1453
|
// 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.' })
|
1462
1454
|
parser.add_argument('-rt', '--rebuildTemplate', { action: 'store_true', help: 'Force a template rebuild' })
|
@@ -1464,7 +1456,7 @@ const knowledgeModule = async ({
|
|
1464
1456
|
parser.add_argument('-i', '--info', { action: 'store_true', help: 'Print meta-data for the module' })
|
1465
1457
|
parser.add_argument('-v', '--vimdiff', { action: 'store_true', help: 'For failures run vimdiff' })
|
1466
1458
|
parser.add_argument('-g', '--greg', { action: 'store_true', help: 'Set the server to be localhost so I can debug stuff' })
|
1467
|
-
parser.add_argument('-cl', '--checkForLoop', {
|
1459
|
+
parser.add_argument('-cl', '--checkForLoop', { nargs: "?", help: 'Check for loops in the priorities, Optional argument is list of operator keys to consider. For example [["banana", 0], ["food", 1]]' })
|
1468
1460
|
parser.add_argument('-r', '--retrain', { action: 'store_true', help: 'Get the server to retrain the neural nets' })
|
1469
1461
|
parser.add_argument('-q', '--query', { help: 'Run the specified query' })
|
1470
1462
|
parser.add_argument('-ip ', '--server', { help: 'Server to run against' })
|
@@ -1477,14 +1469,16 @@ const knowledgeModule = async ({
|
|
1477
1469
|
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' })
|
1478
1470
|
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.' })
|
1479
1471
|
parser.add_argument('-sd', '--saveDeveloper', { action: 'store_true', help: 'Same as -s but the query will not show up in the info command.' })
|
1480
|
-
parser.add_argument('-dic', '--debugIncludeConvolutions', { action: 'store_true', help: 'When running with the --debugIncludeConvolutions flag the logs will include convolutions which are somewhat annoying verbose. Default is false' })
|
1481
1472
|
parser.add_argument('-dl', '--debugLoops', { action: 'store_true', help: 'When running with the --debugLoops flag the logs calls to semantics and generators will be immediately written to the console '})
|
1482
1473
|
parser.add_argument('-d', '--debug', { action: 'store_true', help: 'When running with the --debug flag this set the debug flag in the config' })
|
1483
|
-
parser.add_argument('-da', '--debugAssociation', { help: helpDebugAssociation })
|
1484
|
-
parser.add_argument('-dh', '--debugHierarchy', { help: helpDebugHierarchy })
|
1485
|
-
parser.add_argument('-dp', '--debugPriority', { help: helpDebugPriority })
|
1486
|
-
parser.add_argument('-
|
1487
|
-
parser.add_argument('-
|
1474
|
+
parser.add_argument('-da', '--debugAssociation', { action: 'store_true', help: helpDebugAssociation })
|
1475
|
+
parser.add_argument('-dh', '--debugHierarchy', { action: 'store_true', help: helpDebugHierarchy })
|
1476
|
+
parser.add_argument('-dp', '--debugPriority', { action: 'store_true', help: helpDebugPriority })
|
1477
|
+
parser.add_argument('-dcp', '--debugContextualPriority', { action: 'store_true', help: helpDebugContextualPriority })
|
1478
|
+
parser.add_argument('-db', '--debugBridge', { action: 'store_true', help: helpDebugBridge })
|
1479
|
+
parser.add_argument('-do', '--debugOperator', { action: 'store_true', help: helpDebugOperator })
|
1480
|
+
parser.add_argument('-ep', '--explainPriorities', { action: 'store_true', help: "The server will return all priorities including the generated one along with an explanation of there they came from"})
|
1481
|
+
parser.add_argument('-dic', '--debugIncludeConvolutions', { nargs: "?", help: 'When running with the --debugIncludeConvolutions flag the logs will include convolutions which are somewhat annoyingly verbose. Default is false' })
|
1488
1482
|
|
1489
1483
|
const args = parser.parse_args()
|
1490
1484
|
args.count = args.count || 1
|
@@ -1492,7 +1486,35 @@ const knowledgeModule = async ({
|
|
1492
1486
|
if (args.parenthesized) {
|
1493
1487
|
config.parenthesized = true
|
1494
1488
|
}
|
1495
|
-
|
1489
|
+
if (args.checkForLoop) {
|
1490
|
+
try {
|
1491
|
+
args.checkForLoop = JSON.parse(args.checkForLoop)
|
1492
|
+
const isKey = (what) => {
|
1493
|
+
if (!Array.isArray(what)) {
|
1494
|
+
return false
|
1495
|
+
}
|
1496
|
+
if (what.length !== 2) {
|
1497
|
+
return false
|
1498
|
+
}
|
1499
|
+
if (!typeof what[0] == 'string') {
|
1500
|
+
return false
|
1501
|
+
}
|
1502
|
+
if (!typeof what[1] == 'number') {
|
1503
|
+
return false
|
1504
|
+
}
|
1505
|
+
return true
|
1506
|
+
}
|
1507
|
+
if (!Array.isArray(args.checkForLoop) || args.checkForLoop.some((value) => !isKey(value))) {
|
1508
|
+
throw new Error(`Error for the checkForLoop argument. Expected a JSON array of operator keys of the form "[<id>, <level>]"`)
|
1509
|
+
}
|
1510
|
+
} catch( e ) {
|
1511
|
+
throw new Error(`Error parsing JSON of the checkForLoop argument. ${e}`)
|
1512
|
+
}
|
1513
|
+
} else {
|
1514
|
+
if (process.argv.includes('--checkForLoop') || process.argv.includes('-cl')) {
|
1515
|
+
args.checkForLoop = true
|
1516
|
+
}
|
1517
|
+
}
|
1496
1518
|
if (args.debugAssociation) {
|
1497
1519
|
console.log(helpDebugAssociation)
|
1498
1520
|
runtime.process.exit(-1)
|
@@ -1550,35 +1572,12 @@ const knowledgeModule = async ({
|
|
1550
1572
|
if (args.debug) {
|
1551
1573
|
config.config.debug = true
|
1552
1574
|
}
|
1553
|
-
config.config.debugIncludeConvolutions = args.debugIncludeConvolutions
|
1554
|
-
|
1555
|
-
if (template) {
|
1556
|
-
const needsRebuild = config.needsRebuild(template.template, template.instance, options)
|
1557
|
-
if (needsRebuild) {
|
1558
|
-
console.log(`This module "${config.name}" needs rebuilding all other arguments will be ignored. Try again after the template is rebuilt.`)
|
1559
|
-
|
1560
|
-
}
|
1561
|
-
config.load(template.template, template.instance, { rebuild: needsRebuild })
|
1562
|
-
if (needsRebuild) {
|
1563
|
-
return
|
1564
|
-
}
|
1565
|
-
}
|
1566
1575
|
|
1567
|
-
if (
|
1568
|
-
config.
|
1569
|
-
//for (let query in config.tests) {
|
1570
|
-
// config.addAssociations(config.tests[query].associations || []);
|
1571
|
-
//}
|
1576
|
+
if (args.explainPriorities) {
|
1577
|
+
config.config.explain_priorities = true
|
1572
1578
|
}
|
1573
1579
|
|
1574
|
-
|
1575
|
-
if (args.buildTemplate) {
|
1576
|
-
if (template) {
|
1577
|
-
config.rebuild()
|
1578
|
-
config.load(template.template, template.instance, { rebuild: true })
|
1579
|
-
}
|
1580
|
-
}
|
1581
|
-
*/
|
1580
|
+
config.config.debugIncludeConvolutions = args.debugIncludeConvolutions || process.argv.includes('--debugIncludeConvolutions') || process.argv.includes('-dic')
|
1582
1581
|
|
1583
1582
|
let configPrinted = false
|
1584
1583
|
const printConfig = () => {
|
@@ -1671,6 +1670,24 @@ const knowledgeModule = async ({
|
|
1671
1670
|
}
|
1672
1671
|
}
|
1673
1672
|
|
1673
|
+
if (template) {
|
1674
|
+
const needsRebuild = config.needsRebuild(template.template, template.instance, options)
|
1675
|
+
if (needsRebuild) {
|
1676
|
+
console.log(`This module "${config.name}" needs rebuilding all other arguments will be ignored. Try again after the template is rebuilt.`)
|
1677
|
+
options.rebuild = true
|
1678
|
+
config.config.rebuild = true
|
1679
|
+
}
|
1680
|
+
config.load(template.template, template.instance, { rebuild: needsRebuild })
|
1681
|
+
printConfig()
|
1682
|
+
if (needsRebuild) {
|
1683
|
+
return
|
1684
|
+
}
|
1685
|
+
}
|
1686
|
+
|
1687
|
+
if (!args.save && !args.rebuildTemplate && !args.dontAddAssociations) {
|
1688
|
+
config.addAssociationsFromTests(config.tests);
|
1689
|
+
}
|
1690
|
+
|
1674
1691
|
if (args.retrain) {
|
1675
1692
|
config.config.retrain = true
|
1676
1693
|
}
|
@@ -1712,11 +1729,13 @@ const knowledgeModule = async ({
|
|
1712
1729
|
if (JSON.stringify(result.expected.paraphrases) !== JSON.stringify(result.actual.paraphrases)) {
|
1713
1730
|
hasError = true
|
1714
1731
|
}
|
1715
|
-
if (
|
1716
|
-
|
1717
|
-
|
1718
|
-
|
1719
|
-
|
1732
|
+
if (!args.testNoParenthesized) {
|
1733
|
+
if (JSON.stringify(result.expected.paraphrasesParenthesized) !== JSON.stringify(result.actual.paraphrasesParenthesized)) {
|
1734
|
+
hasError = true
|
1735
|
+
}
|
1736
|
+
if (JSON.stringify(result.expected.generatedParenthesized) !== JSON.stringify(result.actual.generatedParenthesized)) {
|
1737
|
+
hasError = true
|
1738
|
+
}
|
1720
1739
|
}
|
1721
1740
|
if (JSON.stringify(result.expected.responses) !== JSON.stringify(result.actual.responses)) {
|
1722
1741
|
hasError = true
|
@@ -1724,6 +1743,9 @@ const knowledgeModule = async ({
|
|
1724
1743
|
if (JSON.stringify(result.expected.checked) !== JSON.stringify(result.actual.checked)) {
|
1725
1744
|
hasError = true
|
1726
1745
|
}
|
1746
|
+
if (!sameJSON(result.expected.checkedContexts, result.actual.checkedContexts)) {
|
1747
|
+
hasError = true
|
1748
|
+
}
|
1727
1749
|
}
|
1728
1750
|
|
1729
1751
|
if (hasError) {
|
@@ -1742,9 +1764,13 @@ const knowledgeModule = async ({
|
|
1742
1764
|
}
|
1743
1765
|
}
|
1744
1766
|
show('paraphrases', result.expected.paraphrases, result.actual.paraphrases)
|
1745
|
-
|
1767
|
+
if (!args.testNoParenthesized) {
|
1768
|
+
show('paraphrases parenthesized', result.expected.paraphrasesParenthesized, result.actual.paraphrasesParenthesized)
|
1769
|
+
}
|
1746
1770
|
show('responses', result.expected.responses, result.actual.responses)
|
1747
|
-
|
1771
|
+
if (!args.testNoParenthesized) {
|
1772
|
+
show('responses parenthesized', result.expected.generatedParenthesized, result.actual.generatedParenthesized)
|
1773
|
+
}
|
1748
1774
|
/*
|
1749
1775
|
if (JSON.stringify(result.expected.paraphrases) !== JSON.stringify(result.actual.paraphrases)) {
|
1750
1776
|
if (!headerShown) {
|
@@ -1783,6 +1809,24 @@ const knowledgeModule = async ({
|
|
1783
1809
|
newError = true
|
1784
1810
|
headerShown = true
|
1785
1811
|
}
|
1812
|
+
if (!sameJSON(result.expected.checkedContexts, result.actual.checkedContexts)) {
|
1813
|
+
if (!headerShown) {
|
1814
|
+
console.log(' Failure')
|
1815
|
+
}
|
1816
|
+
const widths = [4, 18, 72]
|
1817
|
+
const lines = new Lines(widths)
|
1818
|
+
lines.setElement(1, 1, 'expected checkedContexts', true)
|
1819
|
+
lines.setElement(2, 2, JSON.stringify(result.expected.checkedContexts, null, 2))
|
1820
|
+
lines.log()
|
1821
|
+
lines.setElement(1, 1, 'actual checkedContexts', true)
|
1822
|
+
lines.setElement(2, 2, JSON.stringify(result.actual.checkedContexts, null, 2))
|
1823
|
+
lines.log()
|
1824
|
+
if (args.vimdiff) {
|
1825
|
+
vimdiff(result.actual.checkedContexts, result.expected.checkedContexts)
|
1826
|
+
}
|
1827
|
+
newError = true
|
1828
|
+
headerShown = true
|
1829
|
+
}
|
1786
1830
|
}
|
1787
1831
|
} else {
|
1788
1832
|
if (results.length > 0 && args.vimdiff) {
|
@@ -1821,7 +1865,6 @@ const knowledgeModule = async ({
|
|
1821
1865
|
if (query.length === 0) {
|
1822
1866
|
return readline.close()
|
1823
1867
|
}
|
1824
|
-
// const promise = processResults(_process(config, query, { testsFN: test }))
|
1825
1868
|
const promise = _process(config, query, { testsFN: test }).then((results) => {
|
1826
1869
|
console.log(results.responses.join(' '))
|
1827
1870
|
})
|
@@ -1849,7 +1892,6 @@ const knowledgeModule = async ({
|
|
1849
1892
|
if (args.objectDiff) {
|
1850
1893
|
global.beforeObjects = _.cloneDeep(objects)
|
1851
1894
|
}
|
1852
|
-
config.beforeQuery({ query: args.query, isModule: false, objects })
|
1853
1895
|
try {
|
1854
1896
|
await processResults(_process(config, args.query, { commandLineArgs: args, dontAddAssociations: args.dontAddAssociations, writeTests: args.save || args.saveDeveloper, saveDeveloper: args.saveDeveloper, testConfig, testsFN: test }))
|
1855
1897
|
} catch( error ) {
|
@@ -1858,11 +1900,55 @@ const knowledgeModule = async ({
|
|
1858
1900
|
}
|
1859
1901
|
printConfig()
|
1860
1902
|
} else {
|
1861
|
-
|
1862
|
-
|
1863
|
-
|
1864
|
-
|
1865
|
-
|
1903
|
+
const initConfig = (config) => {
|
1904
|
+
setupConfig(config)
|
1905
|
+
|
1906
|
+
let loadForTesting = false
|
1907
|
+
if (global.theprogrammablemind) {
|
1908
|
+
if (global.theprogrammablemind.loadForTesting[config.name]) {
|
1909
|
+
loadForTesting = true
|
1910
|
+
}
|
1911
|
+
}
|
1912
|
+
// remove test only stuff
|
1913
|
+
if (!isProcess && !loadForTesting) {
|
1914
|
+
config.config.operators = config.config.operators.filter( (operator) => {
|
1915
|
+
if (operator.development) {
|
1916
|
+
return false
|
1917
|
+
} else {
|
1918
|
+
return true
|
1919
|
+
}
|
1920
|
+
})
|
1921
|
+
config.config.bridges = config.config.bridges.filter( (bridge) => {
|
1922
|
+
if (bridge.development) {
|
1923
|
+
return false
|
1924
|
+
} else {
|
1925
|
+
return true
|
1926
|
+
}
|
1927
|
+
})
|
1928
|
+
}
|
1929
|
+
|
1930
|
+
if (template) {
|
1931
|
+
if (config.needsRebuild(template.template, template.instance, { isModule: !isProcess })) {
|
1932
|
+
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.`
|
1933
|
+
throw new Error(error)
|
1934
|
+
}
|
1935
|
+
try {
|
1936
|
+
config.load(template.template, template.instance)
|
1937
|
+
} catch( e ) {
|
1938
|
+
errorHandler(e)
|
1939
|
+
}
|
1940
|
+
}
|
1941
|
+
|
1942
|
+
config.addAssociationsFromTests(config.tests);
|
1943
|
+
}
|
1944
|
+
|
1945
|
+
createConfigExport = () => {
|
1946
|
+
const config = createConfig()
|
1947
|
+
initConfig(config)
|
1948
|
+
config.rebuild({ isModule: true })
|
1949
|
+
return config
|
1950
|
+
}
|
1951
|
+
moduleFromJSFile.exports = createConfigExport
|
1866
1952
|
}
|
1867
1953
|
|
1868
1954
|
}
|
@@ -1918,7 +2004,7 @@ module.exports = {
|
|
1918
2004
|
w,
|
1919
2005
|
// submitBug,
|
1920
2006
|
ensureTestFile,
|
1921
|
-
|
2007
|
+
rebuildTemplate,
|
1922
2008
|
processContext,
|
1923
2009
|
processContexts,
|
1924
2010
|
runTests,
|
@@ -1930,8 +2016,9 @@ module.exports = {
|
|
1930
2016
|
Digraph,
|
1931
2017
|
analyzeMetaData,
|
1932
2018
|
processContextsB,
|
1933
|
-
|
2019
|
+
loadInstance,
|
1934
2020
|
gs,
|
1935
2021
|
flattens,
|
1936
2022
|
writeTest
|
1937
2023
|
}
|
2024
|
+
|