diff --git a/server/src/core/brain.js b/server/src/core/brain.js index 164d14be..14a8d1cf 100644 --- a/server/src/core/brain.js +++ b/server/src/core/brain.js @@ -190,6 +190,8 @@ class Brain { slots: obj.slots } + console.log('intentObjintentObjintentObj', intentObj) + try { fs.writeFileSync(intentObjectPath, JSON.stringify(intentObj)) this.process = spawn(`pipenv run python bridges/python/main.py ${intentObjectPath}`, { shell: true }) diff --git a/server/src/core/nlu.js b/server/src/core/nlu.js index 401dd3a6..8791abee 100644 --- a/server/src/core/nlu.js +++ b/server/src/core/nlu.js @@ -188,21 +188,40 @@ class Nlu { const processedData = await this.brain.execute(this.nluResultObj, { mute: opts.mute }) console.log('processedData', processedData) - const expectedItems = processedData.action.loop.expected_items.map(({ name }) => name) - // TODO: also check for resolvers, not only entities - const hasMatchingItem = processedData - .entities.filter(({ entity }) => expectedItems.includes(entity)).length > 0 - || processedData - .resolvers.filter(({ resolver }) => expectedItems.includes(resolver)).length > 0 + const { name: expectedItemName, type: expectedItemType } = processedData + .action.loop.expected_item + let hasMatchingEntity = false + let hasMatchingResolver = false - console.log('expectedItems', expectedItems[0]) - // TODO: only process expected_items includes resolvers - const testo = await this.nlp.process(utterance) - console.log('testo', testo) - // this.nluResultObj.resolvers = await this.resolveResolvers() + console.log('expectedItemName', expectedItemName) + if (expectedItemType === 'entity') { + hasMatchingEntity = processedData + .entities.filter(({ entity }) => expectedItemName === entity) + } else if (expectedItemType === 'resolver') { + const { intent } = await this.nlp.process(utterance) + const resolveResolvers = (resolver, intent) => { + const resolversPath = join(process.cwd(), 'core/data', this.brain.lang, 'resolvers') + const { intents } = JSON.parse(fs.readFileSync(join(resolversPath, `${resolver}.json`))) + + return [{ + name: expectedItemName, + value: intents[intent].value + }] + } + + // TODO: understand why the resolvers aren't correctly resolved on the Python side + + console.log('INTENT', intent) + this.nluResultObj.resolvers = resolveResolvers(expectedItemName, intent) + + hasMatchingResolver = this.nluResultObj.resolvers.length > 0 + // await this.process(utterance, opts) + } + + console.log('this.nluResultObj.resolvers', this.nluResultObj.resolvers) // Ensure expected items are in the utterance, otherwise clean context and reprocess - if (!hasMatchingItem) { + if (!hasMatchingEntity && !hasMatchingResolver) { this.brain.talk(`${this.brain.wernicke('random_context_out_of_topic')}.`) this.conv.cleanActiveContext() await this.process(utterance, opts) @@ -276,7 +295,6 @@ class Nlu { * Classify the utterance, * pick-up the right classification * and extract entities - * TODO: split this method into several methods */ process (utterance, opts) { console.log('process() start this.conv.activeContext', this.conv.activeContext) @@ -309,24 +327,16 @@ class Nlu { if (this.conv.hasActiveContext()) { // When the active context is in an action loop, then directly trigger the action if (this.conv.activeContext.isInActionLoop) { - console.log('111111') return resolve(await this.handleActionLoop(utterance, opts)) } - // TODO: make difference between context that needs slots and the ones who does not - // TODO: this case is only for slots context - // TODO: an action requiring slots must always have a next_action - console.log('THIS.CONV', this.conv.activeContext) // When the active context has slots filled if (Object.keys(this.conv.activeContext.slots).length > 0) { - console.log('222222') return resolve(await this.handleSlotFilling(utterance, opts)) } } - console.log('333333') const result = await this.nlp.process(utterance) - // console.log('result', result) const { locale, answers, classifications } = result @@ -565,7 +575,7 @@ class Nlu { * then break the loop. Need "loop" object in NLU skill config to describe * 8. [OK] Replay with the original utterance * 9. [OK] Be able to use the loop without necessarily need slots - * 10. Split this process() method into several ones + clean nlu.js and brain.js + * 10. [OK] Split this process() method into several ones + clean nlu.js and brain.js * 11. Add logs in terminal about context switching, active context, etc. */ diff --git a/server/src/intent-object.sample.json b/server/src/intent-object.sample.json index 2fcdd922..10bdb7bf 100644 --- a/server/src/intent-object.sample.json +++ b/server/src/intent-object.sample.json @@ -1,9 +1,9 @@ { "lang": "en", - "domain": "utilities", - "skill": "is_it_down", - "action": "run", - "utterance": "Check if github.com, mozilla.org and twitter.com are up", + "domain": "games", + "skill": "guess_the_number", + "action": "replay", + "utterance": "No no no", "slots": {}, "entities": [], "current_entities": [ @@ -31,5 +31,7 @@ "value": "twitter.com" } } - ] + ], + "current_resolvers": [], + "resolvers": [] } diff --git a/skills/games/guess_the_number/nlu/en.json b/skills/games/guess_the_number/nlu/en.json index d4170872..9312bf7a 100644 --- a/skills/games/guess_the_number/nlu/en.json +++ b/skills/games/guess_the_number/nlu/en.json @@ -13,24 +13,20 @@ "guess": { "type": "logic", "loop": { - "expected_items": [ - { - "type": "entity", - "name": "number" - } - ] + "expected_item": { + "type": "entity", + "name": "number" + } }, "next_action": "replay" }, "replay": { "type": "logic", "loop": { - "expected_items": [ - { - "type": "resolver", - "name": "affirmation_denial" - } - ] + "expected_item": { + "type": "resolver", + "name": "affirmation_denial" + } } } }, diff --git a/skills/games/guess_the_number/src/actions/replay.py b/skills/games/guess_the_number/src/actions/replay.py index 8acbb5d9..e857ad6b 100644 --- a/skills/games/guess_the_number/src/actions/replay.py +++ b/skills/games/guess_the_number/src/actions/replay.py @@ -6,20 +6,20 @@ import utils def replay(params): """This is a test""" - entities, slots = params['entities'], params['slots'] - decision = 0 + entities, resolvers, slots = params['entities'], params['resolvers'], params['slots'] + decision = False # Find entities # TODO: replace with confirmation resolver - for item in params['entities']: - if item['entity'] == 'number': - decision = item['resolution']['value'] + for resolver in resolvers: + if resolver['name'] == 'affirmation_denial': + decision = resolver['value'] - if decision == 1: - return utils.output('end', 'replay', 'Let\'s goooo', { + if decision == True: + return utils.output('end', 'replay', 'Let\'s goooo ' + str(decision), { 'isInActionLoop': False, 'restart': True }) - return utils.output('end', 'quit', 'As you wish', { 'isInActionLoop': False }) + return utils.output('end', 'quit', 'As you wish ' + str(decision), { 'isInActionLoop': False }) diff --git a/skills/games/rochambeau/nlu/en.json b/skills/games/rochambeau/nlu/en.json index 6c781786..a707060c 100644 --- a/skills/games/rochambeau/nlu/en.json +++ b/skills/games/rochambeau/nlu/en.json @@ -31,24 +31,20 @@ "play": { "type": "logic", "loop": { - "expected_items": [ - { - "type": "entity", - "name": "handsign" - } - ] + "expected_item": { + "type": "entity", + "name": "handsign" + } }, "next_action": "rematch" }, "rematch": { "type": "logic", "loop": { - "expected_items": [ - { - "type": "resolver", - "name": "number" - } - ] + "expected_item": { + "type": "resolver", + "name": "number" + } } } },