theprogrammablemind_4wp 8.0.0-beta.43 → 8.0.0-beta.45

Sign up to get free protection for your applications and to get access to all the features.
package/client.js CHANGED
@@ -1107,7 +1107,7 @@ const knowledgeModuleImpl = async ({
1107
1107
  config.stop_auto_rebuild()
1108
1108
  await config.add(...(includes || []))
1109
1109
  if (api) {
1110
- config.setApi(api())
1110
+ config.setApi(api)
1111
1111
  }
1112
1112
  if (multiApiInitializer) {
1113
1113
  await config.setMultiApi(multiApiInitializer)
package/package.json CHANGED
@@ -43,6 +43,7 @@
43
43
  "src/flatten.js",
44
44
  "src/unflatten.js",
45
45
  "src/config.js",
46
+ "src/configHelpers.js",
46
47
  "src/copy.js",
47
48
  "src/digraph.js",
48
49
  "src/digraph_internal.js",
@@ -64,6 +65,6 @@
64
65
  "sort-json": "^2.0.0",
65
66
  "uuid": "^8.3.2"
66
67
  },
67
- "version": "8.0.0-beta.43",
68
+ "version": "8.0.0-beta.45",
68
69
  "license": "UNLICENSED"
69
70
  }
package/src/config.js CHANGED
@@ -774,12 +774,11 @@ const multiApiImpl = (initializer) => {
774
774
  multiApi: true,
775
775
 
776
776
  // multi functions
777
- add: async (config, multiApi, api) => {
777
+ add: async (config, multiApi, api, apiConstructor) => {
778
778
  initializer(config, api)
779
779
  const name = api.getName()
780
780
  multiApi.apis[name] = api
781
- // api.objects = config.get('objects')
782
- // api.config = () => config
781
+ multiApi.apiConstructors[name] = apiConstructor
783
782
  multiApi.current = name
784
783
  },
785
784
 
@@ -802,6 +801,9 @@ const multiApiImpl = (initializer) => {
802
801
  apis: {
803
802
  },
804
803
 
804
+ apiConstructors: {
805
+ },
806
+
805
807
  // api functions
806
808
  api: (multiApi) => multiApi.apis[multiApi.current]
807
809
  })
@@ -1895,7 +1897,7 @@ class Config {
1895
1897
  }
1896
1898
 
1897
1899
  async setMultiApi (initializer) {
1898
- await this.setApi(multiApiImpl(initializer))
1900
+ await this.setApi(() => multiApiImpl(initializer))
1899
1901
  }
1900
1902
 
1901
1903
  get multiApi () {
@@ -1953,15 +1955,27 @@ class Config {
1953
1955
  }
1954
1956
  }
1955
1957
 
1956
- async setApi (value) {
1958
+ async setApi (constructor) {
1959
+ if (typeof constructor !== 'function') {
1960
+ throw new Error(`Expected the argument to be an API constructor for ${this.name}.`)
1961
+ }
1962
+ const value = constructor()
1957
1963
  if (!value.initialize) {
1958
1964
  throw new Error(`Expected the API to have an initialize function for ${this.name}.`)
1959
1965
  }
1960
1966
 
1961
1967
  if (this._api && this._api.multiApi) {
1962
- await this._api.add(this, this._api, value)
1968
+ await this._api.add(this, this._api, value, constructor)
1969
+ const previousApiConstructor = this._apiConstructor
1970
+ this._apiConstructor = (config) => {
1971
+ const api = previousApiConstructor(config)
1972
+ // does this need await?
1973
+ api.add(config, api, constructor(config), constructor)
1974
+ return api
1975
+ }
1963
1976
  } else {
1964
- this._api = _.cloneDeep(value)
1977
+ this._api = value
1978
+ this._apiConstructor = constructor
1965
1979
  await this.rebuild()
1966
1980
  }
1967
1981
  }
@@ -2029,7 +2043,11 @@ class Config {
2029
2043
  cp._uuid = cp.configs[0]._uuid
2030
2044
  // update uuid here set the uuid in the objects and add error checking
2031
2045
  cp.initializerFn = this.initializerFn
2032
- cp._api = _.cloneDeep(this._api)
2046
+ // cp._api = _.cloneDeep(this._api)
2047
+ if (this._apiConstructor) {
2048
+ cp._api = this._apiConstructor(cp)
2049
+ cp._apiConstructor = this._apiConstructor
2050
+ }
2033
2051
  cp._namespace = this._namespace
2034
2052
  cp._eqClasses = this._eqClasses
2035
2053
  cp.name = this.name
@@ -0,0 +1,429 @@
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 setupArgs = (args, config, logs, hierarchy, uuidForScoping) => {
81
+
82
+ // callId
83
+ args.calls = new InitCalls(args.isInstance ? `${args.isInstance}#${config.name}` : config.name)
84
+ if (global.theprogrammablemind && global.theprogrammablemind.loadForTesting) {
85
+ args.calls = new InitCalls(Object.keys(global.theprogrammablemind.loadForTesting)[0])
86
+ }
87
+ args.km = (name) => config.getConfig(name)
88
+ args.api = (name) => config.getConfig(name).api
89
+ args.error = (context) => {
90
+ throw new ErrorReason(context)
91
+ }
92
+ args.kms = config.getConfigs()
93
+ args.config = config
94
+ args.hierarchy = hierarchy
95
+ args.isA = isA(hierarchy)
96
+ args.listable = listable(hierarchy)
97
+ args.asList = asList
98
+ args.retry = () => { throw new RetryError() }
99
+ args.fragments = (query) => config.fragment(query)
100
+ args.breakOnSemantics = false
101
+ args.theDebugger = {
102
+ breakOnSemantics: (value) => args.breakOnSemantics = value
103
+ }
104
+ if (!logs) {
105
+ }
106
+ args.log = (message) => logs.push(message)
107
+
108
+ args.addAssumedScoped = (args, assumed) => {
109
+ const addAssumed = (args, ...moreAssumed) => {
110
+ return { ...args, assumed: Object.assign({}, assumed, (args.assumed || {}), ...moreAssumed) }
111
+ }
112
+
113
+ args.s = (c) => config.getSemantics(logs).apply(args, c)
114
+ args.g = (c, a = {}) => {
115
+ return config.getGenerators(logs).apply(addAssumed(args, a), c, a)
116
+ }
117
+ args.gp = (c, a = {}) => {
118
+ return config.getGenerators(logs).apply(addAssumed(args, a, { paraphrase: true, isResponse: false, response: false }), c, { paraphrase: true, isResponse: false, response: false })
119
+ }
120
+ args.gr = (c, a = {}) => {
121
+ return config.getGenerators(logs).apply(addAssumed(args, a, { paraphrase: false, isResponse: true }), { ...c, paraphrase: false, isResponse: true })
122
+ }
123
+ args.e = (c) => {
124
+ return config.getEvaluator(args.s, args.calls, logs, c)
125
+ }
126
+ args.gs = gs(args.g)
127
+ args.gsp = gs(args.gp)
128
+ args.gsr = gs(args.gr)
129
+ }
130
+ // for semantics
131
+ args.addAssumedScoped(args, {})
132
+
133
+ const getAPI = (uuid) => {
134
+ if (config && config.getAPI) {
135
+ return config.getAPI(uuid)
136
+ }
137
+ }
138
+ const getAPIs = (uuid) => {
139
+ if (config && config.getAPIs) {
140
+ return config.getAPIs(uuid)
141
+ }
142
+ }
143
+ args.getUUIDScoped = (uuid) => {
144
+ return {
145
+ api: getAPI(uuid),
146
+ apis: getAPIs(uuid)
147
+ }
148
+ }
149
+ config.getAddedArgs(args)
150
+
151
+ Object.assign(args, args.getUUIDScoped(uuidForScoping || config.uuid))
152
+ /*
153
+ if (uuidForScoping) {
154
+ Object.assign(args, args.getUUIDScoped(uuidForScoping))
155
+ }
156
+ */
157
+ // sets args for all the API. that make a copy so the args must be fully setup by here except for scoped
158
+ config.setArgs(args)
159
+ }
160
+
161
+ const getObjects = (objects) => {
162
+ return (uuid) => {
163
+ if (objects && objects.namespaced) {
164
+ return objects.namespaced[uuid]
165
+ }
166
+ return objects
167
+ }
168
+ }
169
+
170
+ const processContext = async (context, { objects = {}, config, logs = [] }) => {
171
+ const generators = config.getGenerators(logs)
172
+ const semantics = config.getSemantics(logs)
173
+
174
+ // map to hash
175
+ config = config || {}
176
+ if (config.config) {
177
+ config = config
178
+ }
179
+
180
+ const response = {} // NA but passed in
181
+ // generators = new Generators(generators.map((g) => new Generator(normalizeGenerator(g))))
182
+ // semantics = new Semantics(semantics.map((g) => new Semantic(normalizeSemantic(g))))
183
+ const hierarchy = new DigraphInternal((config.config || {}).hierarchy || [])
184
+
185
+ const args = { objects, response, getObjects: getObjects(objects) }
186
+ setupArgs(args, config, logs, hierarchy)
187
+
188
+ context = await semantics.apply(args, context)
189
+ const generated = await generators.apply(args, context)
190
+ const assumed = { paraphrase: true, response: false, isResponse: false }
191
+ const paraphrases = await generators.apply({ ...args, assumed }, context, { paraphrase: true, response: false, isResponse: false })
192
+ let responses = []
193
+ if (context.isResponse) {
194
+ responses = generated
195
+ }
196
+ return { context, generated, paraphrases, responses }
197
+ }
198
+
199
+ const setupProcessB = ({ config, initializer, allowDelta = false } = {}) => {
200
+ const key = config._key
201
+
202
+ const data = Object.assign({ key, version: '3' }, { uuid: config._uuid })
203
+ if (allowDelta && config.allowDelta && config.hasDelta()) {
204
+ // console.log('config', config)
205
+ data.delta = config.delta()
206
+ } else {
207
+ config.toData(data)
208
+ // Object.assign(data, config.config)
209
+ }
210
+
211
+ // config.toServer(data)
212
+
213
+ if (data.namespaces) {
214
+ for (const uuid of Object.keys(data.namespaces)) {
215
+ const km = config.configs.find((km) => km.uuid === uuid)
216
+ data.namespaces[uuid].name = km.name
217
+ }
218
+ }
219
+
220
+ // const generators = new Generators((data.generators || []).map((g) => new Generator(normalizeGenerator(g))))
221
+ delete data.generators
222
+ // const semantics = new Semantics((data.semantics || []).map((g) => new Semantic(normalizeSemantic(g))))
223
+ delete data.semantics
224
+ const hierarchy = new DigraphInternal((config.config || {}).hierarchy || [])
225
+
226
+ return {
227
+ data,
228
+ // generators,
229
+ // semantics,
230
+ hierarchy
231
+ }
232
+ }
233
+
234
+ const setupContexts = (rawContexts) => {
235
+ let first = true
236
+ const contexts = []
237
+ contexts.push({ marker: 'controlStart', controlRemove: true })
238
+ for (const context of rawContexts) {
239
+ if (first) {
240
+ first = false
241
+ } else {
242
+ contexts.push({ marker: 'controlBetween', controlRemove: true })
243
+ }
244
+ contexts.push(context)
245
+ }
246
+ contexts.push({ marker: 'controlEnd', controlRemove: true })
247
+ return contexts
248
+ }
249
+
250
+ const processContextsB = async ({ config, hierarchy, semantics, generators, json, isTest, rebuildingTemplate, isInstance, instance, query, data, retries, url, commandLineArgs }) => {
251
+ // TODO fix this name to contextsPrime
252
+ const contextsPrime = []
253
+ const generatedPrime = []
254
+ const paraphrasesPrime = []
255
+ const paraphrasesParenthesizedPrime = []
256
+ const generatedParenthesizedPrime = []
257
+ const responsesPrime = []
258
+ const contexts = setupContexts(json.contexts)
259
+
260
+ const objects = config.get('objects')
261
+ const args = { objects, isResponse: true, response: json, isTest, isInstance, getObjects: getObjects(objects), instance }
262
+ if (!json.logs) {
263
+ json.logs = []
264
+ }
265
+ setupArgs(args, config, json.logs, hierarchy)
266
+ const toDo = [...contexts]
267
+ args.insert = (context) => toDo.unshift(context)
268
+ let overlap, lastRange
269
+ config.debugLoops = commandLineArgs && commandLineArgs.debugLoops
270
+ while (toDo.length > 0) {
271
+ const context = toDo.shift()
272
+ args.calls.next()
273
+ let contextPrime = context
274
+ context.topLevel = true
275
+ try {
276
+ if (json.has_errors) {
277
+ throw new Error('There are errors in the logs. Run with the -d flag and grep for Error')
278
+ }
279
+ const generateParenthesized = isTest || (commandLineArgs && commandLineArgs.save)
280
+ if (!config.get('skipSemantics')) {
281
+ const semantics = config.getSemantics(json.logs)
282
+ try {
283
+ contextPrime = await semantics.apply(args, context)
284
+ } catch (e) {
285
+ if (e.message == 'Maximum call stack size exceeded') {
286
+ const mostCalled = semantics.getMostCalled()
287
+ e.message += `\nThe most called semantic was:\nnotes: ${mostCalled.notes}\nmatch: ${mostCalled.matcher.toString()}\napply: ${mostCalled._apply.toString()}\n`
288
+ }
289
+ // contextPrime = semantics.apply(args, { marker: 'error', context, error: e })
290
+ if (isInstance) {
291
+ console.log('error', e.error)
292
+ }
293
+ contextPrime = await semantics.apply(args, {
294
+ marker: 'error',
295
+ context,
296
+ text: e ? e.toString() : 'not available',
297
+ reason: e.reason,
298
+ error: e.stack || e.error
299
+ })
300
+ if (rebuildingTemplate) {
301
+ throw e
302
+ }
303
+ }
304
+ }
305
+ if (contextPrime.controlRemove) {
306
+ continue
307
+ }
308
+ let assumed = { isResponse: true }
309
+ const generated = contextPrime.isResponse ? await config.getGenerators(json.logs).apply({ ...args, assumed }, contextPrime, assumed) : ''
310
+ let generatedParenthesized = []
311
+ if (generateParenthesized) {
312
+ config.parenthesized = true
313
+ generatedParenthesized = contextPrime.isResponse ? await config.getGenerators(json.logs).apply({ ...args, assumed }, contextPrime, assumed) : ''
314
+ config.parenthesized = false
315
+ }
316
+ // assumed = { paraphrase: true, response: false };
317
+ assumed = { paraphrase: true, isResponse: false, response: false }
318
+ if (generateParenthesized) {
319
+ config.parenthesized = false
320
+ }
321
+ const paraphrases = await config.getGenerators(json.logs).apply({ ...args, assumed }, contextPrime, assumed)
322
+ let paraphrasesParenthesized = []
323
+ if (generateParenthesized) {
324
+ config.parenthesized = true
325
+ paraphrasesParenthesized = await config.getGenerators(json.logs).apply({ ...args, assumed }, contextPrime, assumed)
326
+ config.parenthesized = false
327
+ }
328
+ contextsPrime.push(contextPrime)
329
+ generatedPrime.push(generated)
330
+ paraphrasesPrime.push(paraphrases)
331
+ if (generateParenthesized) {
332
+ paraphrasesParenthesizedPrime.push(paraphrasesParenthesized)
333
+ generatedParenthesizedPrime.push(generatedParenthesized)
334
+ }
335
+ if (contextPrime.isResponse) {
336
+ responsesPrime.push(generated)
337
+ } else {
338
+ responsesPrime.push('')
339
+ }
340
+
341
+ // add results to processed list
342
+ config.config.objects.processed = config.config.objects.processed || []
343
+ config.config.objects.processed = config.config.objects.processed.slice(0, 5)
344
+ config.config.objects.processed.unshift({ context: contextPrime, paraphrases: paraphrases, paraphrasesParenthesized, generatedParenthesized, responses: responsesPrime })
345
+ } catch (e) {
346
+ if (Array.isArray(e)) {
347
+ e = {
348
+ errors: e
349
+ }
350
+ }
351
+ e.context = contextPrime
352
+ if (e.logs) {
353
+ e.logs = e.logs.concat(json.logs)
354
+ } else {
355
+ e.logs = json.logs
356
+ }
357
+ e.metadata = json.metadata
358
+ if (json.trace) {
359
+ e.trace = json.trace
360
+ }
361
+ throw e
362
+ }
363
+ }
364
+ return { contextsPrime, generatedPrime, paraphrasesPrime, paraphrasesParenthesizedPrime, generatedParenthesizedPrime, responsesPrime }
365
+ }
366
+
367
+ // instance template loadTemplate
368
+ const loadInstance = async (config, instance) => {
369
+ const transitoryMode = global.transitoryMode
370
+ global.transitoryMode = false
371
+
372
+ if (instance && (instance.associations || instance.learned_contextual_priorities)) {
373
+ if (!config.config.retrain) {
374
+ if (instance.associations) {
375
+ config.addAssociations(instance.associations)
376
+ }
377
+ if (instance.learned_contextual_priorities && instance.learned_contextual_priorities.length > 0) {
378
+ config.addPriorities(instance.learned_contextual_priorities)
379
+ }
380
+ }
381
+ }
382
+
383
+ const { /* data, generators, semantics, */ hierarchy } = setupProcessB({ config })
384
+ // for (const results of (instance.resultss || [])) {
385
+ for (const i in (instance.resultss || [])) {
386
+ const results = instance.resultss[i]
387
+ if (results.extraConfig) {
388
+ // config.addInternal(results, useOldVersion = true, skipObjects = false, includeNamespaces = true, allowNameToBeNull = false)
389
+ const uuid = config.nameToUUID(instance.name)
390
+ // used to do a CLONE
391
+ config.addInternal(instance.template.configs[i], { uuid, addFirst: true, handleCalculatedProps: true })
392
+ } else if (results.apply) {
393
+ const objects = config.get('objects')
394
+ const args = { objects, getObjects: getObjects(objects) }
395
+ if (instance.configs) {
396
+ args.isInstance = `instance${i}`
397
+ args.instance = instance.configs[i]
398
+ }
399
+
400
+ const uuid = config.nameToUUID(instance.name)
401
+ setupArgs(args, config, config.logs, hierarchy, uuid)
402
+ await results.apply(args)
403
+ } else {
404
+ if (results.skipSemantics) {
405
+ config.config.skipSemantics = results.skipSemantics
406
+ }
407
+ const args = { config, hierarchy, json: results, commandLineArgs: {} }
408
+ args.isInstance = `instance${i}`
409
+ args.instance = ''
410
+ await processContextsB(args)
411
+ if (results.skipSemantics) {
412
+ config.config.skipSemantics = null
413
+ }
414
+ }
415
+ }
416
+ global.transitoryMode = transitoryMode
417
+ }
418
+
419
+ module.exports = {
420
+ setupProcessB,
421
+ ErrorReason,
422
+ listable,
423
+ setupArgs,
424
+ processContext,
425
+ getObjects,
426
+ gs,
427
+ processContextsB,
428
+ loadInstance,
429
+ }