UNPKG

tpmkms

Version:

Reusable libraries for Entodicton, a natural language to json converter

203 lines (179 loc) 5.78 kB
const { debug, knowledgeModule, where, process:clientProcess } = require('./runtime').theprogrammablemind const { defaultContextCheck } = require('./helpers') const gdefaults = require('./gdefaults.js') const createCurrencyKM = require('./currency.js') const createTimeKM = require('./time.js') const { table } = require('table') const _ = require('lodash') const characters_tests = require('./characters.test.json') function getHelp(config, indent=2) { indent = ' '.repeat(indent) let help = '' help += `${indent}NAME: ${config.name}\n` help += `${indent}DESCRIPTION: ${config.description}\n\n` help += `${indent}SAMPLE SENTENCES\n\n` for (query of Object.keys(config.tests)) { help += `${indent} ${query}\n` } return help } /* get request -> process to contexts -> use "sally" to select user to send command to -> in semantics convert to paraphrase -> send paraphrase to sally -> get response back: sally said: blah */ const config = { name: 'characters', operators: [ "([([character])] (any))", "([help])", ], bridges: [ { id: 'character', level: 0, bridge: "{ ...next(operator), words: [] }" }, { id: 'character', level: 1, bridge: "{ ...operator, words: append(operator.words, after) }" }, { id: 'help', level: 0, bridge: "{ ...next(operator) }" }, ], "words": { "literals": { "sally": [{"id": "character", scope: "testing", "initial": "{ value: 'sally' }" }], "bob": [{"id": "character", scope: "testing", "initial": "{ value: 'bob' }" }], }, }, generators: [ { where: where(), match: ({context}) => context.marker == 'character' && context.paraphrase, apply: ({context}) => context.value + ", " + context.utterance }, { where: where(), match: ({context}) => context.marker == 'character' && context.isResponse, apply: ({context}) => 'Asked ' + context.value + " '" + context.utterance + "'" }, { where: where(), match: ({context}) => context.marker == 'character', apply: ({context}) => context.value }, { where: where(), match: ({context, config}) => context.marker == 'help', apply: ({context, config}) => { let help = `MAIN KNOWLEDGE MODULE\n\n` help += getHelp(config, 2) if (config.configs.length > 1) { help += '\n\n' help += 'INCLUDED KNOWLEDGE MODULES\n' for (km of config.configs) { if (km._config instanceof Config) { help += '\n' + getHelp(km._config, 4) } } } return help } }, ], semantics: [ { where: where(), match: ({context}) => context.marker == 'character', // ({context, config, km}) => { apply: (args) => { const {context, km, log} = args; const words = context.words.map( (context) => context.word ) const utterance = words.join(' ') const config = km('characters') const api = config._api.apis[context.value] api.process(config, utterance).then( (result) => { if (!api.response) { throw `WARNING characters km: the "response" handler for the api "${api.getName()}" is not defined so no callback is made` } else { api.response({ ...args, result }) } }) context.utterance = utterance context.isResponse = true } } ] }; class Sally { getName() { return "sally" } process(config, utterance) { // call the characters config to get response and return that. this is testing so I am not doing that /* if (utterance == 'what is the time') { return 'the magic has happened' } */ this.timeKM.server(config.getServer(), config.getAPIKey()) // return this.timeKM.process(utterance) return clientProcess(this.timeKM, utterance) } response({context, result}) { console.log('----------------------------------------') console.log(`${context.value} says: `, result.generated) console.log('----------------------------------------') } initialize() { } constructor(timeKM) { this.timeKM = timeKM } } class Bob { getName() { return "bob" } process(config, utterance) { this.currencyKM.server(config.getServer(), config.getAPIKey()) // return this.currencyKM.process(utterance, { credentials: this.credentials }) // return clientProcess(this.currencyKM.process, utterance, { credentials: this.credentials }) return clientProcess(this.currencyKM, utterance) } response({context, result}) { console.log('----------------------------------------') console.log(`${context.value} says: `, result.generated) console.log('----------------------------------------') } initialize() { } constructor(currencyKM) { this.currencyKM = currencyKM } } function initializeApi(config, api) { const name = api.getName(); config.addWord(name, {"id": "character", "initial": "{ value: '" + name + `', api: '${name}'}` }) } async function demoInitializer(config) { const timeKM = await createTimeKM() const currencyKM = await createCurrencyKM() const api = new Sally(timeKM) const api2 = new Bob(currencyKM) await config.setApi(() => api2) await config.setApi(() => api) } // mode this to non-module init only knowledgeModule({ config, includes: [gdefaults], demoInitializer, multiApiInitializer: initializeApi, module, description: 'this module is for creating a team of characters that can respond to commands', demo: "https://youtu.be/eA25GZ0ZAHo", test: { name: './characters.test.json', contents: characters_tests, checks: { context: [defaultContextCheck()], }, }, })