theprogrammablemind 8.0.0-beta.43 → 8.0.0-beta.45

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 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
+ }