theprogrammablemind 7.12.4 → 7.12.5
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 +226 -108
- package/package.json +1 -1
- package/src/config.js +36 -12
- package/src/helpers.js +8 -0
- package/src/semantics.js +11 -1
package/client.js
CHANGED
@@ -10,12 +10,47 @@ const _ = require('lodash')
|
|
10
10
|
const stringify = require('json-stable-stringify')
|
11
11
|
const Lines = require('./lines')
|
12
12
|
const flattens = require('./src/flatten')
|
13
|
-
const { appendNoDups, InitCalls, updateQueries, safeNoDups } = require('./src/helpers')
|
13
|
+
const { appendNoDups, InitCalls, updateQueries, safeNoDups, stableId } = require('./src/helpers')
|
14
14
|
const runtime = require('./runtime')
|
15
15
|
const sortJson = runtime.sortJson
|
16
16
|
|
17
|
-
|
18
|
-
|
17
|
+
function where (goUp = 2) {
|
18
|
+
const e = new Error()
|
19
|
+
const regexForm1 = /\((.*):(\d+):(\d+)\)$/
|
20
|
+
const regexForm2 = /at (.*):(\d+):(\d+)$/
|
21
|
+
const lines = e.stack.split('\n')
|
22
|
+
let line
|
23
|
+
let match
|
24
|
+
for (line of lines.slice(1)) {
|
25
|
+
// if (!(line.includes('config.js:') || line.includes('client.js:') || line.includes('<anonymous>'))) {
|
26
|
+
if (!(line.includes('config.js:') || line.includes('client.js:'))) {
|
27
|
+
match = regexForm1.exec(line) || regexForm2.exec(line)
|
28
|
+
if (!match) {
|
29
|
+
continue
|
30
|
+
}
|
31
|
+
break
|
32
|
+
}
|
33
|
+
}
|
34
|
+
// const line = e.stack.split("\n")[goUp];
|
35
|
+
// const match = regexForm1.exec(line) || regexForm2.exec(line)
|
36
|
+
if (match) {
|
37
|
+
return `${match[1]}:${match[2]}`
|
38
|
+
} else {
|
39
|
+
return 'running in browser'
|
40
|
+
}
|
41
|
+
}
|
42
|
+
|
43
|
+
const getConfig_getObjectsCheck = (config, testConfig) => {
|
44
|
+
let testConfigName = config.name
|
45
|
+
if (testConfig.testModuleName) {
|
46
|
+
testConfigName = testConfig.testModuleName
|
47
|
+
}
|
48
|
+
const checks = (testConfig.checks && testConfig.checks.objects) || []
|
49
|
+
if (Array.isArray(checks)) {
|
50
|
+
return { [testConfigName]: checks }
|
51
|
+
} else {
|
52
|
+
return checks
|
53
|
+
}
|
19
54
|
}
|
20
55
|
|
21
56
|
const getConfig_getContextCheck = (testConfig) => {
|
@@ -26,61 +61,122 @@ const pickContext = (testConfig) => (context) => {
|
|
26
61
|
return project(context, getConfig_getContextCheck(testConfig))
|
27
62
|
}
|
28
63
|
|
29
|
-
const pickObjects = (testConfig,
|
30
|
-
|
64
|
+
const pickObjects = (config, testConfig, getObjects) => {
|
65
|
+
/*
|
66
|
+
let testConfigName = config.name
|
67
|
+
if (testConfig.testModuleName) {
|
68
|
+
objects = getObjects(config.config.objects)(config.getConfigs()[testConfig.testModuleName].uuid)
|
69
|
+
testConfigName = testConfig.testModuleName
|
70
|
+
}
|
71
|
+
*/
|
72
|
+
const checks = getConfig_getObjectsCheck(config, testConfig)
|
73
|
+
const projection = {}
|
74
|
+
for (let km in checks) {
|
75
|
+
const objects = getObjects(km)
|
76
|
+
if (!objects) {
|
77
|
+
throw new Error(`In the checks for ${config.name} the KM ${km} does not exist`)
|
78
|
+
}
|
79
|
+
projection[km] = project(objects, checks[km])
|
80
|
+
}
|
81
|
+
return projection
|
31
82
|
}
|
32
83
|
|
33
|
-
// move ask to the KM's since verbatim is called
|
34
|
-
const getAsk = (config) => (uuid) =>
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
84
|
+
// move ask to the KM's since verbatim is called probably in dialogues?
|
85
|
+
const getAsk = (config) => (uuid) => {
|
86
|
+
// if (!uuid) {
|
87
|
+
// debugger
|
88
|
+
//}
|
89
|
+
return (asks) => {
|
90
|
+
const ask = (ask) => {
|
91
|
+
let oneShot = true // default
|
92
|
+
if (ask.oneShot === false) {
|
93
|
+
oneShot = false
|
94
|
+
}
|
95
|
+
|
96
|
+
const id_q = stableId('semantic')
|
97
|
+
const id_rs = []
|
98
|
+
let wasAsked = false
|
99
|
+
let wasApplied = false
|
100
|
+
const getWasAsked = () => {
|
101
|
+
return wasAsked
|
102
|
+
}
|
103
|
+
const setWasAsked = (value) => {
|
104
|
+
wasAsked = value
|
105
|
+
}
|
106
|
+
const getWasApplied = () => {
|
107
|
+
return wasApplied
|
108
|
+
}
|
109
|
+
const setWasApplied = (value) => {
|
110
|
+
wasApplied = value
|
111
|
+
}
|
112
|
+
|
113
|
+
const semanticsr = ask.semanticsr || []
|
114
|
+
if (semanticsr.length == 0) {
|
115
|
+
semanticsr.push({ match: ask.matchr, apply: ask.applyr })
|
116
|
+
}
|
117
|
+
for (const semantic of semanticsr) {
|
118
|
+
const id_r = stableId('semantic')
|
119
|
+
id_rs.push(id_r)
|
120
|
+
config.addSemantic({
|
121
|
+
uuid,
|
122
|
+
id: id_r,
|
123
|
+
tied_ids: [id_q],
|
124
|
+
oneShot,
|
125
|
+
where: semantic.where || ask.where || where(2),
|
126
|
+
source: 'response',
|
127
|
+
match: (args) => semantic.match(args),
|
128
|
+
apply: (args) => {
|
129
|
+
setWasApplied(true)
|
130
|
+
semantic.apply(args)
|
131
|
+
},
|
132
|
+
})
|
133
|
+
}
|
134
|
+
|
135
|
+
config.addSemantic({
|
136
|
+
uuid,
|
137
|
+
oneShot,
|
138
|
+
id: id_q,
|
139
|
+
tied_ids: id_rs,
|
140
|
+
where: ask.where,
|
141
|
+
isQuestion: true, // do one question at a time
|
142
|
+
getWasAsked,
|
143
|
+
getWasApplied,
|
144
|
+
onNevermind: ask.onNevermind,
|
145
|
+
source: 'question',
|
146
|
+
match: ({ context }) => context.marker == 'controlEnd' || context.marker == 'controlBetween',
|
147
|
+
apply: (args) => {
|
148
|
+
let matchq = ask.matchq
|
149
|
+
let applyq = ask.applyq
|
150
|
+
if (!matchq) {
|
151
|
+
let wasAsked = false
|
152
|
+
matchq = () => !wasAsked,
|
153
|
+
applyq = (args) => {
|
154
|
+
wasAsked = true
|
155
|
+
return ask.applyq(args)
|
156
|
+
}
|
67
157
|
}
|
158
|
+
if (matchq(args)) {
|
159
|
+
setWasAsked(true)
|
160
|
+
setWasApplied(false)
|
161
|
+
// args.context.motivationKeep = true
|
162
|
+
args.verbatim(applyq(args))
|
163
|
+
/*
|
164
|
+
args.context.verbatim = applyq(args)
|
165
|
+
args.context.isResponse = true;
|
166
|
+
delete args.context.controlRemove;
|
167
|
+
*/
|
168
|
+
args.context.controlKeepMotivation = true
|
169
|
+
}
|
170
|
+
args.context.cascade = true
|
68
171
|
}
|
69
|
-
|
70
|
-
// args.context.motivationKeep = true
|
71
|
-
args.verbatim(applyq(args))
|
72
|
-
/*
|
73
|
-
args.context.verbatim = applyq(args)
|
74
|
-
args.context.isResponse = true;
|
75
|
-
delete args.context.controlRemove;
|
76
|
-
*/
|
77
|
-
args.context.controlKeepMotivation = true
|
78
|
-
break
|
79
|
-
}
|
80
|
-
}
|
81
|
-
args.context.cascade = true
|
172
|
+
})
|
82
173
|
}
|
83
|
-
|
174
|
+
if (!Array.isArray(asks)) {
|
175
|
+
asks = [asks]
|
176
|
+
}
|
177
|
+
|
178
|
+
[...asks].reverse().forEach( (a) => ask(a) )
|
179
|
+
}
|
84
180
|
}
|
85
181
|
|
86
182
|
const sameJSON = (json1, json2) => {
|
@@ -105,6 +201,9 @@ const vimdiff = (actualJSON, expectedJSON, title) => {
|
|
105
201
|
}
|
106
202
|
|
107
203
|
const listable = (hierarchy) => (c, type) => {
|
204
|
+
if (!c) {
|
205
|
+
return false
|
206
|
+
}
|
108
207
|
if (hierarchy.isA(c.marker, type)) {
|
109
208
|
return true
|
110
209
|
}
|
@@ -119,6 +218,9 @@ const listable = (hierarchy) => (c, type) => {
|
|
119
218
|
}
|
120
219
|
|
121
220
|
const isA = (hierarchy) => (child, parent) => {
|
221
|
+
if (!child || !parent) {
|
222
|
+
return false
|
223
|
+
}
|
122
224
|
if (child.marker) {
|
123
225
|
child = child.marker
|
124
226
|
}
|
@@ -147,7 +249,8 @@ class ErrorReason extends Error {
|
|
147
249
|
}
|
148
250
|
|
149
251
|
const setupArgs = (args, config, logs, hierarchy, uuidForScoping) => {
|
150
|
-
|
252
|
+
|
253
|
+
// callId
|
151
254
|
args.calls = new InitCalls(args.isInstance ? `${args.isInstance}#${config.name}` : config.name)
|
152
255
|
if (global.theprogrammablemind && global.theprogrammablemind.loadForTesting) {
|
153
256
|
args.calls = new InitCalls(Object.keys(global.theprogrammablemind.loadForTesting)[0])
|
@@ -165,32 +268,11 @@ const setupArgs = (args, config, logs, hierarchy, uuidForScoping) => {
|
|
165
268
|
args.asList = asList
|
166
269
|
args.retry = () => { throw new RetryError() }
|
167
270
|
args.fragments = (query) => config.fragment(query)
|
168
|
-
const scopedAsk = getAsk(config)
|
169
|
-
|
170
|
-
const getAPI = (uuid) => {
|
171
|
-
if (config && config.getAPI) {
|
172
|
-
return config.getAPI(uuid)
|
173
|
-
}
|
174
|
-
}
|
175
|
-
const getAPIs = (uuid) => {
|
176
|
-
if (config && config.getAPIs) {
|
177
|
-
return config.getAPIs(uuid)
|
178
|
-
}
|
179
|
-
}
|
180
|
-
args.getUUIDScoped = (uuid) => {
|
181
|
-
return {
|
182
|
-
ask: scopedAsk(uuid),
|
183
|
-
api: getAPI(uuid),
|
184
|
-
apis: getAPIs(uuid)
|
185
|
-
}
|
186
|
-
}
|
187
|
-
Object.assign(args, args.getUUIDScoped(uuidForScoping))
|
188
271
|
args.breakOnSemantics = false
|
189
272
|
args.theDebugger = {
|
190
273
|
breakOnSemantics: (value) => args.breakOnSemantics = value
|
191
274
|
}
|
192
275
|
if (!logs) {
|
193
|
-
debugger
|
194
276
|
}
|
195
277
|
args.log = (message) => logs.push(message)
|
196
278
|
|
@@ -219,6 +301,33 @@ const setupArgs = (args, config, logs, hierarchy, uuidForScoping) => {
|
|
219
301
|
// for semantics
|
220
302
|
args.addAssumedScoped(args, {})
|
221
303
|
config.getAddedArgs(args)
|
304
|
+
|
305
|
+
const getAPI = (uuid) => {
|
306
|
+
if (config && config.getAPI) {
|
307
|
+
return config.getAPI(uuid)
|
308
|
+
}
|
309
|
+
}
|
310
|
+
const getAPIs = (uuid) => {
|
311
|
+
if (config && config.getAPIs) {
|
312
|
+
return config.getAPIs(uuid)
|
313
|
+
}
|
314
|
+
}
|
315
|
+
const scopedAsk = getAsk(config)
|
316
|
+
args.getUUIDScoped = (uuid) => {
|
317
|
+
return {
|
318
|
+
ask: scopedAsk(uuid),
|
319
|
+
api: getAPI(uuid),
|
320
|
+
apis: getAPIs(uuid)
|
321
|
+
}
|
322
|
+
}
|
323
|
+
Object.assign(args, args.getUUIDScoped(uuidForScoping || config.uuid))
|
324
|
+
/*
|
325
|
+
if (uuidForScoping) {
|
326
|
+
Object.assign(args, args.getUUIDScoped(uuidForScoping))
|
327
|
+
}
|
328
|
+
*/
|
329
|
+
// sets args for all the API. that make a copy so the args must be fully setup by here except for scoped
|
330
|
+
config.setArgs(args)
|
222
331
|
}
|
223
332
|
|
224
333
|
const gs = (g) => (contexts, separator, lastSeparator) => {
|
@@ -657,10 +766,8 @@ const loadInstance = (config, instance) => {
|
|
657
766
|
config.config.skipSemantics = results.skipSemantics
|
658
767
|
}
|
659
768
|
const args = { config, hierarchy, json: results, commandLineArgs: {} }
|
660
|
-
|
661
|
-
|
662
|
-
args.instance = instance.queries[i]
|
663
|
-
}
|
769
|
+
args.isInstance = `instance${i}`
|
770
|
+
args.instance = ''
|
664
771
|
processContextsB(args)
|
665
772
|
if (results.skipSemantics) {
|
666
773
|
config.config.skipSemantics = null
|
@@ -777,6 +884,7 @@ const _process = async (config, query, { initializer, commandLineArgs, credentia
|
|
777
884
|
response.trace = response.trace.concat(json.trace)
|
778
885
|
response.version = json.version
|
779
886
|
response.explain_priorities = json.explain_priorities
|
887
|
+
response.contextual_priorities_ambiguities = json.contextual_priorities_ambiguities
|
780
888
|
|
781
889
|
response.contexts = response.contexts.concat(contextsPrime)
|
782
890
|
response.generated = response.generated.concat(generatedPrime)
|
@@ -851,11 +959,6 @@ const runTest = async (config, expected, { args, verbose, testConfig, debug }) =
|
|
851
959
|
}
|
852
960
|
|
853
961
|
let objects = getObjects(config.config.objects)(config.uuid)
|
854
|
-
let testConfigName = config.name
|
855
|
-
if (testConfig.testModuleName) {
|
856
|
-
objects = getObjects(config.config.objects)(config.getConfigs()[testConfig.testModuleName].uuid)
|
857
|
-
testConfigName = testConfig.testModuleName
|
858
|
-
}
|
859
962
|
try {
|
860
963
|
const result = await _process(config, test, { errorHandler, isTest: true })
|
861
964
|
result.query = test
|
@@ -895,7 +998,7 @@ const runTest = async (config, expected, { args, verbose, testConfig, debug }) =
|
|
895
998
|
}
|
896
999
|
return expected.objects.namespaced[expected.objects.nameToUUID[name]] || {}
|
897
1000
|
}
|
898
|
-
const expected_checked = sortJson(pickObjects(testConfig, expectedGetObjects
|
1001
|
+
const expected_checked = sortJson(pickObjects(config, testConfig, expectedGetObjects), { depth: 25 })
|
899
1002
|
const actualGetObjects = (name) => {
|
900
1003
|
if (!name) {
|
901
1004
|
name = config.name
|
@@ -903,7 +1006,7 @@ const runTest = async (config, expected, { args, verbose, testConfig, debug }) =
|
|
903
1006
|
const km = config.configs.find((km) => km.name == name)
|
904
1007
|
return config.config.objects.namespaced[km.uuid] || {}
|
905
1008
|
}
|
906
|
-
const actual_checked = sortJson(pickObjects(testConfig, actualGetObjects
|
1009
|
+
const actual_checked = sortJson(pickObjects(config, testConfig, actualGetObjects), { depth: 25 })
|
907
1010
|
const failed_checked = !matching(actual_objects, expected_objects)
|
908
1011
|
|
909
1012
|
const failed_checks = !matching(actual_objects, expected_objects)
|
@@ -1155,6 +1258,24 @@ const defaultErrorHandler = async (error) => {
|
|
1155
1258
|
throw error
|
1156
1259
|
}
|
1157
1260
|
|
1261
|
+
const printContextualPrioritiesAmbiguities = (cpa) => {
|
1262
|
+
console.log('Contextual Priorities Ambiguities')
|
1263
|
+
for (const counter in cpa) {
|
1264
|
+
console.log(` Counter ${counter}`)
|
1265
|
+
for (const choices of cpa[counter]) {
|
1266
|
+
console.log(' [')
|
1267
|
+
for (const choice of choices) {
|
1268
|
+
console.log(' [')
|
1269
|
+
for (const element of choice) {
|
1270
|
+
console.log(` ${JSON.stringify(element)},`)
|
1271
|
+
}
|
1272
|
+
console.log(' ],')
|
1273
|
+
}
|
1274
|
+
console.log(' ],')
|
1275
|
+
}
|
1276
|
+
}
|
1277
|
+
}
|
1278
|
+
|
1158
1279
|
const defaultInnerProcess = (config, errorHandler, responses) => {
|
1159
1280
|
if (responses.errors) {
|
1160
1281
|
console.log('Errors')
|
@@ -1173,6 +1294,9 @@ const defaultInnerProcess = (config, errorHandler, responses) => {
|
|
1173
1294
|
console.log('Logs')
|
1174
1295
|
responses.logs.forEach((log) => console.log(` ${log}`))
|
1175
1296
|
}
|
1297
|
+
if (responses.contextual_priorities_ambiguities) {
|
1298
|
+
printContextualPrioritiesAmbiguities(responses.contextual_priorities_ambiguities)
|
1299
|
+
}
|
1176
1300
|
console.log(responses.trace)
|
1177
1301
|
|
1178
1302
|
if (global.beforeObjects) {
|
@@ -1211,8 +1335,15 @@ const defaultInnerProcess = (config, errorHandler, responses) => {
|
|
1211
1335
|
console.log(` inputs: ${JSON.stringify(inputs)} output: ${JSON.stringify(output)} reason: ${reason}`)
|
1212
1336
|
}
|
1213
1337
|
}
|
1214
|
-
const objects = config.get('objects').namespaced[config.uuid]
|
1215
|
-
const
|
1338
|
+
// const objects = config.get('objects').namespaced[config.uuid]
|
1339
|
+
const actualGetObjects = (name) => {
|
1340
|
+
if (!name) {
|
1341
|
+
name = config.name
|
1342
|
+
}
|
1343
|
+
const km = config.configs.find((km) => km.name == name)
|
1344
|
+
return config.config.objects.namespaced[km.uuid] || {}
|
1345
|
+
}
|
1346
|
+
const picked = sortJson(pickObjects(config, config.testConfig, actualGetObjects), { depth: 25 })
|
1216
1347
|
if (!_.isEmpty(picked)) {
|
1217
1348
|
console.log('--- Object showing only the checked values ---')
|
1218
1349
|
console.log(JSON.stringify(picked, null, 2))
|
@@ -2024,6 +2155,13 @@ const knowledgeModuleImpl = async ({
|
|
2024
2155
|
})
|
2025
2156
|
f()
|
2026
2157
|
} else if (args.query) {
|
2158
|
+
let useTestConfig = testConfig
|
2159
|
+
if (args.testModuleName) {
|
2160
|
+
config.testConfig.testModuleName = args.testModuleName
|
2161
|
+
config.testConfig.checks = config.getConfigs()[args.testModuleName].getTestConfig().checks
|
2162
|
+
// useTestConfig = config.getConfigs()[args.testModuleName].getTestConfig()
|
2163
|
+
// useTestConfig.testModuleName = args.testModuleName
|
2164
|
+
}
|
2027
2165
|
const objects = getObjects(config.config.objects)(config.uuid)
|
2028
2166
|
// for the compare
|
2029
2167
|
if (args.objectDiff) {
|
@@ -2118,26 +2256,6 @@ const ensureTestFile = (module, name, type) => {
|
|
2118
2256
|
}
|
2119
2257
|
}
|
2120
2258
|
|
2121
|
-
function where (goUp = 2) {
|
2122
|
-
const e = new Error()
|
2123
|
-
const regexForm1 = /\((.*):(\d+):(\d+)\)$/
|
2124
|
-
const regexForm2 = /at (.*):(\d+):(\d+)$/
|
2125
|
-
const lines = e.stack.split('\n')
|
2126
|
-
let line
|
2127
|
-
for (line of lines.slice(1)) {
|
2128
|
-
if (!(line.includes('config.js:') || line.includes('client.js:'))) {
|
2129
|
-
break
|
2130
|
-
}
|
2131
|
-
}
|
2132
|
-
// const line = e.stack.split("\n")[goUp];
|
2133
|
-
const match = regexForm1.exec(line) || regexForm2.exec(line)
|
2134
|
-
if (match) {
|
2135
|
-
return `${match[1]}:${match[2]}`
|
2136
|
-
} else {
|
2137
|
-
return 'running in browser'
|
2138
|
-
}
|
2139
|
-
}
|
2140
|
-
|
2141
2259
|
function w (func) {
|
2142
2260
|
func.where = where(3)
|
2143
2261
|
return func
|
package/package.json
CHANGED
package/src/config.js
CHANGED
@@ -199,7 +199,7 @@ const priority_valid = (cp) => {
|
|
199
199
|
)
|
200
200
|
}
|
201
201
|
|
202
|
-
const handleBridgeProps = (config, bridge, addFirst) => {
|
202
|
+
const handleBridgeProps = (config, bridge, { addFirst, uuid } = {}) => {
|
203
203
|
ecatch(`While processing the bridge for ${bridge.id}#${bridge.level}`,
|
204
204
|
() => {
|
205
205
|
if (!bridge.bridge) {
|
@@ -260,7 +260,8 @@ const handleBridgeProps = (config, bridge, addFirst) => {
|
|
260
260
|
}
|
261
261
|
*/
|
262
262
|
|
263
|
-
const addUUID = (obj) => { return { ...obj, uuid: config.uuid } }
|
263
|
+
const addUUID = (obj) => { return { ...obj, uuid: uuid || config.uuid } }
|
264
|
+
|
264
265
|
if (bridge.generators) {
|
265
266
|
const generators = [...bridge.generators]
|
266
267
|
generators.reverse()
|
@@ -343,14 +344,14 @@ const handleBridgeProps = (config, bridge, addFirst) => {
|
|
343
344
|
)
|
344
345
|
}
|
345
346
|
|
346
|
-
const handleCalculatedProps = (baseConfig, moreConfig, addFirst) => {
|
347
|
+
const handleCalculatedProps = (baseConfig, moreConfig, { addFirst, uuid } = {}) => {
|
347
348
|
if (moreConfig.bridges) {
|
348
349
|
moreConfig.bridges = moreConfig.bridges.map((bridge) => {
|
349
350
|
bridge = { ...bridge }
|
350
351
|
const valid = ['after', 'before', 'bridge', 'development', 'evaluator', 'generatorp', 'generatorr', 'generatorpr', 'generators', 'id', 'convolution', 'inverted', 'isA', 'children', 'parents',
|
351
352
|
'level', 'optional', 'selector', 'semantic', 'words', /Bridge$/, 'localHierarchy', 'levelSpecificHierarchy', 'where', 'uuid']
|
352
353
|
helpers.validProps(valid, bridge, 'bridge')
|
353
|
-
handleBridgeProps(baseConfig, bridge, addFirst)
|
354
|
+
handleBridgeProps(baseConfig, bridge, { addFirst, uuid })
|
354
355
|
return bridge
|
355
356
|
})
|
356
357
|
}
|
@@ -466,7 +467,7 @@ const normalizeConfig = (config) => {
|
|
466
467
|
if (config.semantics) {
|
467
468
|
for (const semantic of config.semantics) {
|
468
469
|
if (semantic.oneShot) {
|
469
|
-
semantic.id =
|
470
|
+
semantic.id = semantic.id || helpers.stableId('semantic')
|
470
471
|
}
|
471
472
|
}
|
472
473
|
}
|
@@ -901,6 +902,10 @@ class Config {
|
|
901
902
|
}
|
902
903
|
}
|
903
904
|
|
905
|
+
get semantics() {
|
906
|
+
return [...this.config.semantics]
|
907
|
+
}
|
908
|
+
|
904
909
|
getSemantics (logs = []) {
|
905
910
|
return new Semantics(this.config.semantics, logs, { km: this.name })
|
906
911
|
}
|
@@ -1314,7 +1319,7 @@ class Config {
|
|
1314
1319
|
if (global.transitoryMode) {
|
1315
1320
|
def.transitoryMode = true
|
1316
1321
|
}
|
1317
|
-
handleBridgeProps(this, def)
|
1322
|
+
handleBridgeProps(this, def, { uuid })
|
1318
1323
|
bridges.push(def)
|
1319
1324
|
this.checkBridges()
|
1320
1325
|
this._delta.json.bridges.push({ action: 'add', bridge: def })
|
@@ -1365,9 +1370,28 @@ class Config {
|
|
1365
1370
|
}
|
1366
1371
|
|
1367
1372
|
removeSemantic (deleteSemantic) {
|
1368
|
-
const
|
1369
|
-
|
1370
|
-
|
1373
|
+
const id = deleteSemantic.id || deleteSemantic
|
1374
|
+
const todo = [id]
|
1375
|
+
const seen = new Set()
|
1376
|
+
|
1377
|
+
while (todo.length > 0) {
|
1378
|
+
const id = todo.pop()
|
1379
|
+
if (seen.has(id)) {
|
1380
|
+
continue
|
1381
|
+
}
|
1382
|
+
seen.add(id)
|
1383
|
+
const index = this.config.semantics.findIndex((semantic) => semantic.id === id)
|
1384
|
+
if (index == -1) {
|
1385
|
+
continue
|
1386
|
+
}
|
1387
|
+
for (const tied_id of this.config.semantics[index].tied_ids || []) {
|
1388
|
+
if (!seen.has(tied_id)) {
|
1389
|
+
todo.push(tied_id)
|
1390
|
+
}
|
1391
|
+
}
|
1392
|
+
if (index >= 0) {
|
1393
|
+
this.config.semantics.splice(index, 1)
|
1394
|
+
}
|
1371
1395
|
}
|
1372
1396
|
}
|
1373
1397
|
|
@@ -1555,7 +1579,7 @@ class Config {
|
|
1555
1579
|
config._api.multiApi[api].args = args
|
1556
1580
|
}
|
1557
1581
|
} else {
|
1558
|
-
config._api.args = args
|
1582
|
+
config._api.args = { ...args, ...args.getUUIDScoped(config.uuid) }
|
1559
1583
|
}
|
1560
1584
|
}
|
1561
1585
|
|
@@ -2842,7 +2866,7 @@ class Config {
|
|
2842
2866
|
debugConfigProps(more)
|
2843
2867
|
|
2844
2868
|
if (hcps) {
|
2845
|
-
handleCalculatedProps(this, more, addFirst)
|
2869
|
+
handleCalculatedProps(this, more, { addFirst, uuid })
|
2846
2870
|
applyUUID(more, uuid || this._uuid)
|
2847
2871
|
}
|
2848
2872
|
for (const key of Object.keys(more)) {
|
@@ -3078,5 +3102,5 @@ module.exports = {
|
|
3078
3102
|
Config,
|
3079
3103
|
config_toServer,
|
3080
3104
|
operatorKey_valid,
|
3081
|
-
handleBridgeProps
|
3105
|
+
handleBridgeProps,
|
3082
3106
|
}
|
package/src/helpers.js
CHANGED
@@ -374,7 +374,15 @@ const subPriority = (sub, sup) => {
|
|
374
374
|
return true
|
375
375
|
}
|
376
376
|
|
377
|
+
const stableIds = {}
|
378
|
+
const stableId = (tag) => {
|
379
|
+
const id = stableIds[tag] || 1
|
380
|
+
stableIds[tag] = id + 1
|
381
|
+
return id
|
382
|
+
}
|
383
|
+
|
377
384
|
module.exports = {
|
385
|
+
stableId,
|
378
386
|
ecatch,
|
379
387
|
functionsToStrings,
|
380
388
|
updateQueries,
|
package/src/semantics.js
CHANGED
@@ -6,7 +6,7 @@ class Semantic {
|
|
6
6
|
// constructor ({match, apply, uuid, index, km, notes}) {
|
7
7
|
constructor (semantic) {
|
8
8
|
semantic = normalizeSemantic(semantic)
|
9
|
-
const { match, apply, uuid, index, km, notes, priority, debug, where, applyWrapped, property, oneShot, id } = semantic
|
9
|
+
const { match, apply, uuid, index, km, notes, priority, debug, where, source, applyWrapped, property, oneShot, id, tied_ids, isQuestion } = semantic
|
10
10
|
this.matcher = match
|
11
11
|
this._apply = apply
|
12
12
|
this._applyWrapped = applyWrapped
|
@@ -18,8 +18,11 @@ class Semantic {
|
|
18
18
|
this.notes = notes
|
19
19
|
this.callId = debug
|
20
20
|
this.where = where
|
21
|
+
this.source = source
|
21
22
|
this.oneShot = oneShot
|
23
|
+
this.isQuestion = isQuestion
|
22
24
|
this.id = id
|
25
|
+
this.tied_ids = tied_ids || []
|
23
26
|
}
|
24
27
|
|
25
28
|
toLabel () {
|
@@ -184,11 +187,16 @@ class Semantics {
|
|
184
187
|
let applied = false
|
185
188
|
const stack = args.calls.push()
|
186
189
|
let counter = 0
|
190
|
+
let seenQuestion = false
|
187
191
|
for (const isemantic in this.semantics) {
|
188
192
|
const semantic = this.semantics[isemantic]
|
189
193
|
if (!semantic) {
|
190
194
|
debugger
|
191
195
|
}
|
196
|
+
// only one question at a time
|
197
|
+
if (semantic.isQuestion && seenQuestion) {
|
198
|
+
continue
|
199
|
+
}
|
192
200
|
if (semantic.matches(args, context, options)) {
|
193
201
|
if (!this.calls[counter]) {
|
194
202
|
this.calls[counter] = 0
|
@@ -198,6 +206,7 @@ class Semantics {
|
|
198
206
|
try {
|
199
207
|
contextPrime = semantic.apply(args, context, s, log, options)
|
200
208
|
if (!contextPrime.controlKeepMotivation && semantic.oneShot) {
|
209
|
+
// semantic.tied_ids.forEach((tied_id) => args.config.removeSemantic(tied_id))
|
201
210
|
args.config.removeSemantic(semantic)
|
202
211
|
}
|
203
212
|
} catch (e) {
|
@@ -274,6 +283,7 @@ class Semantics {
|
|
274
283
|
this.logs.push(lines.toString())
|
275
284
|
}
|
276
285
|
applied = true
|
286
|
+
seenQuestion = seenQuestion || semantic.isQuestion
|
277
287
|
if (contextPrime.cascade) {
|
278
288
|
contextPrime.cascade = false
|
279
289
|
} else {
|