theprogrammablemind_4wp 8.0.0-beta.8 → 8.0.0-beta.80

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,455 @@
1
+ const { InitCalls } = require('./helpers')
2
+ const DigraphInternal = require('./digraph_internal')
3
+
4
+ const gs = (g) => async (contexts, separator, lastSeparator) => {
5
+ if (!Array.isArray(contexts)) {
6
+ throw new Error('Expected a list')
7
+ }
8
+
9
+ let s = ''
10
+ if (!separator) {
11
+ separator = ' '
12
+ }
13
+ if (!lastSeparator) {
14
+ lastSeparator = separator
15
+ }
16
+ let nextSeparator = ''
17
+ for (let i = 0; i < contexts.length; ++i) {
18
+ const context = contexts[i]
19
+ const value = await g(context)
20
+ if (i > 0) {
21
+ if (i === contexts.length - 1) {
22
+ nextSeparator = lastSeparator
23
+ } else {
24
+ nextSeparator = separator
25
+ }
26
+ }
27
+ s += nextSeparator + value
28
+ }
29
+ return s
30
+ }
31
+
32
+ const asList = (context) => {
33
+ if (context.marker === 'list') {
34
+ return context
35
+ }
36
+ return {
37
+ marker: 'list',
38
+ types: [context.marker],
39
+ value: [context]
40
+ }
41
+ }
42
+
43
+ const isA = (hierarchy) => (child, parent) => {
44
+ if (!child || !parent) {
45
+ return false
46
+ }
47
+ if (child.marker) {
48
+ child = child.marker
49
+ }
50
+ if (parent.marker) {
51
+ parent = parent.marker
52
+ }
53
+ return hierarchy.isA(child, parent)
54
+ }
55
+
56
+ class ErrorReason extends Error {
57
+ constructor (context) {
58
+ super(JSON.stringify(context))
59
+ this.reason = context
60
+ }
61
+ }
62
+
63
+ const listable = (hierarchy) => (c, type) => {
64
+ if (!c) {
65
+ return false
66
+ }
67
+ if (hierarchy.isA(c.marker, type)) {
68
+ return true
69
+ }
70
+ if (c.marker === 'list') {
71
+ for (const t of c.types) {
72
+ if (hierarchy.isA(t, type)) {
73
+ return true
74
+ }
75
+ }
76
+ }
77
+ return false
78
+ }
79
+
80
+ const cleanAssign = (dest, ...srcs) => {
81
+ for (const key in dest) {
82
+ let found = false
83
+ for (const src of srcs) {
84
+ if (src[key]) {
85
+ found = true
86
+ break
87
+ }
88
+ }
89
+ if (!found) {
90
+ delete dest[key]
91
+ }
92
+ }
93
+ Object.assign(dest, ...srcs)
94
+ }
95
+
96
+ const setupArgs = (args, config, logs, hierarchy, uuidForScoping) => {
97
+
98
+ // callId
99
+ args.calls = new InitCalls(args.isInstance ? `${args.isInstance}#${config.name}` : config.name)
100
+ if (global.theprogrammablemind && global.theprogrammablemind.loadForTesting) {
101
+ args.calls = new InitCalls(Object.keys(global.theprogrammablemind.loadForTesting)[0])
102
+ }
103
+ args.cleanAssign = cleanAssign
104
+ args.km = (name) => config.getConfig(name)
105
+ args.api = (name) => config.getConfig(name).api
106
+ args.error = (context) => {
107
+ throw new ErrorReason(context)
108
+ }
109
+ args.kms = config.getConfigs()
110
+ args.config = config
111
+ args.hierarchy = hierarchy
112
+ args.isA = isA(hierarchy)
113
+ args.listable = listable(hierarchy)
114
+ args.asList = asList
115
+ args.retry = () => { throw new RetryError() }
116
+ args.fragments = (query) => {
117
+ return config.fragment(args, query)
118
+ }
119
+ args.breakOnSemantics = false
120
+ args.theDebugger = {
121
+ breakOnSemantics: (value) => args.breakOnSemantics = value
122
+ }
123
+ if (!logs) {
124
+ }
125
+ args.log = (message) => logs.push(message)
126
+
127
+ args.addAssumedScoped = (args, assumed) => {
128
+ const addAssumed = (args, ...moreAssumed) => {
129
+ return { ...args, assumed: Object.assign({}, assumed, (args.assumed || {}), ...moreAssumed) }
130
+ }
131
+
132
+ args.s = (c) => config.getSemantics(logs).apply(args, c)
133
+ args.g = (c, a = {}) => {
134
+ return config.getGenerators(logs).apply(addAssumed(args, a), c, a)
135
+ }
136
+ args.gp = (c, a = {}) => {
137
+ return config.getGenerators(logs).apply(addAssumed(args, a, { paraphrase: true, isResponse: false, response: false }), c, { paraphrase: true, isResponse: false, response: false })
138
+ }
139
+ args.gr = (c, a = {}) => {
140
+ return config.getGenerators(logs).apply(addAssumed(args, a, { paraphrase: false, isResponse: true }), { ...c, paraphrase: false, isResponse: true })
141
+ }
142
+ args.e = (c) => {
143
+ return config.getEvaluator(args.s, args.calls, logs, c)
144
+ }
145
+ args.gs = gs(args.g)
146
+ args.gsp = gs(args.gp)
147
+ args.gsr = gs(args.gr)
148
+ }
149
+ // for semantics
150
+ args.addAssumedScoped(args, {})
151
+
152
+ const getAPI = (uuid) => {
153
+ if (config && config.getAPI) {
154
+ return config.getAPI(uuid)
155
+ }
156
+ }
157
+ const getAPIs = (uuid) => {
158
+ if (config && config.getAPIs) {
159
+ return config.getAPIs(uuid)
160
+ }
161
+ }
162
+ args.getUUIDScoped = (uuid) => {
163
+ return {
164
+ api: getAPI(uuid),
165
+ apis: getAPIs(uuid)
166
+ }
167
+ }
168
+ config.getAddedArgs(args)
169
+
170
+ Object.assign(args, args.getUUIDScoped(uuidForScoping || config.uuid))
171
+ /*
172
+ if (uuidForScoping) {
173
+ Object.assign(args, args.getUUIDScoped(uuidForScoping))
174
+ }
175
+ */
176
+ // sets args for all the API. that make a copy so the args must be fully setup by here except for scoped
177
+ config.setArgs(args)
178
+ }
179
+
180
+ const getObjects = (objects) => {
181
+ return (uuid) => {
182
+ if (objects && objects.namespaced) {
183
+ return objects.namespaced[uuid]
184
+ }
185
+ return objects
186
+ }
187
+ }
188
+
189
+ const processContext = async (context, { objects = {}, config, logs = [] }) => {
190
+ const generators = config.getGenerators(logs)
191
+ const semantics = config.getSemantics(logs)
192
+
193
+ // map to hash
194
+ config = config || {}
195
+ if (config.config) {
196
+ config = config
197
+ }
198
+
199
+ const response = {} // NA but passed in
200
+ // generators = new Generators(generators.map((g) => new Generator(normalizeGenerator(g))))
201
+ // semantics = new Semantics(semantics.map((g) => new Semantic(normalizeSemantic(g))))
202
+ const hierarchy = new DigraphInternal((config.config || {}).hierarchy || [])
203
+
204
+ const args = { objects, response, getObjects: getObjects(objects) }
205
+ setupArgs(args, config, logs, hierarchy)
206
+
207
+ context = await semantics.apply(args, context)
208
+ const generated = await generators.apply(args, context)
209
+ const assumed = { paraphrase: true, response: false, isResponse: false }
210
+ const paraphrases = await generators.apply({ ...args, assumed }, context, { paraphrase: true, response: false, isResponse: false })
211
+ let responses = []
212
+ if (context.isResponse) {
213
+ responses = generated
214
+ }
215
+ return { context, generated, paraphrases, responses }
216
+ }
217
+
218
+ const setupProcessB = ({ config, initializer, allowDelta = false } = {}) => {
219
+ const key = config._key
220
+
221
+ const data = Object.assign({ key, version: '3' }, { uuid: config._uuid })
222
+ if (allowDelta && config.allowDelta && config.hasDelta()) {
223
+ // console.log('config', config)
224
+ data.delta = config.delta()
225
+ } else {
226
+ config.toData(data)
227
+ // Object.assign(data, config.config)
228
+ }
229
+
230
+ // config.toServer(data)
231
+
232
+ if (data.namespaces) {
233
+ for (const uuid of Object.keys(data.namespaces)) {
234
+ const km = config.configs.find((km) => km.uuid === uuid)
235
+ data.namespaces[uuid].name = km.name
236
+ }
237
+ }
238
+
239
+ // const generators = new Generators((data.generators || []).map((g) => new Generator(normalizeGenerator(g))))
240
+ delete data.generators
241
+ // const semantics = new Semantics((data.semantics || []).map((g) => new Semantic(normalizeSemantic(g))))
242
+ delete data.semantics
243
+ const hierarchy = new DigraphInternal((config.config || {}).hierarchy || [])
244
+
245
+ return {
246
+ data,
247
+ // generators,
248
+ // semantics,
249
+ hierarchy
250
+ }
251
+ }
252
+
253
+ const setupContexts = (rawContexts) => {
254
+ let first = true
255
+ const contexts = []
256
+ contexts.push({ marker: 'controlStart', controlRemove: true })
257
+ for (const context of rawContexts) {
258
+ if (first) {
259
+ first = false
260
+ } else {
261
+ contexts.push({ marker: 'controlBetween', controlRemove: true })
262
+ }
263
+ contexts.push(context)
264
+ }
265
+ contexts.push({ marker: 'controlEnd', controlRemove: true })
266
+ return contexts
267
+ }
268
+
269
+ const processContextsB = async ({ config, hierarchy, semantics, generators, json, isTest, rebuildingTemplate, isInstance, instance, query, data, retries, url, commandLineArgs }) => {
270
+ // TODO fix this name to contextsPrime
271
+ const contextsPrime = []
272
+ const generatedPrime = []
273
+ const paraphrasesPrime = []
274
+ const paraphrasesParenthesizedPrime = []
275
+ const generatedParenthesizedPrime = []
276
+ const responsesPrime = []
277
+ const contexts = setupContexts(json.contexts)
278
+
279
+ const objects = config.get('objects')
280
+ const args = { objects, isResponse: true, response: json, isTest, isInstance, getObjects: getObjects(objects), instance }
281
+ if (!json.logs) {
282
+ json.logs = []
283
+ }
284
+ setupArgs(args, config, json.logs, hierarchy)
285
+ const toDo = [...contexts]
286
+ args.insert = (context) => toDo.unshift(context)
287
+ let overlap, lastRange
288
+ config.debugLoops = commandLineArgs && commandLineArgs.debugLoops
289
+ while (toDo.length > 0) {
290
+ const context = toDo.shift()
291
+ args.calls.next()
292
+ let contextPrime = context
293
+ context.topLevel = true
294
+ try {
295
+ if (json.has_errors) {
296
+ throw new Error('There are errors in the logs. Run with the -d flag and grep for Error')
297
+ }
298
+ const generateParenthesized = isTest || (commandLineArgs && commandLineArgs.save)
299
+ if (!config.get('skipSemantics')) {
300
+ const semantics = config.getSemantics(json.logs)
301
+ try {
302
+ contextPrime = await semantics.apply(args, context)
303
+ } catch (e) {
304
+ if (e.message == 'Maximum call stack size exceeded') {
305
+ const mostCalled = semantics.getMostCalled()
306
+ e.message += `\nThe most called semantic was:\nnotes: ${mostCalled.notes}\nmatch: ${mostCalled.matcher.toString()}\napply: ${mostCalled._apply.toString()}\n`
307
+ }
308
+ // contextPrime = semantics.apply(args, { marker: 'error', context, error: e })
309
+ if (isInstance) {
310
+ console.log('error', e.error)
311
+ }
312
+ let reason = e.reason
313
+ if (!reason) {
314
+ if (e.error) {
315
+ reason = e.error[0]
316
+ }
317
+ }
318
+ contextPrime = await semantics.apply(args, {
319
+ marker: 'error',
320
+ context,
321
+ text: e ? e.toString() : 'not available',
322
+ // reason: e.reason,
323
+ reason,
324
+ error: e.stack || e.error
325
+ })
326
+ if (rebuildingTemplate) {
327
+ throw e
328
+ }
329
+ }
330
+ }
331
+ if (contextPrime.controlRemove) {
332
+ continue
333
+ }
334
+ let assumed = { isResponse: true }
335
+ const generated = contextPrime.isResponse ? await config.getGenerators(json.logs).apply({ ...args, assumed }, contextPrime, assumed) : ''
336
+ let generatedParenthesized = []
337
+ if (generateParenthesized) {
338
+ config.parenthesized = true
339
+ generatedParenthesized = contextPrime.isResponse ? await config.getGenerators(json.logs).apply({ ...args, assumed }, contextPrime, assumed) : ''
340
+ config.parenthesized = false
341
+ }
342
+ // assumed = { paraphrase: true, response: false };
343
+ assumed = { paraphrase: true, isResponse: false, response: false }
344
+ if (generateParenthesized) {
345
+ config.parenthesized = false
346
+ }
347
+ const paraphrases = await config.getGenerators(json.logs).apply({ ...args, assumed }, contextPrime, assumed)
348
+ let paraphrasesParenthesized = []
349
+ if (generateParenthesized) {
350
+ config.parenthesized = true
351
+ paraphrasesParenthesized = await config.getGenerators(json.logs).apply({ ...args, assumed }, contextPrime, assumed)
352
+ config.parenthesized = false
353
+ }
354
+ contextsPrime.push(contextPrime)
355
+ generatedPrime.push(generated)
356
+ paraphrasesPrime.push(paraphrases)
357
+ if (generateParenthesized) {
358
+ paraphrasesParenthesizedPrime.push(paraphrasesParenthesized)
359
+ generatedParenthesizedPrime.push(generatedParenthesized)
360
+ }
361
+ if (contextPrime.isResponse) {
362
+ responsesPrime.push(generated)
363
+ } else {
364
+ responsesPrime.push('')
365
+ }
366
+
367
+ // add results to processed list
368
+ config.config.objects.processed = config.config.objects.processed || []
369
+ config.config.objects.processed = config.config.objects.processed.slice(0, 5)
370
+ config.config.objects.processed.unshift({ context: contextPrime, paraphrases: paraphrases, paraphrasesParenthesized, generatedParenthesized, responses: responsesPrime })
371
+ } catch (e) {
372
+ if (Array.isArray(e)) {
373
+ e = {
374
+ errors: e
375
+ }
376
+ }
377
+ e.context = contextPrime
378
+ if (e.logs) {
379
+ e.logs = e.logs.concat(json.logs)
380
+ } else {
381
+ e.logs = json.logs
382
+ }
383
+ e.metadata = json.metadata
384
+ if (json.trace) {
385
+ e.trace = json.trace
386
+ }
387
+ throw e
388
+ }
389
+ }
390
+ return { contextsPrime, generatedPrime, paraphrasesPrime, paraphrasesParenthesizedPrime, generatedParenthesizedPrime, responsesPrime }
391
+ }
392
+
393
+ // instance template loadTemplate
394
+ const loadInstance = async (config, instance) => {
395
+ const transitoryMode = global.transitoryMode
396
+ global.transitoryMode = false
397
+
398
+ if (instance && (instance.associations || instance.learned_contextual_priorities)) {
399
+ if (!config.config.retrain) {
400
+ if (instance.associations) {
401
+ config.addAssociations(instance.associations)
402
+ }
403
+ if (instance.learned_contextual_priorities && instance.learned_contextual_priorities.length > 0) {
404
+ config.addPriorities(instance.learned_contextual_priorities)
405
+ }
406
+ }
407
+ }
408
+
409
+ const { /* data, generators, semantics, */ hierarchy } = setupProcessB({ config })
410
+ for (const i in (instance.resultss || [])) {
411
+ const results = instance.resultss[i]
412
+ if (results.extraConfig) {
413
+ // config.addInternal(results, useOldVersion = true, skipObjects = false, includeNamespaces = true, allowNameToBeNull = false)
414
+ const uuid = config.nameToUUID(instance.name)
415
+ // used to do a CLONE
416
+ config.addInternal(instance.template.configs[i], { uuid, addFirst: true, handleCalculatedProps: true })
417
+ } else if (results.apply) {
418
+ const objects = getObjects(config.get('objects'))(config.uuid)
419
+ const args = { objects, getObjects: getObjects(objects) }
420
+ if (instance.configs) {
421
+ args.isInstance = `instance${i}`
422
+ args.instance = instance.configs[i]
423
+ }
424
+
425
+ const uuid = config.nameToUUID(instance.name)
426
+ setupArgs(args, config, config.logs, hierarchy, uuid)
427
+ await results.apply(args)
428
+ } else if (results.isFragment) {
429
+ } else {
430
+ if (results.skipSemantics) {
431
+ config.config.skipSemantics = results.skipSemantics
432
+ }
433
+ const args = { config, hierarchy, json: results, commandLineArgs: {} }
434
+ args.isInstance = `instance${i}`
435
+ args.instance = ''
436
+ await processContextsB(args)
437
+ if (results.skipSemantics) {
438
+ config.config.skipSemantics = null
439
+ }
440
+ }
441
+ }
442
+ global.transitoryMode = transitoryMode
443
+ }
444
+
445
+ module.exports = {
446
+ setupProcessB,
447
+ ErrorReason,
448
+ listable,
449
+ setupArgs,
450
+ processContext,
451
+ getObjects,
452
+ gs,
453
+ processContextsB,
454
+ loadInstance,
455
+ }
package/src/generators.js CHANGED
@@ -44,7 +44,7 @@ class Generator {
44
44
  return `Generator(${this.match}, ${this._applyWrapped || this._apply})${this.property ? `\nsee the ${this.property} property` : ''}`
45
45
  }
