theprogrammablemind 7.5.8 → 7.6.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 +589 -345
- package/index.js +1 -0
- package/lines.js +3 -3
- package/package.json +2 -1
- package/runtime.js +1 -1
- package/src/config.js +699 -325
- package/src/flatten.js +9 -1
- package/src/generators.js +2 -2
- package/src/helpers.js +38 -10
- package/src/project.js +81 -0
- package/src/semantics.js +8 -3
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,10 +83,9 @@ 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
|
-
const child = runtime.child_process.spawn(editor, [`${path}/expected.json`, `${path}/actual.json`], { stdio: 'inherit' })
|
62
|
-
|
63
|
-
|
64
|
-
})
|
86
|
+
// const child = runtime.child_process.spawn(editor, [`${path}/expected.json`, `${path}/actual.json`], { stdio: 'inherit' })
|
87
|
+
console.log(`${editor} ${path}/expected.json ${path}/actual.json`)
|
88
|
+
runtime.child_process.execSync(`${editor} ${path}/expected.json ${path}/actual.json`, {stdio: 'inherit'})
|
65
89
|
}
|
66
90
|
}
|
67
91
|
|
@@ -100,10 +124,24 @@ const asList = (context) => {
|
|
100
124
|
}
|
101
125
|
}
|
102
126
|
|
127
|
+
class ErrorReason extends Error {
|
128
|
+
constructor(context) {
|
129
|
+
super(JSON.stringify(context))
|
130
|
+
this.reason = context
|
131
|
+
}
|
132
|
+
}
|
133
|
+
|
103
134
|
const setupArgs = (args, config, logs, hierarchy) => {
|
104
135
|
config.setArgs(args)
|
105
|
-
args.calls = new InitCalls()
|
136
|
+
args.calls = new InitCalls(args.isInstance ? `${args.isInstance}#${config.name}` : config.name)
|
137
|
+
if (global.theprogrammablemind && global.theprogrammablemind.loadForTesting) {
|
138
|
+
args.calls = new InitCalls(Object.keys(global.theprogrammablemind.loadForTesting)[0])
|
139
|
+
}
|
106
140
|
args.km = (name) => config.getConfig(name)
|
141
|
+
args.api = (name) => config.getConfig(name).api
|
142
|
+
args.error = (context) => {
|
143
|
+
throw new ErrorReason(context)
|
144
|
+
}
|
107
145
|
args.kms = config.getConfigs()
|
108
146
|
args.config = config
|
109
147
|
args.hierarchy = hierarchy
|
@@ -111,6 +149,7 @@ const setupArgs = (args, config, logs, hierarchy) => {
|
|
111
149
|
args.listable = listable(hierarchy)
|
112
150
|
args.asList = asList
|
113
151
|
args.retry = () => { throw new RetryError() }
|
152
|
+
args.fragments = (query) => config.fragment(query)
|
114
153
|
const scopedAsk = getAsk(config)
|
115
154
|
|
116
155
|
const getAPI = (uuid) => {
|
@@ -130,7 +169,6 @@ const setupArgs = (args, config, logs, hierarchy) => {
|
|
130
169
|
apis: getAPIs(uuid)
|
131
170
|
}
|
132
171
|
}
|
133
|
-
args.motivation = (m) => config.addMotivation(m)
|
134
172
|
args.breakOnSemantics = false
|
135
173
|
args.theDebugger = {
|
136
174
|
breakOnSemantics: (value) => args.breakOnSemantics = value
|
@@ -139,12 +177,15 @@ const setupArgs = (args, config, logs, hierarchy) => {
|
|
139
177
|
args.g = (c) => config.getGenerators(logs).apply(args, c)
|
140
178
|
args.gp = (c) => config.getGenerators(logs).apply(args, { ...c, paraphrase: true, isResponse: false, response: false})
|
141
179
|
args.gr = (c) => config.getGenerators(logs).apply(args, { ...c, paraphrase: false, isResponse: true })
|
142
|
-
|
180
|
+
if (!logs) {
|
181
|
+
debugger
|
182
|
+
}
|
183
|
+
args.e = (c) => config.getEvaluator(args.s, args.calls, logs, c)
|
143
184
|
args.log = (message) => logs.push(message)
|
144
|
-
// config.getAddedArgs(args)
|
145
185
|
args.gs = gs(args.g)
|
146
186
|
args.gsp = gs(args.gp)
|
147
187
|
args.gsr = gs(args.gr)
|
188
|
+
config.getAddedArgs(args)
|
148
189
|
}
|
149
190
|
|
150
191
|
const gs = (g) => (contexts, separator, lastSeparator) => {
|
@@ -272,7 +313,7 @@ const writeTestFile = (fn, tests) => {
|
|
272
313
|
runtime.fs.writeFileSync(fn, stringify(tests, { space: 2 }), { encoding: 'utf8', flag: 'w+' })
|
273
314
|
}
|
274
315
|
|
275
|
-
const writeTest = (fn, query, objects, generated, paraphrases, responses, contexts, associations, metadata, config, saveDeveloper) => {
|
316
|
+
const writeTest = (fn, query, objects, generated, paraphrases, responses, contexts, associations, metadata, config, saveDeveloper, paraphrasesParenthesized, generatedParenthesized) => {
|
276
317
|
let tests = []
|
277
318
|
if (runtime.fs.existsSync(fn)) {
|
278
319
|
tests = JSON.parse(runtime.fs.readFileSync(fn))
|
@@ -282,7 +323,18 @@ const writeTest = (fn, query, objects, generated, paraphrases, responses, contex
|
|
282
323
|
}
|
283
324
|
associations.sort()
|
284
325
|
// tests[query] = sortJson({ paraphrases, responses, contexts, objects: convertToStable(objects), associations, metadata, config, developerTest: saveDeveloper }, { depth: 25 })
|
285
|
-
results = sortJson({
|
326
|
+
results = sortJson({
|
327
|
+
query,
|
328
|
+
paraphrases,
|
329
|
+
responses,
|
330
|
+
contexts,
|
331
|
+
objects: convertToStable(objects),
|
332
|
+
associations,
|
333
|
+
metadata,
|
334
|
+
config,
|
335
|
+
developerTest: saveDeveloper,
|
336
|
+
paraphrasesParenthesized,
|
337
|
+
generatedParenthesized }, { depth: 25 })
|
286
338
|
let wasSet = false;
|
287
339
|
tests.forEach( (test, index) => {
|
288
340
|
if (test.query == query) {
|
@@ -339,16 +391,21 @@ const setupContexts = (rawContexts) => {
|
|
339
391
|
return contexts
|
340
392
|
}
|
341
393
|
|
342
|
-
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 }) => {
|
343
395
|
// TODO fix this name to contextsPrime
|
344
396
|
const contextsPrime = []
|
345
397
|
const generatedPrime = []
|
346
398
|
const paraphrasesPrime = []
|
399
|
+
const paraphrasesParenthesizedPrime = []
|
400
|
+
const generatedParenthesizedPrime = []
|
347
401
|
const responsesPrime = []
|
348
402
|
const contexts = setupContexts(json.contexts)
|
349
403
|
|
350
404
|
const objects = config.get('objects')
|
351
|
-
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 }
|
406
|
+
if (!json.logs) {
|
407
|
+
json.logs = []
|
408
|
+
}
|
352
409
|
setupArgs(args, config, json.logs, hierarchy)
|
353
410
|
const toDo = [...contexts]
|
354
411
|
args.insert = (context) => toDo.unshift(context)
|
@@ -356,28 +413,6 @@ const processContextsB = ({ config, hierarchy, semantics, generators, json, isTe
|
|
356
413
|
config.debugLoops = commandLineArgs && commandLineArgs.debugLoops
|
357
414
|
while (toDo.length > 0) {
|
358
415
|
const context = toDo.shift()
|
359
|
-
/*
|
360
|
-
if (false && query) {
|
361
|
-
if (config.wasChanged()) {
|
362
|
-
// process contexts that overlap
|
363
|
-
overlap = lastRange
|
364
|
-
} else {
|
365
|
-
config.watch()
|
366
|
-
}
|
367
|
-
if (overlap) {
|
368
|
-
if (overlaps(overlap, context)) {
|
369
|
-
// okay
|
370
|
-
query = query.slice(overlap.end+1)
|
371
|
-
data.utterance = query
|
372
|
-
const json = await doWithRetries(retries, url, data)
|
373
|
-
toDo = setupContexts(json.contexts).slice(1) // take off the start context
|
374
|
-
}
|
375
|
-
overlap = undefined
|
376
|
-
}
|
377
|
-
lastRange = context.range
|
378
|
-
}
|
379
|
-
*/
|
380
|
-
|
381
416
|
args.calls.next()
|
382
417
|
let contextPrime = context
|
383
418
|
context.topLevel = true
|
@@ -385,25 +420,40 @@ const processContextsB = ({ config, hierarchy, semantics, generators, json, isTe
|
|
385
420
|
if (json.has_errors) {
|
386
421
|
throw new Error('There are errors in the logs. Run with the -d flag and grep for Error')
|
387
422
|
}
|
423
|
+
const generateParenthesized = isTest || (commandLineArgs && commandLineArgs.save)
|
388
424
|
if (!config.get('skipSemantics')) {
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
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)
|
399
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
|
+
})
|
400
444
|
}
|
401
445
|
}
|
402
446
|
if (contextPrime.controlRemove) {
|
403
447
|
continue
|
404
448
|
}
|
405
449
|
let assumed = { isResponse: true };
|
406
|
-
const generated = config.getGenerators(json.logs).apply(args, contextPrime, assumed)[0]
|
450
|
+
const generated = contextPrime.isResponse ? config.getGenerators(json.logs).apply(args, contextPrime, assumed)[0] : ''
|
451
|
+
let generatedParenthesized = []
|
452
|
+
if (generateParenthesized) {
|
453
|
+
config.parenthesized = true
|
454
|
+
generatedParenthesized = contextPrime.isResponse ? config.getGenerators(json.logs).apply(args, contextPrime, assumed)[0] : ''
|
455
|
+
config.parenthesized = false
|
456
|
+
}
|
407
457
|
// assumed = { paraphrase: true, response: false };
|
408
458
|
assumed = { paraphrase: true };
|
409
459
|
args.g = (c) => config.getGenerators(json.logs).apply(args, c, assumed)
|
@@ -412,7 +462,16 @@ const processContextsB = ({ config, hierarchy, semantics, generators, json, isTe
|
|
412
462
|
args.gs = gs(args.g)
|
413
463
|
args.gsp = gs(args.gsp)
|
414
464
|
args.gsr = gs(args.gr)
|
465
|
+
if (generateParenthesized) {
|
466
|
+
config.parenthesized = false
|
467
|
+
}
|
415
468
|
const paraphrases = config.getGenerators(json.logs).apply(args, contextPrime, assumed)[0]
|
469
|
+
let paraphrasesParenthesized = []
|
470
|
+
if (generateParenthesized) {
|
471
|
+
config.parenthesized = true
|
472
|
+
paraphrasesParenthesized = config.getGenerators(json.logs).apply(args, contextPrime, assumed)[0]
|
473
|
+
config.parenthesized = false
|
474
|
+
}
|
416
475
|
args.g = (c) => config.getGenerators(json.logs).apply(args, c)
|
417
476
|
args.gp = (c) => config.getGenerators(json.logs).apply(args, {...c, paraphrase: true, isResponse: false, response: false })
|
418
477
|
args.gr = (c) => config.getGenerators(json.logs).apply(args, {...c, paraphrase: false })
|
@@ -422,6 +481,10 @@ const processContextsB = ({ config, hierarchy, semantics, generators, json, isTe
|
|
422
481
|
contextsPrime.push(contextPrime)
|
423
482
|
generatedPrime.push(generated)
|
424
483
|
paraphrasesPrime.push(paraphrases)
|
484
|
+
if (generateParenthesized) {
|
485
|
+
paraphrasesParenthesizedPrime.push(paraphrasesParenthesized)
|
486
|
+
generatedParenthesizedPrime.push(generatedParenthesized)
|
487
|
+
}
|
425
488
|
if (contextPrime.isResponse) {
|
426
489
|
responsesPrime.push(generated)
|
427
490
|
} else {
|
@@ -431,7 +494,7 @@ const processContextsB = ({ config, hierarchy, semantics, generators, json, isTe
|
|
431
494
|
// add results to processed list
|
432
495
|
config.config.objects.processed = config.config.objects.processed || []
|
433
496
|
config.config.objects.processed = config.config.objects.processed.slice(0, 5)
|
434
|
-
config.config.objects.processed.unshift({ context: contextPrime, paraphrases: paraphrases, responses: responsesPrime })
|
497
|
+
config.config.objects.processed.unshift({ context: contextPrime, paraphrases: paraphrases, paraphrasesParenthesized, generatedParenthesized, responses: responsesPrime })
|
435
498
|
} catch (e) {
|
436
499
|
if (Array.isArray(e)) {
|
437
500
|
e = {
|
@@ -451,7 +514,7 @@ const processContextsB = ({ config, hierarchy, semantics, generators, json, isTe
|
|
451
514
|
throw e
|
452
515
|
}
|
453
516
|
}
|
454
|
-
return { contextsPrime, generatedPrime, paraphrasesPrime, responsesPrime }
|
517
|
+
return { contextsPrime, generatedPrime, paraphrasesPrime, paraphrasesParenthesizedPrime, generatedParenthesizedPrime, responsesPrime }
|
455
518
|
}
|
456
519
|
|
457
520
|
const doWithRetries = async (n, url, queryParams, data) => {
|
@@ -473,17 +536,17 @@ const doWithRetries = async (n, url, queryParams, data) => {
|
|
473
536
|
}
|
474
537
|
if (result.status === 504) {
|
475
538
|
if (n === 0) {
|
476
|
-
throw `Error ${result.status} - ${result.statusText}`
|
539
|
+
throw new Error(`Error ${result.status} - ${result.statusText}`)
|
477
540
|
} else {
|
478
541
|
continue
|
479
542
|
}
|
480
543
|
}
|
481
544
|
if (result.status >= 500 && result.status < 600) {
|
482
|
-
throw `Error ${result.status} - ${result.statusText}.`
|
545
|
+
throw new Error(`Error ${result.status} - ${result.statusText}.`)
|
483
546
|
} if (result.status >= 404) {
|
484
|
-
throw `Error ${result.status} - ${result.statusText} - Trying it connect to ${url}`
|
547
|
+
throw new Error(`Error ${result.status} - ${result.statusText} - Trying it connect to ${url}`)
|
485
548
|
} else {
|
486
|
-
throw `Error ${result.status} - ${result.statusText}`
|
549
|
+
throw new Error(`Error ${result.status} - ${result.statusText}`)
|
487
550
|
}
|
488
551
|
}
|
489
552
|
}
|
@@ -496,8 +559,11 @@ const setupProcessB = ({ config, initializer, allowDelta=false } = {}) => {
|
|
496
559
|
// console.log('config', config)
|
497
560
|
data.delta = config.delta()
|
498
561
|
} else {
|
499
|
-
|
562
|
+
config.toData(data)
|
563
|
+
// Object.assign(data, config.config)
|
500
564
|
}
|
565
|
+
|
566
|
+
// config.toServer(data)
|
501
567
|
|
502
568
|
if (data.namespaces) {
|
503
569
|
for (const uuid of Object.keys(data.namespaces)) {
|
@@ -520,10 +586,22 @@ const setupProcessB = ({ config, initializer, allowDelta=false } = {}) => {
|
|
520
586
|
}
|
521
587
|
}
|
522
588
|
|
523
|
-
// instance template
|
524
|
-
const
|
589
|
+
// instance template loadTemplate
|
590
|
+
const loadInstance = (config, instance) => {
|
525
591
|
const transitoryMode = global.transitoryMode
|
526
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
|
+
|
527
605
|
const { /* data, generators, semantics, */ hierarchy } = setupProcessB({ config })
|
528
606
|
// for (const results of (instance.resultss || [])) {
|
529
607
|
for (const i in (instance.resultss || [])) {
|
@@ -531,15 +609,21 @@ const processInstance = (config, instance) => {
|
|
531
609
|
if (results.extraConfig) {
|
532
610
|
// config.addInternal(results, useOldVersion = true, skipObjects = false, includeNamespaces = true, allowNameToBeNull = false)
|
533
611
|
// config.addInternal(config.template.queries[i], { handleCalculatedProps: true } )
|
534
|
-
config.addInternal(instance.template.queries[i], { handleCalculatedProps: true } )
|
612
|
+
config.addInternal(instance.template.queries[i], { addFirst: true, handleCalculatedProps: true } )
|
535
613
|
} else {
|
536
|
-
|
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
|
+
}
|
537
621
|
}
|
538
622
|
}
|
539
623
|
global.transitoryMode = transitoryMode
|
540
624
|
}
|
541
625
|
|
542
|
-
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 } = {}) => {
|
543
627
|
if (credentials) {
|
544
628
|
config.server(credentials.server, credentials.key)
|
545
629
|
}
|
@@ -553,7 +637,6 @@ const _process = async (config, query, { initializer, commandLineArgs, credentia
|
|
553
637
|
if (writeTests) {
|
554
638
|
config.rebuild()
|
555
639
|
const objects = getObjects(config.config.objects)(config.uuid)
|
556
|
-
config.beforeQuery({ query, isModule: false, objects })
|
557
640
|
}
|
558
641
|
} catch(error) {
|
559
642
|
throw error
|
@@ -561,7 +644,10 @@ const _process = async (config, query, { initializer, commandLineArgs, credentia
|
|
561
644
|
|
562
645
|
let { data, /* generators, semantics, */ hierarchy } = setupProcessB({ config, initializer, allowDelta: true })
|
563
646
|
if (commandLineArgs && commandLineArgs.checkForLoop) {
|
564
|
-
data.checkForLoop =
|
647
|
+
data.checkForLoop = commandLineArgs.checkForLoop
|
648
|
+
}
|
649
|
+
if (rebuildingTemplate) {
|
650
|
+
data.errors_ignore_contextual_priorities_non_existant_ops = true
|
565
651
|
}
|
566
652
|
let queries = query.split('\\n')
|
567
653
|
|
@@ -578,6 +664,8 @@ const _process = async (config, query, { initializer, commandLineArgs, credentia
|
|
578
664
|
contexts: [],
|
579
665
|
generated: [],
|
580
666
|
paraphrases: [],
|
667
|
+
paraphrasesParenthesized: [],
|
668
|
+
generatedParenthesized: [],
|
581
669
|
responses: [],
|
582
670
|
associations: [],
|
583
671
|
}
|
@@ -613,9 +701,10 @@ const _process = async (config, query, { initializer, commandLineArgs, credentia
|
|
613
701
|
if (json.status !== 200) {
|
614
702
|
throw json
|
615
703
|
} else {
|
616
|
-
const { contextsPrime, generatedPrime, paraphrasesPrime, responsesPrime } =
|
704
|
+
const { contextsPrime, generatedPrime, paraphrasesPrime, paraphrasesParenthesizedPrime, generatedParenthesizedPrime, responsesPrime } =
|
617
705
|
processContextsB({ isTest, config, hierarchy, json, commandLineArgs /*, generators, semantics */ })
|
618
706
|
response.associations = json.associations
|
707
|
+
response.learned_contextual_priorities = json.learned_contextual_priorities
|
619
708
|
response.hierarchy = json.hierarchy
|
620
709
|
response.load_cache_time += json.load_cache_time
|
621
710
|
appendNoDups(response.logs, json.logs)
|
@@ -626,10 +715,13 @@ const _process = async (config, query, { initializer, commandLineArgs, credentia
|
|
626
715
|
response.times += json.times
|
627
716
|
response.trace = response.trace.concat(json.trace)
|
628
717
|
response.version = json.version
|
718
|
+
response.explain_priorities = json.explain_priorities
|
629
719
|
|
630
720
|
response.contexts = response.contexts.concat(contextsPrime)
|
631
721
|
response.generated = response.generated.concat(generatedPrime)
|
632
722
|
response.paraphrases = response.paraphrases.concat(paraphrasesPrime)
|
723
|
+
response.paraphrasesParenthesized = response.paraphrasesParenthesized.concat(paraphrasesParenthesizedPrime)
|
724
|
+
response.generatedParenthesized = response.generatedParenthesized.concat(generatedParenthesizedPrime)
|
633
725
|
response.responses = response.responses.concat(responsesPrime)
|
634
726
|
queries = queries.slice(1)
|
635
727
|
}
|
@@ -637,13 +729,18 @@ const _process = async (config, query, { initializer, commandLineArgs, credentia
|
|
637
729
|
|
638
730
|
if (writeTests) {
|
639
731
|
const actual_config = getConfigForTest(config, testConfig)
|
640
|
-
|
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)
|
641
738
|
}
|
642
739
|
|
643
740
|
return response
|
644
741
|
} catch(error) {
|
645
742
|
error.query = query
|
646
|
-
|
743
|
+
errorHandler(error)
|
647
744
|
}
|
648
745
|
}
|
649
746
|
|
@@ -677,11 +774,13 @@ const getConfigForTest = (config, testConfig) => {
|
|
677
774
|
return configForTest
|
678
775
|
}
|
679
776
|
|
680
|
-
const runTest = async (config, expected, {
|
777
|
+
const runTest = async (config, expected, { args, verbose, testConfig, debug }) => {
|
681
778
|
const test = expected.query
|
682
779
|
// initialize in between test so state is not preserved since the test was adding without state
|
683
780
|
config.rebuild()
|
684
|
-
|
781
|
+
if (!args.dontAddAssociations) {
|
782
|
+
config.addAssociationsFromTests(config.tests)
|
783
|
+
}
|
685
784
|
// config.addAssocationsFromTests(
|
686
785
|
const errorHandler = (error) => {
|
687
786
|
if (error.metadata) {
|
@@ -700,8 +799,6 @@ const runTest = async (config, expected, { verbose, afterTest, testConfig, debug
|
|
700
799
|
objects = getObjects(config.config.objects)(config.getConfigs()[testConfig.testModuleName].uuid)
|
701
800
|
testConfigName = testConfig.testModuleName
|
702
801
|
}
|
703
|
-
config.beforeQuery({ query: test, isModule: false, objects })
|
704
|
-
// config.resetMotivations()
|
705
802
|
try {
|
706
803
|
const result = await _process(config, test, { errorHandler, isTest: true })
|
707
804
|
result.query = test
|
@@ -716,66 +813,48 @@ const runTest = async (config, expected, { verbose, afterTest, testConfig, debug
|
|
716
813
|
lines.log()
|
717
814
|
}
|
718
815
|
const expected_objects = sortJson(convertToStable(expected.objects), { depth: 25 })
|
816
|
+
delete expected_objects.nameToUUID
|
719
817
|
const actual_objects = sortJson(convertToStable(config.config.objects), { depth: 25 })
|
720
818
|
const failed_paraphrases = !matching(result.paraphrases, expected.paraphrases)
|
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
|
721
822
|
const failed_responses = !matching(result.responses, expected.responses)
|
722
823
|
const failed_contexts = !matching(result.contexts, expected.contexts)
|
723
824
|
const failed_objects = !matching(actual_objects, expected_objects)
|
724
825
|
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
if (prop.km) {
|
729
|
-
c = config.getConfig(prop.km)
|
730
|
-
o = getObjects(prop.km)
|
731
|
-
picked[prop.km] = {}
|
732
|
-
for (let p of c.testConfig.check) {
|
733
|
-
if (p.km) {
|
734
|
-
continue
|
735
|
-
}
|
736
|
-
picked[p] = o[p]
|
737
|
-
}
|
738
|
-
} else {
|
739
|
-
picked[prop] = getObjects(testConfigName)[prop]
|
740
|
-
}
|
741
|
-
}
|
742
|
-
return picked
|
826
|
+
if (args.testNoParenthesized) {
|
827
|
+
failed_paraphrasesParenthesized = false
|
828
|
+
failed_generatedParenthesized = false
|
743
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
|
+
|
744
835
|
const expectedGetObjects = (name) => {
|
745
836
|
if (!name) {
|
746
837
|
name = config.name
|
747
838
|
}
|
748
|
-
return expected.objects.namespaced[expected.objects.nameToUUID[name]]
|
839
|
+
return expected.objects.namespaced[expected.objects.nameToUUID[name]] || {}
|
749
840
|
}
|
750
|
-
const expected_checked = sortJson(
|
841
|
+
const expected_checked = sortJson(pickObjects(testConfig, expectedGetObjects(testConfigName)), { depth: 25 })
|
751
842
|
const actualGetObjects = (name) => {
|
752
843
|
if (!name) {
|
753
844
|
name = config.name
|
754
845
|
}
|
755
846
|
const km = config.configs.find( (km) => km.name == name )
|
756
|
-
return config.config.objects.namespaced[km.uuid]
|
847
|
+
return config.config.objects.namespaced[km.uuid] || {}
|
757
848
|
}
|
758
|
-
const actual_checked = sortJson(
|
849
|
+
const actual_checked = sortJson(pickObjects(testConfig, actualGetObjects(testConfigName)), { depth: 25 })
|
759
850
|
const failed_checked = !matching(actual_objects, expected_objects)
|
760
851
|
|
761
852
|
const failed_checks = !matching(actual_objects, expected_objects)
|
853
|
+
const failed_checked_objects = !matching(actual_checked, expected_checked)
|
762
854
|
const actual_config = sortJson(convertToStable(getConfigForTest(config, testConfig)), { depth: 25 })
|
763
855
|
const expected_config = sortJson(convertToStable(expected.config), { depth: 25 })
|
764
856
|
const failed_config = !matching(actual_config, expected_config)
|
765
|
-
let failed = failed_paraphrases || failed_responses || failed_contexts || failed_objects || failed_config || failed_checked
|
766
|
-
if (!failed) {
|
767
|
-
if (config.afterTest) {
|
768
|
-
failed = config.afterTest({ query: test, expected, actual: result, config })
|
769
|
-
if (failed) {
|
770
|
-
return {
|
771
|
-
utterance: test,
|
772
|
-
errorFromAfterTest: failed,
|
773
|
-
expected: { responses: expected.responses, paraphrases: expected.paraphrases, results: expected.contexts, checked: expected_checked, objects: expected_objects, config: expected.config },
|
774
|
-
actual: { responses: result.responses, paraphrases: result.paraphrases, results: result.contexts, checked: actual_checked, objects: actual_objects, config: actual_config }
|
775
|
-
}
|
776
|
-
}
|
777
|
-
}
|
778
|
-
}
|
857
|
+
let failed = failed_checked_objects || failed_paraphrases || failed_paraphrasesParenthesized || failed_generatedParenthesized || failed_responses || failed_contexts || failed_objects || failed_config || failed_checked || failedCheckedContexts
|
779
858
|
|
780
859
|
if (expected.metadata && result.metadata && failed) {
|
781
860
|
const priorities = analyzeMetaData(expected.metadata, result.metadata)
|
@@ -787,8 +866,28 @@ const runTest = async (config, expected, { verbose, afterTest, testConfig, debug
|
|
787
866
|
if (failed) {
|
788
867
|
return {
|
789
868
|
utterance: test,
|
790
|
-
expected: {
|
791
|
-
|
869
|
+
expected: {
|
870
|
+
responses: expected.responses,
|
871
|
+
paraphrases: expected.paraphrases,
|
872
|
+
paraphrasesParenthesized: expected.paraphrasesParenthesized,
|
873
|
+
generatedParenthesized: expected.generatedParenthesized,
|
874
|
+
results: expected.contexts,
|
875
|
+
checked: expected_checked,
|
876
|
+
checkedContexts: pickedExpectedContexts,
|
877
|
+
objects: expected_objects,
|
878
|
+
config: expected.config
|
879
|
+
},
|
880
|
+
actual: {
|
881
|
+
responses: result.responses,
|
882
|
+
paraphrases: result.paraphrases,
|
883
|
+
paraphrasesParenthesized: result.paraphrasesParenthesized,
|
884
|
+
generatedParenthesized: result.generatedParenthesized,
|
885
|
+
results: result.contexts,
|
886
|
+
checked: actual_checked,
|
887
|
+
checkedContexts: pickedResultContexts,
|
888
|
+
objects: actual_objects,
|
889
|
+
config: actual_config
|
890
|
+
}
|
792
891
|
}
|
793
892
|
}
|
794
893
|
} catch(error) {
|
@@ -825,20 +924,16 @@ const runTestsHelper = async (config, tests, failed, juicyBits) => {
|
|
825
924
|
|
826
925
|
const runTests = async (config, testFile, juicyBits) => {
|
827
926
|
const tests = JSON.parse(runtime.fs.readFileSync(testFile))
|
828
|
-
config.beforeTests()
|
829
927
|
if (juicyBits.verbose) {
|
830
928
|
console.log('\n', testFile, '-----------------------------------------------', '\n')
|
831
929
|
}
|
832
930
|
const v = await runTestsHelper(config, [...tests], [], juicyBits)
|
833
|
-
config.afterTests()
|
834
931
|
return v
|
835
932
|
}
|
836
933
|
|
837
934
|
const saveTest = async (testFile, config, test, expected, testConfig, saveDeveloper) => {
|
838
935
|
config.rebuild()
|
839
936
|
const objects = getObjects(config.config.objects)(config.uuid)
|
840
|
-
//config.resetMotivations()
|
841
|
-
config.beforeQuery({ query: test, isModule: false, objects })
|
842
937
|
console.log(test)
|
843
938
|
const result = await _process(config, test, { isTest: true })
|
844
939
|
// const actualObjects = config.config.objects
|
@@ -850,7 +945,7 @@ const saveTest = async (testFile, config, test, expected, testConfig, saveDevelo
|
|
850
945
|
for (let km of config.configs) {
|
851
946
|
saveObjects.nameToUUID[km.name] = km.uuid
|
852
947
|
}
|
853
|
-
writeTest(testFile, test, saveObjects, result.generated, result.paraphrases, result.responses, result.contexts, result.associations, result.metadata, actualConfig, saveDeveloper)
|
948
|
+
writeTest(testFile, test, saveObjects, result.generated, result.paraphrases, result.responses, result.contexts, result.associations, result.metadata, actualConfig, saveDeveloper, result.paraphrasesParenthesized, result.generatedParenthesized)
|
854
949
|
}
|
855
950
|
|
856
951
|
const saveTestsHelper = async (testFile, config, tests, todo, testConfig, saveDeveloper) => {
|
@@ -1020,10 +1115,11 @@ const defaultErrorHandler = async (error) => {
|
|
1020
1115
|
doErrorExit = true
|
1021
1116
|
}
|
1022
1117
|
|
1023
|
-
if (doErrorExit) {
|
1118
|
+
if (typeof runtime.process.exit == 'function' && doErrorExit) {
|
1024
1119
|
runtime.process.exit(-1)
|
1025
1120
|
}
|
1026
|
-
|
1121
|
+
|
1122
|
+
throw error
|
1027
1123
|
}
|
1028
1124
|
|
1029
1125
|
const defaultInnerProcess = (config, errorHandler, responses) => {
|
@@ -1033,6 +1129,13 @@ const defaultInnerProcess = (config, errorHandler, responses) => {
|
|
1033
1129
|
}
|
1034
1130
|
console.log("KM's loaded", config.configs.map((c) => c.name))
|
1035
1131
|
console.log('This is the global objects from running semantics:\n', config.objects)
|
1132
|
+
if (!_.isEmpty(responses.learned_contextual_priorities)) {
|
1133
|
+
console.log('\nThe learned contextual priorties are :\n')
|
1134
|
+
for (const lcp of responses.learned_contextual_priorities) {
|
1135
|
+
console.log(` ${JSON.stringify(lcp)},\n`)
|
1136
|
+
}
|
1137
|
+
console.log("\n")
|
1138
|
+
}
|
1036
1139
|
if (responses.logs) {
|
1037
1140
|
console.log('Logs')
|
1038
1141
|
responses.logs.forEach((log) => console.log(` ${log}`))
|
@@ -1044,6 +1147,50 @@ const defaultInnerProcess = (config, errorHandler, responses) => {
|
|
1044
1147
|
} else {
|
1045
1148
|
console.log('objects', runtime.util.inspect(config.get('objects'), { depth: Infinity, sorted: true }))
|
1046
1149
|
}
|
1150
|
+
|
1151
|
+
const pickEm = () => {
|
1152
|
+
const picked = {}
|
1153
|
+
const namespaced = config.get('objects')['namespaced']
|
1154
|
+
for (let prop of getConfig_getObjectCheck(config.testConfig)) {
|
1155
|
+
if (prop.km) {
|
1156
|
+
/*
|
1157
|
+
const objects = namespaced[prop.km]]
|
1158
|
+
picked[prop.km] = {}
|
1159
|
+
for (let p of c.testConfig.check) {
|
1160
|
+
if (p.km) {
|
1161
|
+
continue
|
1162
|
+
}
|
1163
|
+
picked[p] = objects[p]
|
1164
|
+
}
|
1165
|
+
*/
|
1166
|
+
console.log('TODO implement this if needed')
|
1167
|
+
} else {
|
1168
|
+
const objects = namespaced[config.uuid]
|
1169
|
+
picked[prop] = objects[prop]
|
1170
|
+
}
|
1171
|
+
}
|
1172
|
+
return picked
|
1173
|
+
}
|
1174
|
+
|
1175
|
+
if (responses.explain_priorities) {
|
1176
|
+
console.log("Explain Priorities")
|
1177
|
+
for ([inputss, outpus, reason] of responses.explain_priorities) {
|
1178
|
+
console.log(` ${JSON.stringify(inputss)} reason: ${reason}`)
|
1179
|
+
}
|
1180
|
+
}
|
1181
|
+
const objects = config.get('objects').namespaced[config.uuid]
|
1182
|
+
const picked = sortJson(pickObjects(config.testConfig, objects), { depth: 25 })
|
1183
|
+
if (!_.isEmpty(picked)) {
|
1184
|
+
console.log('--- Object showing only the checked values ---')
|
1185
|
+
console.log(JSON.stringify(picked, null, 2))
|
1186
|
+
}
|
1187
|
+
|
1188
|
+
const pickedResultContexts = responses.contexts.map(pickContext(config.testConfig))
|
1189
|
+
if (pickedResultContexts.some( (context) => Object.keys(context).length > 0 )) {
|
1190
|
+
console.log('--- Contexts showing only the checked values ---')
|
1191
|
+
console.log(JSON.stringify(pickedResultContexts, null, 2))
|
1192
|
+
}
|
1193
|
+
|
1047
1194
|
console.log('--- The contexts are ----------')
|
1048
1195
|
console.log(JSON.stringify(sortJson(responses.contexts, { depth: 25 }), null, 2))
|
1049
1196
|
console.log('')
|
@@ -1084,37 +1231,14 @@ const defaultProcess = ({ config, errorHandler }) => async (promise) => {
|
|
1084
1231
|
}
|
1085
1232
|
}
|
1086
1233
|
|
1087
|
-
|
1088
|
-
const
|
1089
|
-
`const entodicton = require('entodicton')
|
1090
|
-
const base = require('./${kmBaseName}').copy()
|
1091
|
-
const ${kmName}_tests = require('./${kmName}.test.json')
|
1092
|
-
const ${kmName}_instance = require('./${kmBaseName}.${kmName}.instance.json')
|
1093
|
-
|
1094
|
-
const config = new entodicton.Config({ name: '${kmName}' })
|
1095
|
-
config.add(base)
|
1096
|
-
kirk_instance.base = '${kmBaseName}'
|
1097
|
-
config.load(${kmName}_instance)
|
1098
|
-
|
1099
|
-
entodicton.knowledgeModule( {
|
1100
|
-
module,
|
1101
|
-
description: '${kmName} related concepts',
|
1102
|
-
section,
|
1103
|
-
config,
|
1104
|
-
test: {
|
1105
|
-
name: './${kmName}.test.json',
|
1106
|
-
contents: ${kmName}_tests
|
1107
|
-
},
|
1108
|
-
})
|
1109
|
-
`
|
1110
|
-
*/
|
1111
|
-
|
1112
|
-
const build = async ({ config, target, template, errorHandler = defaultErrorHandler }) => {
|
1234
|
+
// builtTemplate saveInstance
|
1235
|
+
const rebuildTemplate = async ({ config, target, template, errorHandler = defaultErrorHandler }) => {
|
1113
1236
|
const accumulators = {
|
1114
1237
|
resultss: [],
|
1115
1238
|
fragments: [],
|
1116
1239
|
semantics: [],
|
1117
1240
|
associations: [],
|
1241
|
+
learned_contextual_priorities: [],
|
1118
1242
|
}
|
1119
1243
|
const looper = async (queries) => {
|
1120
1244
|
if (queries.length === 0) {
|
@@ -1133,8 +1257,6 @@ const build = async ({ config, target, template, errorHandler = defaultErrorHand
|
|
1133
1257
|
if (property == 'fragments') {
|
1134
1258
|
global.transitoryMode = true
|
1135
1259
|
}
|
1136
|
-
// greg32
|
1137
|
-
// config.addInternal( query )
|
1138
1260
|
if (hierarchy) {
|
1139
1261
|
for (let edge of hierarchy) {
|
1140
1262
|
if (Array.isArray(edge)) {
|
@@ -1144,25 +1266,28 @@ const build = async ({ config, target, template, errorHandler = defaultErrorHand
|
|
1144
1266
|
}
|
1145
1267
|
}
|
1146
1268
|
}
|
1147
|
-
|
1148
1269
|
try {
|
1149
|
-
const results = await _process(config, query.query, {initializer})
|
1270
|
+
const results = await _process(config, query.query, {initializer, rebuildingTemplate: true})
|
1150
1271
|
if (config.config.debug) {
|
1151
1272
|
// TODO pass in the error handler like the other ones
|
1152
1273
|
defaultInnerProcess(config, defaultErrorHandler, results)
|
1153
1274
|
}
|
1154
1275
|
if (results.contexts.length > 1) {
|
1155
|
-
console.log(`query ${query.query}. There is ${results.contexts.length} contexts in the results. Make sure its producing the results that you expect.`)
|
1276
|
+
console.log(`query "${query.query}". There is ${results.contexts.length} contexts in the results. Make sure its producing the results that you expect.`)
|
1277
|
+
} else if (results.paraphrases[0] != query.query) {
|
1278
|
+
console.log(`query "${query.query}". The paraphrase is different from the query "${results.paraphrases[0]}".`)
|
1156
1279
|
} else {
|
1157
1280
|
console.log(`query ${query.query}`)
|
1158
1281
|
}
|
1159
1282
|
global.transitoryMode = transitoryMode
|
1160
1283
|
config.config.skipSemantics = null
|
1161
1284
|
results.query = query.query
|
1285
|
+
results.skipSemantics = skipSemantics
|
1162
1286
|
results.development = query.development
|
1163
1287
|
results.key = { query: query.query, hierarchy }
|
1164
1288
|
accumulators[property].push(results)
|
1165
1289
|
accumulators.associations = accumulators.associations.concat(results.associations)
|
1290
|
+
accumulators.learned_contextual_priorities = accumulators.learned_contextual_priorities.concat(results.learned_contextual_priorities)
|
1166
1291
|
await looper(queries)
|
1167
1292
|
} catch(e) {
|
1168
1293
|
const error = { errors: [e], query: query.query };
|
@@ -1174,6 +1299,12 @@ const build = async ({ config, target, template, errorHandler = defaultErrorHand
|
|
1174
1299
|
// it will just get added to the config
|
1175
1300
|
const extraConfig = queryOrExtraConfig
|
1176
1301
|
console.log('config', extraConfig)
|
1302
|
+
try {
|
1303
|
+
config.addInternal(_.cloneDeep(extraConfig), { handleCalculatedProps: true } )
|
1304
|
+
} catch ( e ) {
|
1305
|
+
const where = extraConfig.where ? ` ${extraConfig.where}` : ''
|
1306
|
+
throw new Error(`Error processing extra config${where}: ${e.stack}}`)
|
1307
|
+
}
|
1177
1308
|
accumulators[property].push({ extraConfig: true, ...extraConfig })
|
1178
1309
|
await looper(queries)
|
1179
1310
|
}
|
@@ -1201,6 +1332,7 @@ const build = async ({ config, target, template, errorHandler = defaultErrorHand
|
|
1201
1332
|
delete result.version
|
1202
1333
|
result.hierarchy.sort()
|
1203
1334
|
stabilizeAssociations(result.associations)
|
1335
|
+
result.learned_contextual_priorities = safeNoDups(result.learned_contextual_priorities)
|
1204
1336
|
}
|
1205
1337
|
}
|
1206
1338
|
}
|
@@ -1221,14 +1353,14 @@ const build = async ({ config, target, template, errorHandler = defaultErrorHand
|
|
1221
1353
|
|
1222
1354
|
const toProperties = (queryStringOrProperties) => {
|
1223
1355
|
if (typeof queryStringOrProperties == 'string') {
|
1224
|
-
return { query: queryStringOrProperties}
|
1356
|
+
return { query: queryStringOrProperties }
|
1225
1357
|
} else {
|
1226
1358
|
return queryStringOrProperties
|
1227
1359
|
}
|
1228
1360
|
}
|
1229
1361
|
let todo = []
|
1230
|
-
todo = todo.concat((template.initializers || []).map((query) => { return { initializer: true, property: 'resultss', query, skipSemantics: false } }))
|
1231
|
-
todo = todo.concat((template.queries || []).map((query) => { return { property: 'resultss', query, skipSemantics: false } }))
|
1362
|
+
todo = todo.concat((template.initializers || []).map((query) => { return { initializer: true, property: 'resultss', query, skipSemantics: false || query.skipSemantics } }))
|
1363
|
+
todo = todo.concat((template.queries || []).map((query) => { return { property: 'resultss', query, skipSemantics: false || query.skipSemantics} }))
|
1232
1364
|
todo = todo.concat((template.fragments || []).map((query) => { return Object.assign({}, toProperties(query), { property: 'fragments', skipSemantics: false }) }))
|
1233
1365
|
todo = todo.concat((template.semantics || []).map((definition) => { return { property: 'semantics', query: `${definition.from}\n${definition.to}`, skipSemantics: true } }))
|
1234
1366
|
await looper(Object.assign([], todo))
|
@@ -1238,114 +1370,86 @@ const knowledgeModule = async ({
|
|
1238
1370
|
module: moduleFromJSFile,
|
1239
1371
|
description,
|
1240
1372
|
section,
|
1241
|
-
config,
|
1373
|
+
// config, createConfig,
|
1374
|
+
createConfig,
|
1375
|
+
newWay,
|
1242
1376
|
demo,
|
1243
1377
|
test,
|
1244
1378
|
template,
|
1245
1379
|
errorHandler = defaultErrorHandler,
|
1246
1380
|
process: processResults = defaultProcess,
|
1247
1381
|
stopAtFirstFailure = true,
|
1248
|
-
|
1249
|
-
beforeTests = () => {},
|
1250
|
-
afterTests = () => {},
|
1251
|
-
beforeTest = () => {},
|
1252
|
-
afterTest = () => {}
|
1382
|
+
...rest
|
1253
1383
|
} = {}) => {
|
1254
1384
|
|
1255
|
-
|
1256
|
-
|
1257
|
-
|
1258
|
-
|
1259
|
-
config.afterTest = afterTest
|
1385
|
+
const unknownArgs = Object.keys(rest)
|
1386
|
+
if (unknownArgs.length > 0) {
|
1387
|
+
throw new Error(`Unknown arguments to knowledgeModule: ${unknownArgs.join()}`)
|
1388
|
+
}
|
1260
1389
|
|
1261
1390
|
const testConfig = test
|
1262
1391
|
|
1263
1392
|
if (!moduleFromJSFile) {
|
1264
|
-
throw "'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."
|
1265
|
-
}
|
1266
|
-
if (!config) {
|
1267
|
-
throw "'config' is a required parameter. The value should the config that defines the knowledge module."
|
1393
|
+
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.")
|
1268
1394
|
}
|
1269
|
-
if (!config
|
1270
|
-
|
1395
|
+
// if (!config && !createConfig) {
|
1396
|
+
if (!createConfig) {
|
1397
|
+
throw new Error("'config' or 'createConfig' is a required parameter. The value should the config that defines the knowledge module.")
|
1271
1398
|
}
|
1272
1399
|
if (!description) {
|
1273
|
-
throw "'description' is a required parameter. The value should the description of the knowledge module."
|
1400
|
+
throw new Error("'description' is a required parameter. The value should the description of the knowledge module.")
|
1274
1401
|
}
|
1275
1402
|
if (!test) {
|
1276
|
-
throw "'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> }."
|
1403
|
+
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> }.")
|
1277
1404
|
}
|
1278
1405
|
|
1279
1406
|
const isProcess = require.main === moduleFromJSFile
|
1280
|
-
|
1281
|
-
|
1282
|
-
if (
|
1283
|
-
|
1407
|
+
|
1408
|
+
const setupConfig = (config) => {
|
1409
|
+
if (!config.name) {
|
1410
|
+
throw new Error("config must have 'name' set to the knowledge module name.")
|
1284
1411
|
}
|
1285
|
-
}
|
1286
1412
|
|
1287
|
-
|
1288
|
-
|
1289
|
-
|
1290
|
-
|
1291
|
-
|
1292
|
-
} else {
|
1293
|
-
return true
|
1294
|
-
}
|
1295
|
-
})
|
1296
|
-
config.config.bridges = config.config.bridges.filter( (bridge) => {
|
1297
|
-
if (bridge.development) {
|
1298
|
-
return false
|
1299
|
-
} else {
|
1300
|
-
return true
|
1413
|
+
config.description = description
|
1414
|
+
if (typeof test === 'object') {
|
1415
|
+
if (test.contents) {
|
1416
|
+
config.tests = test.contents
|
1417
|
+
test = test.name
|
1301
1418
|
}
|
1302
|
-
})
|
1303
|
-
}
|
1304
|
-
|
1305
|
-
let module
|
1306
|
-
if (_.isFunction(moduleFromJSFile)) {
|
1307
|
-
module = moduleFromJSFile
|
1308
|
-
} else {
|
1309
|
-
module = () => {
|
1310
|
-
config.rebuild({ isModule: true })
|
1311
|
-
moduleFromJSFile.exports = config
|
1312
|
-
}
|
1313
|
-
}
|
1314
|
-
processResults = processResults({ config, errorHandler })
|
1315
|
-
config.description = description
|
1316
|
-
config.demo = demo
|
1317
|
-
if (typeof test === 'object') {
|
1318
|
-
if (test.contents) {
|
1319
|
-
config.tests = test.contents
|
1320
|
-
test = test.name
|
1321
|
-
}
|
1322
|
-
} else {
|
1323
|
-
if (runtime.fs && runtime.fs.existsSync(test)) {
|
1324
|
-
config.tests = JSON.parse(runtime.fs.readFileSync(test))
|
1325
1419
|
} else {
|
1326
|
-
|
1327
|
-
|
1328
|
-
|
1329
|
-
|
1330
|
-
|
1331
|
-
if (!isProcess) {
|
1332
|
-
if (template) {
|
1333
|
-
if (config.needsRebuild(template.template, template.instance)) {
|
1334
|
-
throw `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.`
|
1420
|
+
if (runtime.fs && runtime.fs.existsSync(test)) {
|
1421
|
+
config.tests = JSON.parse(runtime.fs.readFileSync(test))
|
1422
|
+
} else {
|
1423
|
+
config.tests = []
|
1335
1424
|
}
|
1336
|
-
config.load(template.template, template.instance)
|
1337
1425
|
}
|
1426
|
+
config.setTestConfig(testConfig)
|
1338
1427
|
}
|
1428
|
+
|
1429
|
+
|
1339
1430
|
if (isProcess) {
|
1431
|
+
const config = createConfig()
|
1432
|
+
setupConfig(config)
|
1433
|
+
processResults = processResults({ config, errorHandler })
|
1340
1434
|
// setup();
|
1341
1435
|
const parser = new runtime.ArgumentParser({
|
1342
1436
|
description: 'Entodicton knowledge module'
|
1343
1437
|
})
|
1344
1438
|
|
1439
|
+
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]]\''
|
1440
|
+
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]]\''
|
1441
|
+
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]]\''
|
1442
|
+
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}\''
|
1443
|
+
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\''
|
1444
|
+
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]))\''
|
1445
|
+
|
1446
|
+
|
1345
1447
|
parser.add_argument('-tmn', '--testModuleName', { help: 'When running tests instead of using the current modules tests use the specified modules tests' })
|
1346
1448
|
parser.add_argument('-t', '--test', { action: 'store_true', help: 'Run the tests. Create tests by running with the --query + --save flag' })
|
1347
1449
|
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' })
|
1450
|
+
// parser.add_argument('-ttr', '--testToRun', { help: 'Only the specified test will be run' })
|
1348
1451
|
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' })
|
1452
|
+
parser.add_argument('-tnp', '--testNoParenthesized', { action: 'store_true', help: 'Don\' check parenthesized differences for the tests' })
|
1349
1453
|
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' })
|
1350
1454
|
// 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.' })
|
1351
1455
|
parser.add_argument('-rt', '--rebuildTemplate', { action: 'store_true', help: 'Force a template rebuild' })
|
@@ -1353,45 +1457,84 @@ const knowledgeModule = async ({
|
|
1353
1457
|
parser.add_argument('-i', '--info', { action: 'store_true', help: 'Print meta-data for the module' })
|
1354
1458
|
parser.add_argument('-v', '--vimdiff', { action: 'store_true', help: 'For failures run vimdiff' })
|
1355
1459
|
parser.add_argument('-g', '--greg', { action: 'store_true', help: 'Set the server to be localhost so I can debug stuff' })
|
1356
|
-
parser.add_argument('-cl', '--checkForLoop', {
|
1460
|
+
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]]' })
|
1357
1461
|
parser.add_argument('-r', '--retrain', { action: 'store_true', help: 'Get the server to retrain the neural nets' })
|
1358
1462
|
parser.add_argument('-q', '--query', { help: 'Run the specified query' })
|
1359
1463
|
parser.add_argument('-ip ', '--server', { help: 'Server to run against' })
|
1360
1464
|
parser.add_argument('-qp ', '--queryParams', { help: 'Query params for the server call' })
|
1361
1465
|
parser.add_argument('-dt', '--deleteTest', { help: 'Delete the specified query from the tests file.' })
|
1466
|
+
parser.add_argument('--parenthesized', { action: 'store_true', help: 'Show the generated phrases with parenthesis.' })
|
1362
1467
|
parser.add_argument('-c', '--clean', { help: 'Remove data from the test files. a === association' })
|
1363
1468
|
parser.add_argument('-od', '--objectDiff', { action: 'store_true', help: 'When showing the objects use a colour diff' })
|
1364
1469
|
parser.add_argument('-daa', '--dontAddAssociations', { action: 'store_true', help: 'Do not add associations from the tests.' })
|
1365
1470
|
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' })
|
1366
1471
|
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.' })
|
1367
1472
|
parser.add_argument('-sd', '--saveDeveloper', { action: 'store_true', help: 'Same as -s but the query will not show up in the info command.' })
|
1368
|
-
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' })
|
1369
1473
|
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 '})
|
1370
1474
|
parser.add_argument('-d', '--debug', { action: 'store_true', help: 'When running with the --debug flag this set the debug flag in the config' })
|
1371
|
-
parser.add_argument('-da', '--debugAssociation', {
|
1372
|
-
parser.add_argument('-dh', '--debugHierarchy', {
|
1373
|
-
parser.add_argument('-
|
1374
|
-
parser.add_argument('-
|
1475
|
+
parser.add_argument('-da', '--debugAssociation', { action: 'store_true', help: helpDebugAssociation })
|
1476
|
+
parser.add_argument('-dh', '--debugHierarchy', { action: 'store_true', help: helpDebugHierarchy })
|
1477
|
+
parser.add_argument('-dp', '--debugPriority', { action: 'store_true', help: helpDebugPriority })
|
1478
|
+
parser.add_argument('-dcp', '--debugContextualPriority', { action: 'store_true', help: helpDebugContextualPriority })
|
1479
|
+
parser.add_argument('-db', '--debugBridge', { action: 'store_true', help: helpDebugBridge })
|
1480
|
+
parser.add_argument('-do', '--debugOperator', { action: 'store_true', help: helpDebugOperator })
|
1481
|
+
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"})
|
1482
|
+
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' })
|
1375
1483
|
|
1376
1484
|
const args = parser.parse_args()
|
1377
1485
|
args.count = args.count || 1
|
1378
1486
|
|
1487
|
+
if (args.parenthesized) {
|
1488
|
+
config.parenthesized = true
|
1489
|
+
}
|
1490
|
+
if (args.checkForLoop) {
|
1491
|
+
try {
|
1492
|
+
args.checkForLoop = JSON.parse(args.checkForLoop)
|
1493
|
+
const isKey = (what) => {
|
1494
|
+
if (!Array.isArray(what)) {
|
1495
|
+
return false
|
1496
|
+
}
|
1497
|
+
if (what.length !== 2) {
|
1498
|
+
return false
|
1499
|
+
}
|
1500
|
+
if (!typeof what[0] == 'string') {
|
1501
|
+
return false
|
1502
|
+
}
|
1503
|
+
if (!typeof what[1] == 'number') {
|
1504
|
+
return false
|
1505
|
+
}
|
1506
|
+
return true
|
1507
|
+
}
|
1508
|
+
if (!Array.isArray(args.checkForLoop) || args.checkForLoop.some((value) => !isKey(value))) {
|
1509
|
+
throw new Error(`Error for the checkForLoop argument. Expected a JSON array of operator keys of the form "[<id>, <level>]"`)
|
1510
|
+
}
|
1511
|
+
} catch( e ) {
|
1512
|
+
throw new Error(`Error parsing JSON of the checkForLoop argument. ${e}`)
|
1513
|
+
}
|
1514
|
+
} else {
|
1515
|
+
if (process.argv.includes('--checkForLoop') || process.argv.includes('-cl')) {
|
1516
|
+
args.checkForLoop = true
|
1517
|
+
}
|
1518
|
+
}
|
1379
1519
|
if (args.debugAssociation) {
|
1380
|
-
|
1520
|
+
console.log(helpDebugAssociation)
|
1521
|
+
runtime.process.exit(-1)
|
1381
1522
|
}
|
1382
1523
|
if (args.debugHierarchy) {
|
1383
|
-
|
1524
|
+
console.log(helpDebugHierarchy)
|
1525
|
+
runtime.process.exit(-1)
|
1526
|
+
}
|
1527
|
+
if (args.debugPriority) {
|
1528
|
+
console.log(helpDebugPriority)
|
1529
|
+
runtime.process.exit(-1)
|
1384
1530
|
}
|
1385
1531
|
if (args.debugBridge) {
|
1386
|
-
|
1387
|
-
|
1388
|
-
if (global.entodictonDebugBridge.length !== 2) {
|
1389
|
-
console.log('Expected DEBUG_BRIDGE to be of the form "id/level"');
|
1390
|
-
}
|
1532
|
+
console.log(helpDebugBridge)
|
1533
|
+
runtime.process.exit(-1)
|
1391
1534
|
}
|
1392
1535
|
if (args.debugOperator) {
|
1393
|
-
|
1394
|
-
|
1536
|
+
console.log(helpDebugOperator)
|
1537
|
+
runtime.process.exit(-1)
|
1395
1538
|
}
|
1396
1539
|
|
1397
1540
|
if (args.clean) {
|
@@ -1430,120 +1573,122 @@ const knowledgeModule = async ({
|
|
1430
1573
|
if (args.debug) {
|
1431
1574
|
config.config.debug = true
|
1432
1575
|
}
|
1433
|
-
config.config.debugIncludeConvolutions = args.debugIncludeConvolutions
|
1434
1576
|
|
1435
|
-
if (
|
1436
|
-
|
1437
|
-
if (needsRebuild) {
|
1438
|
-
console.log(`This module "${config.name}" needs rebuilding all other arguments will be ignored. Try again after the template is rebuilt.`)
|
1439
|
-
|
1440
|
-
}
|
1441
|
-
config.load(template.template, template.instance, { rebuild: needsRebuild })
|
1442
|
-
if (needsRebuild) {
|
1443
|
-
return
|
1444
|
-
}
|
1577
|
+
if (args.explainPriorities) {
|
1578
|
+
config.config.explain_priorities = true
|
1445
1579
|
}
|
1446
1580
|
|
1447
|
-
|
1448
|
-
config.addAssociationsFromTests(config.tests);
|
1449
|
-
//for (let query in config.tests) {
|
1450
|
-
// config.addAssociations(config.tests[query].associations || []);
|
1451
|
-
//}
|
1452
|
-
}
|
1581
|
+
config.config.debugIncludeConvolutions = args.debugIncludeConvolutions || process.argv.includes('--debugIncludeConvolutions') || process.argv.includes('-dic')
|
1453
1582
|
|
1454
|
-
|
1455
|
-
|
1456
|
-
if (
|
1457
|
-
|
1458
|
-
config.load(template.template, template.instance, { rebuild: true })
|
1583
|
+
let configPrinted = false
|
1584
|
+
const printConfig = () => {
|
1585
|
+
if (configPrinted) {
|
1586
|
+
return
|
1459
1587
|
}
|
1460
|
-
|
1461
|
-
|
1462
|
-
|
1463
|
-
|
1464
|
-
|
1465
|
-
|
1466
|
-
|
1467
|
-
|
1468
|
-
|
1469
|
-
|
1588
|
+
configPrinted = true
|
1589
|
+
if (args.print) {
|
1590
|
+
if (args.print.includes('t')) {
|
1591
|
+
console.log("Test queries")
|
1592
|
+
let counter = 0
|
1593
|
+
for (const test of config.tests) {
|
1594
|
+
console.log(`${counter} - ${test.query}`)
|
1595
|
+
counter += 1
|
1596
|
+
}
|
1597
|
+
}
|
1598
|
+
if (args.print.includes('c')) {
|
1599
|
+
const { data } = setupProcessB({ config })
|
1600
|
+
console.log("Config as sent to server")
|
1601
|
+
console.log(JSON.stringify(data, null, 2));
|
1470
1602
|
}
|
1471
|
-
}
|
1472
|
-
if (args.print.includes('c')) {
|
1473
|
-
const { data } = setupProcessB({ config })
|
1474
|
-
console.log("Config as sent to server")
|
1475
|
-
console.log(JSON.stringify(data, null, 2));
|
1476
|
-
}
|
1477
1603
|
|
1478
|
-
|
1479
|
-
|
1480
|
-
|
1481
|
-
|
1604
|
+
if (args.print.includes('l')) {
|
1605
|
+
console.log('Module load ordering')
|
1606
|
+
for (const km of config.configs) {
|
1607
|
+
console.log(` ${km.name}`)
|
1608
|
+
}
|
1482
1609
|
}
|
1483
|
-
|
1484
|
-
|
1485
|
-
|
1486
|
-
|
1610
|
+
if (args.print.includes('w')) {
|
1611
|
+
for (const word in config.config.words) {
|
1612
|
+
console.log(word.concat(' ', ...config.config.words[word].map((def) => JSON.stringify(def))))
|
1613
|
+
}
|
1487
1614
|
}
|
1488
|
-
|
1489
|
-
|
1490
|
-
|
1491
|
-
|
1615
|
+
if (args.print.includes('b')) {
|
1616
|
+
for (const bridge of config.config.bridges) {
|
1617
|
+
console.log(JSON.stringify(bridge))
|
1618
|
+
}
|
1492
1619
|
}
|
1493
|
-
|
1494
|
-
|
1495
|
-
|
1496
|
-
|
1620
|
+
if (args.print.includes('o')) {
|
1621
|
+
for (const operator of config.config.operators) {
|
1622
|
+
console.log(JSON.stringify(operator))
|
1623
|
+
}
|
1497
1624
|
}
|
1498
|
-
|
1499
|
-
|
1500
|
-
|
1501
|
-
|
1502
|
-
|
1503
|
-
|
1504
|
-
|
1505
|
-
|
1506
|
-
|
1507
|
-
|
1508
|
-
|
1509
|
-
|
1625
|
+
if (args.print.includes('j')) {
|
1626
|
+
const { data } = setupProcessB( { config } )
|
1627
|
+
console.log(JSON.stringify(data, null, 2))
|
1628
|
+
}
|
1629
|
+
if (args.print.includes('a')) {
|
1630
|
+
console.log('associations ================')
|
1631
|
+
const properties = ['negative', 'positive']
|
1632
|
+
for (let property of properties) {
|
1633
|
+
console.log(` ${property} ===============`)
|
1634
|
+
for (let association of config.config.associations[property]) {
|
1635
|
+
console.log(` ${JSON.stringify(association)}`)
|
1636
|
+
}
|
1510
1637
|
}
|
1511
1638
|
}
|
1512
|
-
|
1513
|
-
|
1514
|
-
console.log(JSON.stringify(config.config.objects, null, 2))
|
1515
|
-
}
|
1516
|
-
if (args.print.includes('p')) {
|
1517
|
-
for (let priority of config.config.priorities) {
|
1518
|
-
console.log(JSON.stringify(priority))
|
1639
|
+
if (args.print.includes('d')) {
|
1640
|
+
console.log(JSON.stringify(config.config.objects, null, 2))
|
1519
1641
|
}
|
1520
|
-
|
1521
|
-
|
1522
|
-
|
1523
|
-
|
1642
|
+
if (args.print.includes('p')) {
|
1643
|
+
for (let priority of config.config.priorities) {
|
1644
|
+
console.log(JSON.stringify(priority))
|
1645
|
+
}
|
1524
1646
|
}
|
1525
|
-
|
1526
|
-
|
1527
|
-
|
1528
|
-
for (const semantic of easyToRead) {
|
1529
|
-
semantic.match = semantic.match.toString()
|
1530
|
-
semantic.apply = semantic.apply.toString()
|
1531
|
-
if (semantic.applyWrapped) {
|
1532
|
-
semantic.applyWrapped = semantic.applyWrapped.toString()
|
1647
|
+
if (args.print.includes('h')) {
|
1648
|
+
for (let edge of config.config.hierarchy) {
|
1649
|
+
console.log(JSON.stringify(edge))
|
1533
1650
|
}
|
1534
1651
|
}
|
1535
|
-
|
1536
|
-
|
1537
|
-
|
1538
|
-
|
1539
|
-
|
1540
|
-
|
1541
|
-
|
1652
|
+
if (args.print.includes('g')) {
|
1653
|
+
const easyToRead = _.cloneDeep(config.config.generators)
|
1654
|
+
for (const semantic of easyToRead) {
|
1655
|
+
semantic.match = semantic.match.toString()
|
1656
|
+
semantic.apply = semantic.apply.toString()
|
1657
|
+
if (semantic.applyWrapped) {
|
1658
|
+
semantic.applyWrapped = semantic.applyWrapped.toString()
|
1659
|
+
}
|
1660
|
+
}
|
1661
|
+
console.dir(easyToRead)
|
1542
1662
|
}
|
1543
|
-
|
1663
|
+
if (args.print.includes('s')) {
|
1664
|
+
const easyToRead = _.cloneDeep(config.config.semantics)
|
1665
|
+
for (const semantic of easyToRead) {
|
1666
|
+
semantic.match = semantic.match.toString()
|
1667
|
+
semantic.apply = semantic.apply.toString()
|
1668
|
+
}
|
1669
|
+
console.dir(easyToRead)
|
1670
|
+
}
|
1671
|
+
}
|
1672
|
+
}
|
1673
|
+
|
1674
|
+
if (template) {
|
1675
|
+
const needsRebuild = config.needsRebuild(template.template, template.instance, options)
|
1676
|
+
if (needsRebuild) {
|
1677
|
+
console.log(`This module "${config.name}" needs rebuilding all other arguments will be ignored. Try again after the template is rebuilt.`)
|
1678
|
+
options.rebuild = true
|
1679
|
+
config.config.rebuild = true
|
1680
|
+
}
|
1681
|
+
config.load(template.template, template.instance, { rebuild: needsRebuild })
|
1682
|
+
printConfig()
|
1683
|
+
if (needsRebuild) {
|
1684
|
+
return
|
1544
1685
|
}
|
1545
1686
|
}
|
1546
1687
|
|
1688
|
+
if (!args.save && !args.rebuildTemplate && !args.dontAddAssociations) {
|
1689
|
+
config.addAssociationsFromTests(config.tests);
|
1690
|
+
}
|
1691
|
+
|
1547
1692
|
if (args.retrain) {
|
1548
1693
|
config.config.retrain = true
|
1549
1694
|
}
|
@@ -1575,12 +1720,7 @@ const knowledgeModule = async ({
|
|
1575
1720
|
test = useTestConfig.name
|
1576
1721
|
|
1577
1722
|
}
|
1578
|
-
runTests(config, test, { debug: args.debug, testConfig: useTestConfig, verbose: args.testVerbose || args.testAllVerbose, stopAtFirstError: !args.testAllVerbose }).then((results) => {
|
1579
|
-
if (results.length > 0 && args.vimdiff) {
|
1580
|
-
for (const result of results) {
|
1581
|
-
vimdiff(result.expected, result.actual)
|
1582
|
-
}
|
1583
|
-
}
|
1723
|
+
runTests(config, test, { args, debug: args.debug, testConfig: useTestConfig, verbose: args.testVerbose || args.testAllVerbose, stopAtFirstError: !args.testAllVerbose }).then((results) => {
|
1584
1724
|
let newError = false
|
1585
1725
|
if (results.length > 0) {
|
1586
1726
|
let headerShown = false
|
@@ -1590,18 +1730,49 @@ const knowledgeModule = async ({
|
|
1590
1730
|
if (JSON.stringify(result.expected.paraphrases) !== JSON.stringify(result.actual.paraphrases)) {
|
1591
1731
|
hasError = true
|
1592
1732
|
}
|
1733
|
+
if (!args.testNoParenthesized) {
|
1734
|
+
if (JSON.stringify(result.expected.paraphrasesParenthesized) !== JSON.stringify(result.actual.paraphrasesParenthesized)) {
|
1735
|
+
hasError = true
|
1736
|
+
}
|
1737
|
+
if (JSON.stringify(result.expected.generatedParenthesized) !== JSON.stringify(result.actual.generatedParenthesized)) {
|
1738
|
+
hasError = true
|
1739
|
+
}
|
1740
|
+
}
|
1593
1741
|
if (JSON.stringify(result.expected.responses) !== JSON.stringify(result.actual.responses)) {
|
1594
1742
|
hasError = true
|
1595
1743
|
}
|
1596
1744
|
if (JSON.stringify(result.expected.checked) !== JSON.stringify(result.actual.checked)) {
|
1597
1745
|
hasError = true
|
1598
1746
|
}
|
1747
|
+
if (!sameJSON(result.expected.checkedContexts, result.actual.checkedContexts)) {
|
1748
|
+
hasError = true
|
1749
|
+
}
|
1599
1750
|
}
|
1600
1751
|
|
1601
1752
|
if (hasError) {
|
1602
1753
|
console.log('**************************** ERRORS ************************')
|
1603
1754
|
for (const result of results) {
|
1604
1755
|
console.log('Utterance: ', result.utterance)
|
1756
|
+
const show = (label, expected, actual) => {
|
1757
|
+
if (JSON.stringify(expected) !== JSON.stringify(actual)) {
|
1758
|
+
if (!headerShown) {
|
1759
|
+
console.log(' Failure')
|
1760
|
+
}
|
1761
|
+
console.log(` expected ${label}`, expected)
|
1762
|
+
console.log(` actual ${label} `, actual)
|
1763
|
+
newError = true
|
1764
|
+
headerShown = true
|
1765
|
+
}
|
1766
|
+
}
|
1767
|
+
show('paraphrases', result.expected.paraphrases, result.actual.paraphrases)
|
1768
|
+
if (!args.testNoParenthesized) {
|
1769
|
+
show('paraphrases parenthesized', result.expected.paraphrasesParenthesized, result.actual.paraphrasesParenthesized)
|
1770
|
+
}
|
1771
|
+
show('responses', result.expected.responses, result.actual.responses)
|
1772
|
+
if (!args.testNoParenthesized) {
|
1773
|
+
show('responses parenthesized', result.expected.generatedParenthesized, result.actual.generatedParenthesized)
|
1774
|
+
}
|
1775
|
+
/*
|
1605
1776
|
if (JSON.stringify(result.expected.paraphrases) !== JSON.stringify(result.actual.paraphrases)) {
|
1606
1777
|
if (!headerShown) {
|
1607
1778
|
console.log(' Failure')
|
@@ -1620,6 +1791,7 @@ const knowledgeModule = async ({
|
|
1620
1791
|
newError = true
|
1621
1792
|
headerShown = true
|
1622
1793
|
}
|
1794
|
+
*/
|
1623
1795
|
if (JSON.stringify(result.expected.checked) !== JSON.stringify(result.actual.checked)) {
|
1624
1796
|
if (!headerShown) {
|
1625
1797
|
console.log(' Failure')
|
@@ -1632,10 +1804,37 @@ const knowledgeModule = async ({
|
|
1632
1804
|
lines.setElement(1, 1, 'actual checked')
|
1633
1805
|
lines.setElement(2, 2, JSON.stringify(result.actual.checked, null, 2))
|
1634
1806
|
lines.log()
|
1807
|
+
if (args.vimdiff) {
|
1808
|
+
vimdiff(result.actual.checked, result.expected.checked)
|
1809
|
+
}
|
1810
|
+
newError = true
|
1811
|
+
headerShown = true
|
1812
|
+
}
|
1813
|
+
if (!sameJSON(result.expected.checkedContexts, result.actual.checkedContexts)) {
|
1814
|
+
if (!headerShown) {
|
1815
|
+
console.log(' Failure')
|
1816
|
+
}
|
1817
|
+
const widths = [4, 18, 72]
|
1818
|
+
const lines = new Lines(widths)
|
1819
|
+
lines.setElement(1, 1, 'expected checkedContexts', true)
|
1820
|
+
lines.setElement(2, 2, JSON.stringify(result.expected.checkedContexts, null, 2))
|
1821
|
+
lines.log()
|
1822
|
+
lines.setElement(1, 1, 'actual checkedContexts', true)
|
1823
|
+
lines.setElement(2, 2, JSON.stringify(result.actual.checkedContexts, null, 2))
|
1824
|
+
lines.log()
|
1825
|
+
if (args.vimdiff) {
|
1826
|
+
vimdiff(result.actual.checkedContexts, result.expected.checkedContexts)
|
1827
|
+
}
|
1635
1828
|
newError = true
|
1636
1829
|
headerShown = true
|
1637
1830
|
}
|
1638
1831
|
}
|
1832
|
+
} else {
|
1833
|
+
if (results.length > 0 && args.vimdiff) {
|
1834
|
+
for (const result of results) {
|
1835
|
+
vimdiff(result.actual, result.expected)
|
1836
|
+
}
|
1837
|
+
}
|
1639
1838
|
}
|
1640
1839
|
if (!headerShown) {
|
1641
1840
|
if (!(useTestConfig.check && useTestConfig.check.length > 0)) {
|
@@ -1667,12 +1866,11 @@ const knowledgeModule = async ({
|
|
1667
1866
|
if (query.length === 0) {
|
1668
1867
|
return readline.close()
|
1669
1868
|
}
|
1670
|
-
// const promise = processResults(_process(config, query, { testsFN: test }))
|
1671
1869
|
const promise = _process(config, query, { testsFN: test }).then((results) => {
|
1672
1870
|
console.log(results.responses.join(' '))
|
1673
1871
|
})
|
1674
1872
|
if (!('then' in promise)) {
|
1675
|
-
throw 'Return a promise from process in the definition of knowledgeModule'
|
1873
|
+
throw new Error('Return a promise from process in the definition of knowledgeModule')
|
1676
1874
|
}
|
1677
1875
|
promise
|
1678
1876
|
.then(() => {
|
@@ -1695,20 +1893,65 @@ const knowledgeModule = async ({
|
|
1695
1893
|
if (args.objectDiff) {
|
1696
1894
|
global.beforeObjects = _.cloneDeep(objects)
|
1697
1895
|
}
|
1698
|
-
config.beforeQuery({ query: args.query, isModule: false, objects })
|
1699
1896
|
try {
|
1700
|
-
processResults(_process(config, args.query, { commandLineArgs: args, dontAddAssociations: args.dontAddAssociations, writeTests: args.save || args.saveDeveloper, saveDeveloper: args.saveDeveloper, testConfig, testsFN: test }))
|
1897
|
+
await processResults(_process(config, args.query, { commandLineArgs: args, dontAddAssociations: args.dontAddAssociations, writeTests: args.save || args.saveDeveloper, saveDeveloper: args.saveDeveloper, testConfig, testsFN: test }))
|
1701
1898
|
} catch( error ) {
|
1702
1899
|
console.log('Error', error);
|
1703
1900
|
}
|
1704
1901
|
}
|
1902
|
+
printConfig()
|
1705
1903
|
} else {
|
1706
|
-
|
1707
|
-
|
1708
|
-
|
1709
|
-
|
1710
|
-
|
1904
|
+
const initConfig = (config) => {
|
1905
|
+
setupConfig(config)
|
1906
|
+
|
1907
|
+
let loadForTesting = false
|
1908
|
+
if (global.theprogrammablemind) {
|
1909
|
+
if (global.theprogrammablemind.loadForTesting[config.name]) {
|
1910
|
+
loadForTesting = true
|
1911
|
+
}
|
1912
|
+
}
|
1913
|
+
// remove test only stuff
|
1914
|
+
if (!isProcess && !loadForTesting) {
|
1915
|
+
config.config.operators = config.config.operators.filter( (operator) => {
|
1916
|
+
if (operator.development) {
|
1917
|
+
return false
|
1918
|
+
} else {
|
1919
|
+
return true
|
1920
|
+
}
|
1921
|
+
})
|
1922
|
+
config.config.bridges = config.config.bridges.filter( (bridge) => {
|
1923
|
+
if (bridge.development) {
|
1924
|
+
return false
|
1925
|
+
} else {
|
1926
|
+
return true
|
1927
|
+
}
|
1928
|
+
})
|
1929
|
+
}
|
1930
|
+
|
1931
|
+
if (template) {
|
1932
|
+
if (config.needsRebuild(template.template, template.instance, { isModule: !isProcess })) {
|
1933
|
+
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.`
|
1934
|
+
throw new Error(error)
|
1935
|
+
}
|
1936
|
+
try {
|
1937
|
+
config.load(template.template, template.instance)
|
1938
|
+
} catch( e ) {
|
1939
|
+
errorHandler(e)
|
1940
|
+
}
|
1941
|
+
}
|
1942
|
+
|
1943
|
+
config.addAssociationsFromTests(config.tests);
|
1944
|
+
}
|
1945
|
+
|
1946
|
+
createConfigExport = () => {
|
1947
|
+
const config = createConfig()
|
1948
|
+
initConfig(config)
|
1949
|
+
config.rebuild({ isModule: true })
|
1950
|
+
return config
|
1951
|
+
}
|
1952
|
+
moduleFromJSFile.exports = createConfigExport
|
1711
1953
|
}
|
1954
|
+
|
1712
1955
|
}
|
1713
1956
|
|
1714
1957
|
/*
|
@@ -1762,7 +2005,7 @@ module.exports = {
|
|
1762
2005
|
w,
|
1763
2006
|
// submitBug,
|
1764
2007
|
ensureTestFile,
|
1765
|
-
|
2008
|
+
rebuildTemplate,
|
1766
2009
|
processContext,
|
1767
2010
|
processContexts,
|
1768
2011
|
runTests,
|
@@ -1774,8 +2017,9 @@ module.exports = {
|
|
1774
2017
|
Digraph,
|
1775
2018
|
analyzeMetaData,
|
1776
2019
|
processContextsB,
|
1777
|
-
|
2020
|
+
loadInstance,
|
1778
2021
|
gs,
|
1779
2022
|
flattens,
|
1780
2023
|
writeTest
|
1781
2024
|
}
|
2025
|
+
|