diff --git a/server/src/core/brain.js b/server/src/core/brain.js index 18a7b23e..4cf49c12 100644 --- a/server/src/core/brain.js +++ b/server/src/core/brain.js @@ -160,7 +160,10 @@ class Brain { executionTime }) } else { - const { actionType } = obj + const { nluDataFilePath, classification: { action: actionName } } = obj + const { actions } = JSON.parse(fs.readFileSync(nluDataFilePath, 'utf8')) + const { type: actionType } = actions[actionName] + if (!actionType || !supportedActionTypes.includes(actionType)) { log.error(`This action type isn't supported: ${actionType}`) } diff --git a/server/src/core/conversation.js b/server/src/core/conversation.js index f8340e65..02c30d84 100644 --- a/server/src/core/conversation.js +++ b/server/src/core/conversation.js @@ -7,6 +7,7 @@ const defaultActiveContext = { domain: null, intent: null, slots: { }, + nextAction: null, activatedAt: 0 } @@ -57,9 +58,12 @@ class Conversation { // If slots are required to trigger next actions, then go through the context activation if (slotKeys.length > 0) { - // Grab output context from the NLU data file const { actions } = JSON.parse(fs.readFileSync(nluDataFilePath, 'utf8')) + const actionsKeys = Object.keys(actions) + // Grab output context from the NLU data file const { output_context: outputContext } = actions[actionName] + // Define next action + const [nextAction] = actionsKeys.filter((key) => actions[key].input_context === outputContext) /** * If there is an active context and a new one is triggered @@ -74,6 +78,7 @@ class Conversation { domain, intent, slots: { }, + nextAction, activatedAt: Date.now() } } diff --git a/server/src/core/nlu.js b/server/src/core/nlu.js index ccb49ee6..e80453da 100644 --- a/server/src/core/nlu.js +++ b/server/src/core/nlu.js @@ -120,9 +120,11 @@ class Nlu { const { domain, intent } = this.conv.activeContext const [skillName, actionName] = intent.split('.') const nluDataFilePath = join(process.cwd(), 'skills', domain, skillName, `nlu/${this.brain.lang}.json`) - const nluResultObj = { + // TODO: create specific method to build this important object + let nluResultObj = { utterance, entities: [], + nluDataFilePath, classification: { domain, skill: skillName, @@ -165,17 +167,30 @@ class Nlu { * 2. [OK] If none of them match any slot in the active context, then continue * 3. [OK] If an entity match slot in active context, then fill it * 4. [OK] Move skill type to action type - * 5.1 In Conversation, need to chain output/input contexts to each other + * 5.1 [OK] In Conversation, need to chain output/input contexts to each other * to understand what action should be next - * 5.2 Execute next action (based on input_context?) + * 5.2 [OK] Execute next action (based on input_context?) * 5.3 Need to handle the case if a context is filled in one shot * e.g. I wanna play with 2 players and louis.grenard@gmail.com - * 6. Split this process() method into several ones - * 7. Add logs in terminal about context switching, active context, etc. + * 6. What's next once the next action has been executed? + * 7. Handle a "loop" feature from action (guess the number) + * 8. Split this process() method into several ones + clean nlu.js and brain.js + * 9. Add logs in terminal about context switching, active context, etc. */ - // TODO: recreate nluResultObj for the NEXT action (actionType, etc.) - + nluResultObj = { + utterance: '', + entities: [], + // TODO: the brain needs to forward slots to the skill execution + slots: this.conv.activeContext.slots, + nluDataFilePath, + classification: { + domain, + skill: skillName, + action: this.conv.activeContext.nextAction + } + } + const data = await this.brain.execute(nluResultObj, { mute: opts.mute }) return resolve({ ...data @@ -280,10 +295,7 @@ class Nlu { log.success(`Intent found: ${nluResultObj.classification.skill}.${nluResultObj.classification.action} (domain: ${nluResultObj.classification.domain})`) const nluDataFilePath = join(process.cwd(), 'skills', nluResultObj.classification.domain, nluResultObj.classification.skill, `nlu/${this.brain.lang}.json`) - const { actions } = JSON.parse(fs.readFileSync(nluDataFilePath, 'utf8')) - const { type: actionType } = actions[actionName] - - nluResultObj.actionType = actionType + nluResultObj.nluDataFilePath = nluDataFilePath try { nluResultObj.entities = await this.ner.extractEntities( diff --git a/server/src/intent-object.sample.json b/server/src/intent-object.sample.json index 8217badf..3a03499a 100644 --- a/server/src/intent-object.sample.json +++ b/server/src/intent-object.sample.json @@ -1,7 +1,7 @@ { "lang": "en", - "domain": "checker", - "skill": "isitdown", + "domain": "utilities", + "skill": "is_it_down", "action": "run", "utterance": "Check if github.com, mozilla.org and twitter.com are up", "entities": [ diff --git a/skills/games/guess_the_number/src/actions/pick_up.py b/skills/games/guess_the_number/src/actions/pick_up.py new file mode 100644 index 00000000..6c57bc2a --- /dev/null +++ b/skills/games/guess_the_number/src/actions/pick_up.py @@ -0,0 +1,9 @@ +#!/usr/bin/env python +# -*- coding:utf-8 -*- + +import utils + +def pick_up(string, entities): + """This is a test""" + + return utils.output('end', 'ready', utils.translate('ready')) diff --git a/skills/games/guess_the_number/src/actions/run.py b/skills/games/guess_the_number/src/actions/run.py deleted file mode 100644 index ba3ed5dd..00000000 --- a/skills/games/guess_the_number/src/actions/run.py +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env python -# -*- coding:utf-8 -*- - -import utils -from random import randint - -def run(string, entities): - """TODO...""" - - return utils.output('end', 'ready', utils.translate('ready')