46
46
 
47
- matches (baseArgs, objects, context, hierarchy, config, options = {}) {
47
+ async matches (baseArgs, objects, context, hierarchy, config, options = {}) {
48
48
  if (objects && objects.namespaced) {
49
49
  objects = objects.namespaced[this.uuid]
50
50
  }
@@ -63,17 +63,17 @@ class Generator {
63
63
  }
64
64
  const args = Object.assign({}, baseArgs, moreArgs, (baseArgs.getUUIDScoped || (() => { return {} }))(this.uuid))
65
65
  // return this.match(args)
66
- const matches = this.match(args)
66
+ const matches = await this.match(args)
67
67
  if ((matches && (options.debug || {}).match) ||
68
68
  callId == this.callId) {
69
69
  debugger // next line is the matcher
70
- this.match(args)
70
+ await this.match(args)
71
71
  }
72
72
  return matches
73
73
  }
74
74
 
75
75
  // apply (baseArgs, objects, g, gs, context, hierarchy, config, response, log, options = {}) {
76
- apply (baseArgs, objects, context, hierarchy, config, response, log, options = {}) {
76
+ async apply (baseArgs, objects, context, hierarchy, config, response, log, options = {}) {
77
77
  if (!log) {
78
78
  throw new Error('generators.apply argument log is required')
79
79
  }
@@ -129,7 +129,7 @@ class Generator {
129
129
  callId == this.callId) {
130
130
  debugger
131
131
  }
132
- return this._apply(args)
132
+ return await this._apply(args)
133
133
  }
134
134
  }
135
135
 
@@ -165,7 +165,7 @@ class Generators {
165
165
  };
166
166
 
167
167
  // assumed - properties added to context before the generators are called. For setting paraphrase property
168
- apply (args, context, assumed = {}, options = {}) {
168
+ async apply (args, context, assumed = {}, options = {}) {
169
169
  if (Array.isArray(context)) {
170
170
  throw new Error('Expected a context not an array')
171
171
  }
@@ -186,12 +186,12 @@ class Generators {
186
186
  const stack = args.calls.push()
187
187
  for (let igenerator = 0; igenerator < this.generators.length; ++igenerator) {
188
188
  const generator = this.generators[igenerator]
189
- if (generator.matches(args, objects, context, hierarchy, config, options)) {
189
+ if (await generator.matches(args, objects, context, hierarchy, config, options)) {
190
190
  const log = (message) => { this.logs.push(message) }
191
191
  // this.logs.push(`Generators: applied ${generator.toString()}\n to\n ${JSON.stringify(context)}`)
192
192
  let errorMessage = 'The apply function did not return a value'
193
193
  try {
194
- generated = generator.apply(args, objects, context, hierarchy, config, response, log)
194
+ generated = await generator.apply(args, objects, context, hierarchy, config, response, log)
195
195
  } catch (e) {
196
196
  // the next if handle this
197
197
  generated = null
package/src/helpers.js CHANGED
@@ -1,6 +1,37 @@
1
1
  const deepEqual = require('deep-equal')
2
2
  const stringify = require('json-stable-stringify')
3
3
 
4
+ function where (goUp = 2) {
5
+ const e = new Error()
6
+ const regexForm1 = /\((.*):(\d+):(\d+)\)$/
7
+ const regexForm2 = /at (.*):(\d+):(\d+)$/
8
+ const lines = e.stack.split('\n')
9
+ let line
10
+ let match
11
+ for (line of lines.slice(1)) {
12
+ // if (!(line.includes('config.js:') || line.includes('client.js:') || line.includes('<anonymous>'))) {
13
+ if (!(line.includes('config.js:') || line.includes('client.js:') || line.includes('helpers.js:'))) {
14
+ match = regexForm1.exec(line) || regexForm2.exec(line)
15
+ if (!match) {
16
+ continue
17
+ }
18
+ break
19
+ }
20
+ }
21
+ // const line = e.stack.split("\n")[goUp];
22
+ // const match = regexForm1.exec(line) || regexForm2.exec(line)
23
+ if (match) {
24
+ return `${match[1]}:${match[2]}`
25
+ } else {
26
+ return 'running in browser'
27
+ }
28
+ }
29
+
30
+ function w (func) {
31
+ func.where = where(3)
32
+ return func
33
+ }
34
+
4
35
  // properties - the properties that correspond to types
5
36
  // types - the expected types of the properties
6
37
  // returns list of properties found matching order of types
@@ -403,5 +434,7 @@ module.exports = {
403
434
  InitCalls,
404
435
  hashCode,
405
436
  sortJson,
406
- subPriority
437
+ subPriority,
438
+ where,
439
+ w,
407
440
  }
package/src/project.js CHANGED
@@ -49,7 +49,7 @@ const project = (object, filter) => {
49
49
  const property = properties.property
50
50
  if (properties.isPropertyList) {
51
51
  if (!Array.isArray(object[property])) {
52
- return projection
52
+ continue
53
53
  }
54
54
  for (const propertyRef of object[property]) {
55
55
  const old = object[propertyRef]