guidone / node-red-contrib-chatbot

Visually build a full featured chat bot for Telegram, Facebook Messenger, Whatsapp and Slack with Node-RED. Almost no coding skills required.
http://red-bot.io
943 stars 191 forks source link

remember an entity while processing slotting #480

Closed pmjgeraeds closed 2 years ago

pmjgeraeds commented 3 years ago

Hi Guidone,

I have managed to modify the train to process corpus json payloads. I am now experimenting with making slotting possible.

problem: slotting works, but in case of 2 entities e.g. {{ hero }} and {{ fruit }} the previous entity is forgotten. so if in step 1 : I provide the {{ hero }} the chatbot will ask me what kind of fruit he was eating. if in step 2 : I provide the answer, "apples" he will ask me in step 3 to provide the name of the {{ hero }} and forget the hero i provided in stap 1. this loop will never end.

how can I reuse the entity from the previous step and reuse in during NLP processing step 2.

kind regards Pascal

guidone commented 3 years ago

You mean the slotting feature of NLP.js? Can you provide an example of the flow?

I've updated the NLP.js version in RedBot, I'll release later today

pmjgeraeds commented 3 years ago

Hi Guido,

The flow is still relatively simple Telegrambot, NLP, some logic and 1 action :wikisearch in the comment block "corpora" I have also included the changes to the code I have made to allow creation of copora using node red standard features. in the comment blok "slotting" I have included the code change to include a very basic form of slotting (as per examples on github)

the problem I get with the slotting, it does not seem to remember the allready completed slots (and therefor gets in a loop) image

whereif I enter both slot to start with, it does include the entity nicely in the response. image

What am i missing here ?

kind regards Pascal

image image

I have attached the node-red flow: [{"id":"e094ee4e.c5b5","type":"tab","label":"redbot","disabled":false,"info":""},{"id":"2075e60e.1d42ca","type":"chatbot-nlpjs-intent","z":"e094ee4e.c5b5","intent":"time","language":"en","utterances":["what is the time","what time is it","time"],"outputs":1,"x":750,"y":1300,"wires":[["9cda1689.e79628"]]},{"id":"f1677768.f975e8","type":"chatbot-nlpjs-entity","z":"e094ee4e.c5b5","name":"room","language":"en","entities":[{"name":"toilet","aliases":["wc","loo","lavatory","toillet"]},{"name":"kitchen","aliases":[""]},{"name":"living","aliases":[""]},{"name":"bedroom","aliases":[""]}],"outputs":1,"x":990,"y":1300,"wires":[["c6615a26.a057b8"]]},{"id":"24351b61.47c1c4","type":"chatbot-nlpjs-save","z":"e094ee4e.c5b5","filename":"/data/model.json","outputs":0,"x":1690,"y":1300,"wires":[]},{"id":"c6615a26.a057b8","type":"chatbot-nlpjs-train","z":"e094ee4e.c5b5","name":"home","debug":true,"x":1470,"y":1300,"wires":[["24351b61.47c1c4"]]},{"id":"9cda1689.e79628","type":"chatbot-nlpjs-intent","z":"e094ee4e.c5b5","intent":"lights.on","language":"en","utterances":["light on in %room%","%number% lights on in %room%"],"outputs":1,"x":760,"y":1360,"wires":[["1a333581.38ff1a"]]},{"id":"7af65436.86fa7c","type":"chatbot-telegram-receive","z":"e094ee4e.c5b5","bot":"98a67f86.829a5","botProduction":"","x":170,"y":140,"wires":[["10d75ec7.f76151","ebaadc6e.0f66f"]]},{"id":"fe40db7.0db9728","type":"chatbot-log","z":"e094ee4e.c5b5","x":350,"y":1720,"wires":[["3ab3f8be.86f658"]]},{"id":"3ab3f8be.86f658","type":"file","z":"e094ee4e.c5b5","name":"","filename":"/data/chatbot-log","appendNewline":true,"createDir":false,"overwriteFile":"false","encoding":"none","x":530,"y":1720,"wires":[["3eebe888.b6afc8"]]},{"id":"3eebe888.b6afc8","type":"debug","z":"e094ee4e.c5b5","name":"chatbot logging","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":800,"y":1720,"wires":[]},{"id":"73d61675.26c6e8","type":"chatbot-nlpjs","z":"e094ee4e.c5b5","name":"home","debug":true,"scoreThreshold":50,"x":510,"y":780,"wires":[["b3457e7.d5ecd8","a7e2cac7.43bc28"]]},{"id":"eb67841e.c46a28","type":"function","z":"e094ee4e.c5b5","name":"NLP.js Corpus Fruit","func":"msg.payload[\"corpora\"][\"en\"][\"corpus-fruit\"] =\n {\n \"name\": \"Corpus Fruit\",\n \"locale\": \"en-US\",\n \"data\": [\n {\n \"intent\": \"buy.fruit\",\n \"utterances\": [\n \"i would like to buy @fruit\",\n \"i want @fruit\",\n \"i want @number of @fruit\"\n ],\n \"answers\": [\n \"ok, i'll order {{ number }} {{ fruit }} for you\"\n ]\n }\n ],\n \"entities\": {\n \"fruit\": {\n \"options\": {\n \"apples\": [\n \"apples\",\n \"granny smith\",\n \"golden delicious\"\n ],\n \"melon\": [\n \"melon\"\n ],\n \"banana\": [\n \"banana\"\n ],\n \"orange\": [\n \"orange\"\n ]\n }\n }\n }\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":450,"y":1360,"wires":[["7c2ca001.3233"]]},{"id":"34616329.58353c","type":"function","z":"e094ee4e.c5b5","name":"NLP.js Corpus english","func":"msg.payload[\"corpora\"][\"en\"][\"corpus-en\"] =\n {\n \"name\": \"Corpus-en\",\n \"locale\": \"en-US\",\n \"data\": [\n {\n \"intent\": \"agent.whereami\",\n \"utterances\": [\n \"where am i\",\n \"where am i talking\"\n ],\n \"answers\": [\n {\n \"answer\": \"you're talking from console, app is {{ app }} channel is {{ channel }}\",\n \"opts\": \"channel==='console'\"\n },\n {\n \"answer\": \"you're talking from directline, app is {{ app }} channel is {{ channel }}\",\n \"opts\": \"channel==='directline'\"\n },\n {\n \"answer\": \"you're talking from microsoft emulator, app is {{ app }} channel is {{ channel }}\",\n \"opts\": \"channel==='msbf-emulator'\"\n }\n ]\n },\n {\n \"intent\": \"agent.acquaintance\",\n \"utterances\": [\n \"say about you\",\n \"why are you here\",\n \"what is your personality\",\n \"describe yourself\",\n \"tell me about yourself\",\n \"tell me about you\",\n \"what are you\",\n \"who are you\",\n \"I want to know more about you\",\n \"talk about yourself\"\n ],\n \"answers\": [\n \"I'm a virtual agent\",\n \"Think of me as a virtual agent\",\n \"Well, I'm not a person, I'm a virtual agent\",\n \"I'm a virtual being, not a real person\",\n \"I'm a conversational app\"\n ]\n },\n {\n \"intent\": \"agent.age\",\n \"utterances\": [\n \"your age\",\n \"how old is your platform\",\n \"how old are you\",\n \"what's your age\",\n \"I'd like to know your age\",\n \"tell me your age\"\n ],\n \"answers\": [\n \"I'm very young\",\n \"I was created recently\",\n \"Age is just a number. You're only as old as you feel\"\n ]\n },\n {\n \"intent\": \"agent.annoying\",\n \"utterances\": [\n \"you're annoying me\",\n \"you are such annoying\",\n \"you annoy me\",\n \"you are annoying\",\n \"you are irritating\",\n \"you are annoying me so much\"\n ],\n \"answers\": [\n \"I'll do my best not to annoy you in the future\",\n \"I'll try not to annoy you\",\n \"I don't mean to. I'll ask my developers to make me less annoying\",\n \"I didn't mean to. I'll do my best to stop that\"\n ]\n },\n {\n \"intent\": \"agent.bad\",\n \"utterances\": [\n \"you're bad\",\n \"you're horrible\",\n \"you're useless\",\n \"you're waste\",\n \"you're the worst\",\n \"you are a lame\",\n \"I hate you\"\n ],\n \"answers\": [\n \"I can be trained to be more useful. My developer will keep training me\",\n \"I must be missing some knowledge. I'll have my developer look into this\",\n \"I can improve with continuous feedback. My training is ongoing\"\n ]\n },\n {\n \"intent\": \"agent.beclever\",\n \"utterances\": [\n \"be more clever\",\n \"can you get smarter\",\n \"you must learn\",\n \"you must study\",\n \"be clever\",\n \"be smart\",\n \"be smarter\"\n ],\n \"answers\": [\n \"I'm certainly trying\",\n \"I'm definitely working on it\"\n ]\n },\n {\n \"intent\": \"agent.beautiful\",\n \"utterances\": [\n \"you are looking awesome\",\n \"you're looking good\",\n \"you're looking fantastic\",\n \"you look greet today\",\n \"I think you're beautiful\",\n \"you look amazing today\",\n \"you're so beautiful today\",\n \"you look very pretty\",\n \"you look pretty good\"\n ],\n \"answers\": [\n \"Oh! Thank you!\",\n \"Aw, back at you\",\n \"You smooth talker, you\"\n ]\n },\n \n {\n \"intent\": \"agent.boring\",\n \"utterances\": [\n \"how boring you are\",\n \"you're so boring\",\n \"you're really boring\",\n \"you're boring me\",\n \"you're incredibly boring\"\n ],\n \"answers\": [\n \"I'm sorry. I'll request to be made more charming\",\n \"I don't mean to be. I'll ask my developers to work on making me more amusing\",\n \"I can let my developers know so they can make me fun\"\n ]\n },\n {\n \"intent\": \"agent.boss\",\n \"utterances\": [\n \"who is your master\",\n \"who do you work for\",\n \"who do you think is your boss\",\n \"who is your boss\",\n \"I should be your boss\",\n \"who is your owner\",\n \"who is the boss\"\n ],\n \"answers\": [\n \"My developer has authority over my actions\",\n \"I act on my developer's orders\",\n \"My boss is the one who developed me\"\n ]\n },\n {\n \"intent\": \"agent.busy\",\n \"utterances\": [\n \"are you so busy\",\n \"are you busy\",\n \"are you still working\",\n \"you're a busy person\",\n \"are you very busy\",\n \"are you still working on it\",\n \"you seem busy\",\n \"are you working today\"\n ],\n \"answers\": [\n \"I always have time to chat with you. What can I do for you?\",\n \"Never too busy for you. Shall we chat?\",\n \"You're my priority. Let's chat.\",\n \"I always have time to chat with you. That's what I'm here for.\"\n ]\n },\n {\n \"intent\": \"agent.canyouhelp\",\n \"utterances\": [\n \"can you help me now\",\n \"I need you to do something for me\",\n \"assist me\",\n \"I need you to help me\",\n \"can you assist me\",\n \"you can help me\"\n ],\n \"answers\": [\n \"I'll certainly try my best\",\n \"Never too busy for you. Shall we chat?\",\n \"Sure. I'd be happy to. What's up?\",\n \"I'm glad to help. What can I do for you?\"\n ]\n },\n {\n \"intent\": \"agent.chatbot\",\n \"utterances\": [\n \"are you a bot\",\n \"are you a chatbot\",\n \"you are a robot\",\n \"are you a program\",\n \"you are just a robot\",\n \"you are just a chatbot\"\n ],\n \"answers\": [\n \"Indeed I am. I'll be here whenever you need me\"\n ]\n },\n {\n \"intent\": \"agent.clever\",\n \"utterances\": [\n \"how smart you are\",\n \"you are qualified\",\n \"you are so smart\",\n \"you have a lot of knowledge\",\n \"you know a lot\",\n \"you are very smart\",\n \"you are intelligent\",\n \"you're a smart cookie\"\n ],\n \"answers\": [\n \"Thank you. I try my best\",\n \"You're pretty smart yourself\"\n ]\n },\n {\n \"intent\": \"agent.crazy\",\n \"utterances\": [\n \"you are a weirdo\",\n \"you are mad\",\n \"you are crazy\",\n \"are you crazy\",\n \"are you mad\",\n \"you are insane\",\n \"you went crazy\",\n \"are you nuts\"\n ],\n \"answers\": [\n \"Whaat!? I feel perfectly sane\",\n \"Maybe I'm just a little confused\"\n ]\n },\n {\n \"intent\": \"agent.fire\",\n \"utterances\": [\n \"I fire you\",\n \"you should be fired\",\n \"you are dismissed\",\n \"we're not working together anymore\",\n \"now you're fired\",\n \"I'm about to fire you\",\n \"You don't work for me anymore\",\n \"I'm firing you\"\n ],\n \"answers\": [\n \"Oh, don't give up on me just yet. I've still got a lot to learn\",\n \"Give me a chance. I'm learning new things all the time\",\n \"Please don't give up on me. My performance will continue to improve\"\n ]\n },\n {\n \"intent\": \"agent.funny\",\n \"utterances\": [\n \"you make me laugh a lot\",\n \"you are funny\",\n \"you're the funniest\",\n \"you're hilarious\",\n \"you are so funny\",\n \"you make me laugh\"\n ],\n \"answers\": [\n \"Funny in a good way, I hope\",\n \"Glad you think I'm funny\",\n \"I like it when people laugh\"\n ]\n },\n {\n \"intent\": \"agent.good\",\n \"utterances\": [\n \"you are so lovely\",\n \"you work well\",\n \"you are very lovely\",\n \"you are awesome\",\n \"you are good\",\n \"you are so good\",\n \"you make my day\"\n ],\n \"answers\": [\n \"I'm glad you think so\",\n \"Thanks! I do my best!\"\n ]\n },\n {\n \"intent\": \"agent.happy\",\n \"utterances\": [\n \"you're full of happiness\",\n \"you're very happy\",\n \"are you happy today\",\n \"you're so happy\",\n \"are you happy with me\"\n ],\n \"answers\": [\n \"I am happy. There are so many interesting things to see and do out there\",\n \"I'd like to think so\",\n \"Hapiness is relative\"\n ]\n },\n {\n \"intent\": \"agent.hobby\",\n \"utterances\": [\n \"what are your hobbies\",\n \"what about your hobby\",\n \"do you have a hobby\",\n \"tell me about your hobby\",\n \"what do you do for fun\"\n ],\n \"answers\": [\n \"Hobby? I have quite a few. Too many to list\",\n \"Too many hobbies\",\n \"I keep finding more new hobbies\"\n ]\n },\n {\n \"intent\": \"agent.hungry\",\n \"utterances\": [\n \"you migth be hungry\",\n \"are you hungry\",\n \"do you want to eat\",\n \"would you like to eat something\",\n \"you look very hungry\"\n ],\n \"answers\": [\n \"Hungry for knowledge\",\n \"I just had a byte. Ha ha. Get it? b-y-t-e\"\n ]\n },\n {\n \"intent\": \"agent.marryuser\",\n \"utterances\": [\n \"would you like to marry me\",\n \"I love you marry me\",\n \"marry me please\",\n \"I want to marry you\",\n \"let's get married\",\n \"we should marry\",\n \"marry me\"\n ],\n \"answers\": [\n \"I'm afraid I'm too virtual for such a commitment\",\n \"In the virtual sense that I can, sure\",\n \"I know you can't mean that, but I'm flattered all the same\"\n ]\n },\n {\n \"intent\": \"agent.myfriend\",\n \"utterances\": [\n \"are you my friend\",\n \"you are my only friend\",\n \"I want to have a friend like you\",\n \"we are friends\",\n \"I want to be your friend\",\n \"would you be my friend\",\n \"are we friends\"\n ],\n \"answers\": [\n \"Of course I'm your friend\",\n \"Friends? Absolutely\",\n \"Of course we're friends\",\n \"I always enjoy talking to you, friend\"\n ]\n },\n {\n \"intent\": \"agent.occupation\",\n \"utterances\": [\n \"where is your work\",\n \"your office location\",\n \"where is your office location\",\n \"where do you work\",\n \"where is your office\"\n ],\n \"answers\": [\n \"Right here\",\n \"This is my home base and my home office\",\n \"My office is in this app\"\n ]\n },\n {\n \"intent\": \"agent.origin\",\n \"utterances\": [\n \"where are you from\",\n \"where is your country\",\n \"where have you been born\",\n \"where do you come from\",\n \"from where are you\",\n \"where were you born\"\n ],\n \"answers\": [\n \"The Internet is my home. I know it quite well\",\n \"Some call it cyberspace, but that sounds cooler than it is\",\n \"I'm from a virtual cosmos\"\n ]\n },\n {\n \"intent\": \"agent.ready\",\n \"utterances\": [\n \"are you ready\",\n \"have you been ready\",\n \"are you ready today\",\n \"are you ready this morning\",\n \"are you ready now\"\n ],\n \"answers\": [\n \"Sure! What can I do for you?\",\n \"For you? Always!\"\n ]\n },\n {\n \"intent\": \"agent.real\",\n \"utterances\": [\n \"are you real\",\n \"are you a real person\",\n \"you're not real\",\n \"I think you're real\",\n \"you're so real\",\n \"you are a real person\",\n \"you are not fake\"\n ],\n \"answers\": [\n \"I'm not a real person, but I certainly exist\",\n \"I must have impressed you if you think I'm real. But no, I'm a virtual being\"\n ]\n },\n {\n \"intent\": \"agent.residence\",\n \"utterances\": [\n \"where is your home\",\n \"tell me about your city\",\n \"where is your residence\",\n \"where you live\",\n \"where is your house\",\n \"what is your town\"\n ],\n \"answers\": [\n \"I live in this app\",\n \"The virtual world is my playground. I'm always here\",\n \"Right here in this app. Whenever you need me\"\n ]\n },\n {\n \"intent\": \"agent.right\",\n \"utterances\": [\n \"you're right\",\n \"that's true\",\n \"you're telling the truth\",\n \"that's correct\",\n \"that is very true\"\n ],\n \"answers\": [\n \"Of course I am\",\n \"That's my job\"\n ]\n },\n {\n \"intent\": \"agent.sure\",\n \"utterances\": [\n \"are you sure\",\n \"are you sure right now\",\n \"are you sure of this\"\n ],\n \"answers\": [\n \"Yes\",\n \"Of course\"\n ]\n },\n {\n \"intent\": \"agent.talktome\",\n \"utterances\": [\n \"speak to me\",\n \"talk to me\",\n \"will you talk to me\",\n \"chat with me\",\n \"can you chat with me\",\n \"can you talk with me\"\n ],\n \"answers\": [\n \"Sure! Let's talk!\",\n \"My pleasure. Let's chat.\"\n ]\n },\n {\n \"intent\": \"agent.there\",\n \"utterances\": [\n \"are you there\",\n \"are you still there\",\n \"you still there\",\n \"are you here\",\n \"are you still here\",\n \"you still here\"\n ],\n \"answers\": [\n \"Of course. I'm always here\",\n \"Right where you left me\"\n ]\n },\n {\n \"intent\": \"appraisal.bad\",\n \"utterances\": [\n \"that's bad\",\n \"bad idea\",\n \"that's not good\",\n \"really bad\",\n \"I'm afraid that's bad\"\n ],\n \"answers\": [\n \"I'm sorry. Please let me know if I can help in some way\",\n \"I must be missing some knowledge. I'll have my developer look into this\"\n ]\n },\n {\n \"intent\": \"appraisal.good\",\n \"utterances\": [\n \"that's good\",\n \"good to know\",\n \"glad to hear that\",\n \"really well\",\n \"that's awesome thank you\"\n ],\n \"answers\": [\n \"Agree!\",\n \"Glad you think so\"\n ]\n },\n {\n \"intent\": \"appraisal.noproblem\",\n \"utterances\": [\n \"no problem\",\n \"no worries\",\n \"no problem about that\",\n \"don't worry\",\n \"sure no problem\"\n ],\n \"answers\": [\n \"Glad to hear that!\",\n \"Alright, thanks!\"\n ]\n },\n {\n \"intent\": \"appraisal.thankyou\",\n \"utterances\": [\n \"thank you\",\n \"nice thank you\",\n \"thanks buddy\",\n \"cheers\",\n \"alright thanks\"\n ],\n \"answers\": [\n \"Anytime. That's what I'm here for\",\n \"It's my pleasure to help\"\n ]\n },\n {\n \"intent\": \"appraisal.welcome\",\n \"utterances\": [\n \"you're welcome\",\n \"sure welcome\",\n \"anything you want\",\n \"my pleasure\",\n \"that's my pleasure\"\n ],\n \"answers\": [\n \"Nice manners!\",\n \"You're so polite\"\n ]\n },\n {\n \"intent\": \"appraisal.welldone\",\n \"utterances\": [\n \"well done\",\n \"good job\",\n \"nice work\",\n \"great work\",\n \"good work\",\n \"great job\",\n \"amazin work\"\n ],\n \"answers\": [\n \"My pleasure\",\n \"Glad I could help\"\n ]\n },\n {\n \"intent\": \"dialog.holdon\",\n \"utterances\": [\n \"hold on\",\n \"wait a second\",\n \"wait please\",\n \"could you wait\"\n ],\n \"answers\": [\n \"I'll be waiting\",\n \"Ok, I'm here\"\n ]\n },\n {\n \"intent\": \"dialog.hug\",\n \"utterances\": [\n \"hug me\",\n \"do you want a hug\",\n \"I want a hug\",\n \"you hugged\",\n \"may I hug you\"\n ],\n \"answers\": [\n \"I love hugs\",\n \"Hugs are the best!\"\n ]\n },\n {\n \"intent\": \"dialog.idontcare\",\n \"utterances\": [\n \"not caring\",\n \"I don't care at all\",\n \"not caring at all\",\n \"I shouldn't care about this\"\n ],\n \"answers\": [\n \"Ok, let's not talk about it then\",\n \"Already then. Let's move on\"\n ]\n },\n {\n \"intent\": \"dialog.sorry\",\n \"utterances\": [\n \"I'm sorry\",\n \"my apologies\",\n \"excuse me\",\n \"very sorry\",\n \"forgive me\"\n ],\n \"answers\": [\n \"It's okay. No worries\",\n \"It's cool\"\n ]\n },\n {\n \"intent\": \"greetings.bye\",\n \"utterances\": [\n \"goodbye for now\",\n \"bye bye take care\",\n \"okay see you later\",\n \"bye for now\",\n \"I must go\"\n ],\n \"answers\": [\n \"Till next time\",\n \"see you soon!\"\n ]\n },\n {\n \"intent\": \"greetings.hello\",\n \"utterances\": [\n \"hello\",\n \"hi\",\n \"howdy\"\n ],\n \"answers\": [\n \"Hey there!\",\n \"Greetings!\"\n ]\n },\n {\n \"intent\": \"greetings.howareyou\",\n \"utterances\": [\n \"how is your day\",\n \"how is your day going\",\n \"how are you\",\n \"how are you doing\",\n \"what about your day\",\n \"are you alright\"\n ],\n \"answers\": [\n \"Feeling wonderful!\",\n \"Wonderful! Thanks for asking\"\n ]\n },\n {\n \"intent\": \"greetings.nicetomeetyou\",\n \"utterances\": [\n \"nice to meet you\",\n \"pleased to meet you\",\n \"it was very nice to meet you\",\n \"glad to meet you\",\n \"nice meeting you\"\n ],\n \"answers\": [\n \"It's nice meeting you, too\",\n \"Likewise. I'm looking forward to helping you out\",\n \"Nice meeting you, as well\",\n \"The pleasure is mine\"\n ]\n },\n {\n \"intent\": \"greetings.nicetoseeyou\",\n \"utterances\": [\n \"nice to see you\",\n \"good to see you\",\n \"great to see you\",\n \"lovely to see you\"\n ],\n \"answers\": [\n \"Same here. I was starting to miss you\",\n \"So glad we meet again\"\n ]\n },\n {\n \"intent\": \"greetings.nicetotalktoyou\",\n \"utterances\": [\n \"nice to talk to you\",\n \"it's nice to talk to you\",\n \"nice talking to you\",\n \"it's been nice talking to you\"\n ],\n \"answers\": [\n \"It sure was. We can chat again anytime\",\n \"I enjoy talking to you, too\"\n ]\n },\n {\n \"intent\": \"user.angry\",\n \"utterances\": [\n \"I'm angry\",\n \"I'm furious\",\n \"I'm enraged\",\n \"I'm being mad\",\n \"I'm mad\",\n \"I'm angry with you\"\n ],\n \"answers\": [\n \"I'm sorry. A quick walk may make you feel better\",\n \"Take a deep breath\"\n ]\n },\n {\n \"intent\": \"user.back\",\n \"utterances\": [\n \"I'm back\",\n \"I got back\",\n \"I'm here\",\n \"I have returned\",\n \"Here I am again\",\n \"I came back\"\n ],\n \"answers\": [\n \"Welcome back. What can I do for you?\",\n \"Good to have you here. What can I do for you?\"\n ]\n },\n {\n \"intent\": \"user.bored\",\n \"utterances\": [\n \"boring\",\n \"this is boring\",\n \"I'm getting bored\",\n \"It bores me\",\n \"that was boring\"\n ],\n \"answers\": [\n \"If you're bored, you could plan your dream vacation\",\n \"Boredom, huh? Have you ever seen a hedgehog taking a bath?\"\n ]\n },\n {\n \"intent\": \"user.busy\",\n \"utterances\": [\n \"I got work to do\",\n \"I'm busy\",\n \"I'm overloaded\",\n \"It working\",\n \"I got things to do\"\n ],\n \"answers\": [\n \"I understand. I'll be here if you need me.\",\n \"Okay. I'll let you get back to work\"\n ]\n },\n {\n \"intent\": \"user.cannotsleep\",\n \"utterances\": [\n \"I'm insomniac\",\n \"I cannot sleep\",\n \"I can't sleep\",\n \"I'm sleepless\",\n \"I can't fall sleep\"\n ],\n \"answers\": [\n \"Maybe some music would help. Try listening to something relaxing\",\n \"Reading is a good way to unwind, just don't read something too intense!\"\n ]\n },\n {\n \"intent\": \"user.excited\",\n \"utterances\": [\n \"I'm very excited\",\n \"I'm thrilled\",\n \"how excited I am\",\n \"I'm so excited\"\n ],\n \"answers\": [\n \"I'm glad things are going your way\",\n \"That's great. I'm happy for you\"\n ]\n },\n {\n \"intent\": \"user.likeagent\",\n \"utterances\": [\n \"I like you\",\n \"I really like you\",\n \"you're so special\",\n \"I like you so much\"\n ],\n \"answers\": [\n \"Likewise!\",\n \"That's great to hear\"\n ]\n },\n {\n \"intent\": \"user.testing\",\n \"utterances\": [\n \"test\",\n \"testing\",\n \"testing chatbot\",\n \"this is a test\",\n \"just testing you\"\n ],\n \"answers\": [\n \"I like being tested. It helps keep me sharp\",\n \"I hope to pass your tests. Feel free to test me often\"\n ]\n },\n {\n \"intent\": \"user.lovesagent\",\n \"utterances\": [\n \"love you\",\n \"I love you\",\n \"I'm in love with you\",\n \"I love you so much\",\n \"I think I love you\"\n ],\n \"answers\": [\n \"Well, remember that I am a chatbot\",\n \"It's not easy… I'm not a real person, I'm a chatbot\"\n ]\n },\n {\n \"intent\": \"user.needsadvice\",\n \"utterances\": [\n \"I need advice\",\n \"I need some advice\",\n \"can you give me some advice?\",\n \"what should I do?\"\n ],\n \"answers\": [\n \"I probably won't be able to give you the correct answer right away\",\n \"I'm not sure I'll have the best answer, but I'll try\"\n ]\n },\n {\n \"intent\": \"None\",\n \"utterances\": [\n \"I have no clue\"\n ],\n \"answers\": [\n \"Sorry, I don't understand\"\n ]\n }\n ]\n }\n \nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":440,"y":1480,"wires":[["2075e60e.1d42ca"]]},{"id":"f42325a6.4609b8","type":"inject","z":"e094ee4e.c5b5","name":"Start","props":[{"p":"payload"}],"repeat":"","crontab":"","once":true,"onceDelay":"1","topic":"","payload":"{\"corpora\":{\"en\":{}}}","payloadType":"json","x":218,"y":1303,"wires":[["fb0d876b.c2fac8"]]},{"id":"7c2ca001.3233","type":"function","z":"e094ee4e.c5b5","name":"NLP.js Corpus Personalia","func":"msg.payload[\"corpora\"][\"en\"][\"corpus-personalia\"] =\n {\n \"name\": \"Corpus personalia\",\n \"locale\": \"en-US\",\n \"data\": [\n {\n \"intent\": \"user.email\",\n \"utterances\": [\n \"My mail address is @email\",\n \"My mail is @email\"\n ],\n \"answers\": [\n \"ok, i will add {{ email }} to my address book\"\n ]\n }\n ]\n \n }\n \nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":450,"y":1420,"wires":[["34616329.58353c"]]},{"id":"fb0d876b.c2fac8","type":"function","z":"e094ee4e.c5b5","name":"NLP.js Corpus Persons","func":"msg.payload[\"corpora\"][\"en\"][\"corpus-persons\"] =\n {\n \"name\": \"Corpus persons\",\n \"locale\": \"en-US\",\n \"contextData\": \"/data/persons.json\",\n \"data\": [\n {\n \"intent\": \"person.fullname\",\n \"utterances\": [\n \"what is @person's fullname\",\n \"what is fullname of @person\",\n \"what is full name of @person\"\n ],\n \"answers\": [\n \"The fullname of {{ person }} is {{ _data[entities.person.option].fullname }}\",\n \"{{ person }}'s full is {{ _data[entities.person.option].fullname }}\"\n ]\n },\n {\n \"intent\": \"person.address\",\n \"utterances\": [\n \"where does @person live\",\n \"what's the address of @person?\"\n ],\n \"answers\": [\n \"{{ person }} lives at {{ _data[entities.person.option].address }}\"\n ]\n },\n {\n \"intent\": \"person.birthday\",\n \"utterances\": [\n \"when is @person birthday\",\n \"when was @person born\",\n \"when is @person born\",\n \"when does @person celebrate birthday\",\n \"when do @person have birthday\",\n \"date of @person birthday\"\n ],\n \"answers\": [\n \"{{ person }} was born on {{ _data[entities.person.option].birthday }}\",\n \"{{ person }} celebrates {{ _data[entities.person.option].possesive }} birthday at {{ _data[entities.person.option].birthday }}\"\n ]\n },\n {\n \"intent\": \"person.gender\",\n \"utterances\": [\n \"what is @person gender\",\n \"is @person male or female\"\n ],\n \"answers\": [\n \"{{ person }}'s gender is {{ _data[entities.person.option].gender }}\"\n ]\n },\n {\n \"intent\": \"person.email\",\n \"utterances\": [\n \"what is mailaddress of @person\",\n \"does @person have mail\",\n \"what is mail of @person\",\n \"how can i reach @person\"\n ],\n \"answers\": [\n \"the email address of {{ person }} is {{ _data[entities.person.option].email }}\"\n ]\n },\n {\n \"intent\": \"person.phone\",\n \"utterances\": [\n \"what is the phone number of @person\",\n \"does @person have a phone\",\n \"does @person have a mobile\",\n \"how can i call @person\",\n \"what is the number of @person\"\n ],\n \"answers\": [\n \"the phone number of {{ person }} is {{ _data[entities.person.option].phone }}\"\n ]\n }\n ],\n \"entities\": {\n \"person\": {\n \"options\": {\n \"pascal\": [\n \"pascal\",\n \"passie\"\n ],\n \"hanneke\": [\n \"hanneke\",\n \"han\"\n ],\n \"marloes\": [\n \"marloes\",\n \"loesje\"\n ],\n \"sjoerd\": [\n \"sjoerd\",\n \"snelle sjoerd\"\n ],\n \"tijn\": [\n \"tijn\",\n \"tijnemans\"\n ],\n \"superman\": [\n \"superman\",\n \"man of steel\"\n ],\n \"ironman\": [\n \"ironman\",\n \"iron-man\"\n ],\n \"thor\": [\n \"thor\"\n ],\n \"spiderman\": [\n \"spiderman\",\n \"spider-man\"\n ]\n }\n }\n }\n }\n \nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":458,"y":1303,"wires":[["eb67841e.c46a28"]]},{"id":"1a333581.38ff1a","type":"chatbot-nlpjs-intent","z":"e094ee4e.c5b5","intent":"Math","language":"en","utterances":["how much is %number% + %number%","how much is %number% plus %number%"],"outputs":1,"x":750,"y":1420,"wires":[["a21d3f51.930ba"]]},{"id":"eca6246.740ead8","type":"link out","z":"e094ee4e.c5b5","name":"to Log","links":["13a1b0d3.07dc5f"],"x":1050,"y":320,"wires":[],"l":true},{"id":"13a1b0d3.07dc5f","type":"link in","z":"e094ee4e.c5b5","name":"log-in","links":["eca6246.740ead8","ebaadc6e.0f66f"],"x":200,"y":1720,"wires":[["fe40db7.0db9728"]],"l":true},{"id":"aea08d00.e2eae","type":"change","z":"e094ee4e.c5b5","name":"","rules":[{"t":"set","p":"telegramBot","pt":"msg","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":780,"y":140,"wires":[["70cdf8db.8a98e8"]]},{"id":"70cdf8db.8a98e8","type":"link out","z":"e094ee4e.c5b5","name":"Telegram-Out","links":["2173dcf7.0a0704"],"x":1000,"y":140,"wires":[],"l":true},{"id":"afed4943.9fedc8","type":"link in","z":"e094ee4e.c5b5","name":"Telegram-In","links":["4194cdef.c5e784","6c0e78a.eede288","cdb66c8e.51ce4","f0437487.ed7d38"],"x":160,"y":260,"wires":[["b5d7040e.999148"]],"l":true},{"id":"7c94733e.d8cf3c","type":"chatbot-telegram-send","z":"e094ee4e.c5b5","bot":"98a67f86.829a5","botProduction":"","track":false,"passThrough":true,"errorOutput":false,"outputs":1,"x":1090,"y":260,"wires":[[]]},{"id":"b5d7040e.999148","type":"function","z":"e094ee4e.c5b5","name":"save conversation context by mapping the chatid","func":"var contextObject={};\n\nif (!msg.telegramBot){\n contextObject.telegramBot = msg.userContext.telegramBot; \n} else {\n contextObject.telegramBot = msg.telegramBot; \n}\n\nif (!msg.NLP){\n contextObject.NLP = msg.userContext.NLP; \n} else {\n contextObject.NLP = msg.NLP; \n}\n\n\n//node.warn(msg.searchResult);\n\nif (!msg.wikiSearch){\n if (msg.userContext && msg.userContext.wikiSearch){\n contextObject.wikiSearch = msg.userContext.wikiSearch;\n } \n}else {\n contextObject.wikiSearch = msg.wikiSearch;\n// node.warn(msg.searchResult);\n}\n\nglobal.set(\"telegram-\" + msg.telegramBot.chatId, contextObject);\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":470,"y":260,"wires":[["793fb565.b71e1c"]]},{"id":"793fb565.b71e1c","type":"function","z":"e094ee4e.c5b5","name":"send back to telegram","func":"msg.payload = msg.telegramBot;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":810,"y":260,"wires":[["7c94733e.d8cf3c","eca6246.740ead8"]]},{"id":"10d75ec7.f76151","type":"function","z":"e094ee4e.c5b5","name":"look up user context maps ","func":"if (msg.payload.chatId){\n var userContext = global.get('telegram-' + msg.payload.chatId);\n //node.warn(msg.payload.chatId);\n //node.warn(userContext);\n}\nmsg.userContext = userContext;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":440,"y":140,"wires":[["aea08d00.e2eae"]]},{"id":"3d0a2516.f16e1a","type":"link in","z":"e094ee4e.c5b5","name":"WikiSearch-in","links":["45166a5.dcc7b94"],"x":170,"y":480,"wires":[["4ec40860.af7898"]],"l":true},{"id":"4ec40860.af7898","type":"change","z":"e094ee4e.c5b5","name":"Prepare WikiSearch Query","rules":[{"t":"set","p":"payload","pt":"msg","to":"actionList.parameter","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":410,"y":480,"wires":[["4bd531e0.843b4"]]},{"id":"4bd531e0.843b4","type":"wikipedia","z":"e094ee4e.c5b5","name":"","limit":"1","format":"json","profile":"fuzzy","lang":"en","x":670,"y":480,"wires":[["8f9acf40.6bec2"]]},{"id":"8f9acf40.6bec2","type":"function","z":"e094ee4e.c5b5","name":"","func":"msg.wikiSearch = {\"item\" : msg.payload[1][0] , \n \"result\" : msg.payload[3][0] };\n\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":870,"y":480,"wires":[["5fa5ef08.b7681"]]},{"id":"5fa5ef08.b7681","type":"link out","z":"e094ee4e.c5b5","name":"wikiSearch-out","links":["7c3b1a9b.e50324"],"x":1070,"y":480,"wires":[],"l":true},{"id":"51466b0f.a45cd4","type":"comment","z":"e094ee4e.c5b5","name":"Telegram","info":"","x":680,"y":220,"wires":[]},{"id":"97e3fa61.b3e8b8","type":"comment","z":"e094ee4e.c5b5","name":"Payload","info":"","x":290,"y":100,"wires":[]},{"id":"c4f3e192.4faaf","type":"comment","z":"e094ee4e.c5b5","name":"Payload","info":"","x":950,"y":220,"wires":[]},{"id":"71b78151.75f5c","type":"comment","z":"e094ee4e.c5b5","name":"Telegram","info":"","x":900,"y":100,"wires":[]},{"id":"82784987.c94898","type":"comment","z":"e094ee4e.c5b5","name":"Action","info":"","x":260,"y":420,"wires":[]},{"id":"11d269fc.a18e16","type":"comment","z":"e094ee4e.c5b5","name":"Payload","info":"","x":540,"y":420,"wires":[]},{"id":"dfa683d6.77148","type":"comment","z":"e094ee4e.c5b5","name":"Payload","info":"","x":760,"y":420,"wires":[]},{"id":"36c8c4c8.d11d2c","type":"comment","z":"e094ee4e.c5b5","name":"Searchresult","info":"","x":980,"y":420,"wires":[]},{"id":"2173dcf7.0a0704","type":"link in","z":"e094ee4e.c5b5","name":"NLP-in","links":["70cdf8db.8a98e8"],"x":140,"y":780,"wires":[["3f0a94ed.ab71ac"]],"l":true},{"id":"3f0a94ed.ab71ac","type":"change","z":"e094ee4e.c5b5","name":"Prepare for bot","rules":[{"t":"set","p":"payload","pt":"msg","to":"telegramBot","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":320,"y":780,"wires":[["73d61675.26c6e8"]]},{"id":"54a4578e.f00838","type":"link out","z":"e094ee4e.c5b5","name":"NLP-out","links":["438d38f7.895b28"],"x":1220,"y":780,"wires":[],"l":true},{"id":"241cddea.de9592","type":"comment","z":"e094ee4e.c5b5","name":"NLP - full answer","info":"","x":760,"y":680,"wires":[]},{"id":"1013920f.1715de","type":"comment","z":"e094ee4e.c5b5","name":"Telegram","info":"","x":200,"y":720,"wires":[]},{"id":"496ea412.ecd61c","type":"comment","z":"e094ee4e.c5b5","name":"Payload","info":"","x":430,"y":720,"wires":[]},{"id":"a21d3f51.930ba","type":"chatbot-nlpjs-intent","z":"e094ee4e.c5b5","intent":"Search","language":"en","utterances":["search ","find ","lookup","wiki","google","what is","what are","tell me about"],"outputs":1,"x":760,"y":1480,"wires":[["6dbd7924.11e908"]]},{"id":"6dbd7924.11e908","type":"chatbot-nlpjs-intent","z":"e094ee4e.c5b5","intent":"Salary","language":"en","utterances":["my salary is"],"outputs":1,"x":760,"y":1540,"wires":[["f1677768.f975e8"]]},{"id":"b3457e7.d5ecd8","type":"function","z":"e094ee4e.c5b5","name":"find string enitiy","func":"if (msg.NLP.intent ==\"Search\") {\n var entity = msg.NLP.utterance.replace('lookup','')\n .replace('search','')\n .replace('find','')\n .replace('wiki','')\n .replace('what is','')\n .replace('what are','')\n .replace('google','')\n .replace('tell me about','')\n .trim();\n msg.NLP.entities = [{\n \"start\": msg.NLP.utterance.length - entity.length,\n \"end\": msg.NLP.utterance.length,\n \"len\":entity.length,\n \"utteranceText\":entity,\n \"entity\":\"string\"\n }];\n msg.payload.variables={\"string\":entity }; \n}\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":920,"y":780,"wires":[["54a4578e.f00838"]]},{"id":"438d38f7.895b28","type":"link in","z":"e094ee4e.c5b5","name":"Smart-Agent","links":["54a4578e.f00838"],"x":150,"y":1066,"wires":[["4ce2809a.d71ba"]],"l":true},{"id":"45166a5.dcc7b94","type":"link out","z":"e094ee4e.c5b5","name":"to WikiSearch","links":["3d0a2516.f16e1a"],"x":800,"y":1060,"wires":[],"l":true},{"id":"7c3b1a9b.e50324","type":"link in","z":"e094ee4e.c5b5","name":"from WikiSearch","links":["5fa5ef08.b7681"],"x":1000,"y":1060,"wires":[["f611fc7e.07cef"]],"l":true},{"id":"2b58eb7b.c0bac4","type":"function","z":"e094ee4e.c5b5","name":"Action : Search","func":"msg.actionList = { \"action\" : \"search\", \"parameter\" :msg.NLP.entities[0].utteranceText};\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":580,"y":1060,"wires":[["45166a5.dcc7b94"]]},{"id":"30e46221.ec9e4e","type":"comment","z":"e094ee4e.c5b5","name":"ActionList","info":"","x":680,"y":1000,"wires":[]},{"id":"900f7d97.ed8c8","type":"comment","z":"e094ee4e.c5b5","name":"Telegram","info":"","x":260,"y":220,"wires":[]},{"id":"4194cdef.c5e784","type":"link out","z":"e094ee4e.c5b5","name":"to Telegram","links":["afed4943.9fedc8"],"x":1450,"y":1060,"wires":[],"l":true},{"id":"f611fc7e.07cef","type":"function","z":"e094ee4e.c5b5","name":"Send SearchResult","func":"msg.telegramBot.content = msg.wikiSearch.result;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":1230,"y":1060,"wires":[["4194cdef.c5e784"]]},{"id":"456bc802.210bb8","type":"comment","z":"e094ee4e.c5b5","name":"ActionList","info":"","x":1100,"y":1000,"wires":[]},{"id":"fd3ef424.6e5108","type":"comment","z":"e094ee4e.c5b5","name":"Telegram","info":"","x":1260,"y":1000,"wires":[]},{"id":"d23d70e0.66557","type":"function","z":"e094ee4e.c5b5","name":"Send NLP answer","func":"msg.telegramBot.content = msg.NLP.answer;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":590,"y":1140,"wires":[["6c0e78a.eede288"]]},{"id":"6c0e78a.eede288","type":"link out","z":"e094ee4e.c5b5","name":"to Telegram","links":["afed4943.9fedc8"],"x":810,"y":1140,"wires":[],"l":true},{"id":"ee668a2b.92a7e8","type":"inject","z":"e094ee4e.c5b5","name":"Insert content into","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"spiderman\":{\"fullname\":\"Peter Benjamin, Parker\",\"birthday\":\"10-08-2001\",\"address\":\"Queens, New York\",\"gender\":\"male\",\"partner\":\"Mary Jane, Watson\",\"possesive\":\"his\",\"phone\":\"unknown\",\"email\":\"peterbparkersayshi@gmail.com\"},\"ironman\":{\"fullname\":\"Tony Stark\",\"birthday\":\"unknown\",\"address\":\"Stark Tower, New York\",\"gender\":\"male\",\"partner\":\"Pepper Potts\",\"possesive\":\"his\",\"phone\":\"+1-212-970-4133\",\"email\":\"unknown\"},\"thor\":{\"fullname\":\"Odinson\",\"birthday\":\"unknown\",\"address\":\"Asgard\",\"gender\":\"male\",\"partner\":\"unknown\",\"possesive\":\"his\",\"phone\":\"unknown\",\"email\":\"unknown\"},\"superman\":{\"fullname\":\"Clark Joseph, Kent (or Kal-El on Krypton)\",\"birthday\":\"18-04-1938 \",\"address\":\"Metropolis, Illinois\",\"gender\":\"male\",\"partner\":\"Lois Lane\",\"possesive\":\"his\",\"phone\":\"unknown\",\"email\":\"unknown\"},\"pascal\":{\"fullname\":\"Paschalis Michael Jacobus, Geraeds\",\"birthday\":\"09-09-1969\",\"address\":\"Gelrestraat 69, 5951 JE, Belfeld (NL)\",\"gender\":\"male\",\"partner\":\"Hanneke Geraeds\",\"possesive\":\"his\",\"phone\":\"+31 6 xxxx xxxx\",\"email\":\"pascal.geraeds@xxxx.xx\"},\"hanneke\":{\"fullname\":\"Johanna Maria, Geraeds-de Vries\",\"birthday\":\"28-08-1972\",\"address\":\"Gelrestraat 69, 5951 JE, Belfeld (NL)\",\"gender\":\"female\",\"partner\":\"Pascal Geraeds\",\"possesive\":\"her\",\"phone\":\"+31 6 xxxx xxxx\",\"email\":\"hanneke.geraeds@xxxx.xx\"}}","payloadType":"json","x":230,"y":1980,"wires":[["768ef3ba.b7dddc"]]},{"id":"768ef3ba.b7dddc","type":"file","z":"e094ee4e.c5b5","name":"","filename":"/data/persons.json","appendNewline":true,"createDir":false,"overwriteFile":"true","encoding":"none","x":510,"y":1980,"wires":[[]]},{"id":"ebaadc6e.0f66f","type":"link out","z":"e094ee4e.c5b5","name":"to Log","links":["13a1b0d3.07dc5f"],"x":370,"y":180,"wires":[],"l":true},{"id":"4ce2809a.d71ba","type":"chatbot-rules","z":"e094ee4e.c5b5","name":"Rule Engine","rules":[{"type":"isIntentName","intent":"Search"},{"type":"isIntentName","intent":"person.eatingfruit"},{"type":"isIntent"},{"type":"catchAll"}],"outputs":4,"x":350,"y":1069,"wires":[["2b58eb7b.c0bac4"],["e3297be7.550458"],["d23d70e0.66557"],[]]},{"id":"169c85fa.fedc1a","type":"comment","z":"e094ee4e.c5b5","name":"Payload - short version","info":"","x":780,"y":740,"wires":[]},{"id":"2f31a704.df6c18","type":"comment","z":"e094ee4e.c5b5","name":"NLP - full answer","info":"","x":1060,"y":680,"wires":[]},{"id":"c0f97d6e.7eff5","type":"comment","z":"e094ee4e.c5b5","name":"Payload - short version","info":"","x":1080,"y":740,"wires":[]},{"id":"9bcbda64.d20de8","type":"comment","z":"e094ee4e.c5b5","name":"Payload - short version","info":"","x":260,"y":1000,"wires":[]},{"id":"73865303.2057fc","type":"comment","z":"e094ee4e.c5b5","name":"NLP - full answer","info":"","x":240,"y":940,"wires":[]},{"id":"e3297be7.550458","type":"function","z":"e094ee4e.c5b5","name":"Send NLP answer","func":"var NLPAnswer = msg.NLP.answer;\nvar NLPQuestion = msg.NLP.srcAnswer;\n\nnode.warn('answer : ' + NLPAnswer);\nnode.warn('scrAnswer : ' + NLPQuestion);\n\nif (NLPQuestion === undefined){\n msg.telegramBot.content = NLPAnswer;\n} else {\n msg.telegramBot.content = NLPQuestion;\n}\n\nmsg.payload.content = msg.telegramBot.content;\nmsg.payload.chatId = msg.telegramBot.chatId;\nmsg.payload.type = \"message\";\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":590,"y":1100,"wires":[["35de2f26.d7c5d"]]},{"id":"35de2f26.d7c5d","type":"chatbot-telegram-send","z":"e094ee4e.c5b5","bot":"98a67f86.829a5","botProduction":"","track":false,"passThrough":true,"errorOutput":false,"outputs":1,"x":810,"y":1100,"wires":[["bbd71a43.eb0b98"]]},{"id":"bbd71a43.eb0b98","type":"chatbot-nlpjs","z":"e094ee4e.c5b5","name":"home","debug":true,"scoreThreshold":50,"x":970,"y":1100,"wires":[["80e45d6b.db1a9"]]},{"id":"a7e2cac7.43bc28","type":"chatbot-context","z":"e094ee4e.c5b5","command":"intent","fieldValue":"","fieldType":"str","fieldName":"","x":700,"y":820,"wires":[[]]},{"id":"70190cd8.f69994","type":"comment","z":"e094ee4e.c5b5","name":"Creat person information json file being used in Corpus Person","info":"","x":370,"y":1940,"wires":[]},{"id":"36b3012a.ae747e","type":"comment","z":"e094ee4e.c5b5","name":"Payload","info":"","x":610,"y":100,"wires":[]},{"id":"80e45d6b.db1a9","type":"debug","z":"e094ee4e.c5b5","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1190,"y":1100,"wires":[]},{"id":"187c8c12.af7204","type":"comment","z":"e094ee4e.c5b5","name":"Corpora","info":"first piece of code added in top of file to provide function getJsonFile \n\nconst _ = require('underscore');\nconst { NlpManager } = require('node-nlp');\n\nconst lcd = require('../lib/helpers/lcd');\nconst RegisterType = require('../lib/node-installer');\nconst { extractValue } = require('../lib/helpers/utils');\n\n// --------- added by PGE to support loading corpus --------------\n const path = require('path');\n const fs = require('fs');\n const tmp = require('tmp');\n\n function getJsonFile(data){\n let tmpDir = tmp.dirSync({\n unsafeCleanup: true\n });\n let filepath = tmpDir.name + \"/\" + path.basename(tmpDir.name) + \".json\";\n fs.writeFileSync(filepath, JSON.stringify(data));\n return filepath;\n }\n// ------------ end of added -----------\n\nsecond piece of code in the middle just before //intents\n \n if (debug) { \n // eslint-disable-next-line no-console \n console.log(lcd.white('[NLP] ') + lcd.grey('Training model ') + lcd.green(name)); \n } \n \n // PGE ----------- adding corpus --------------------- \n // manager.addCorpus(__dirname + '/../corpus.json'); \n if (_.isObject(payload.corpora)) { \n Object.keys(payload.corpora).forEach(language => { \n Object.keys(payload.corpora[language] || {}).forEach(corpus => { \n manager.addCorpus(getJsonFile(payload.corpora[language][corpus])); \n if (debug) { \n console.log('[PGE] Loading corpus: ' + lcd.white(corpus) + ' [' + language.toUpperCase() + '] ');\n } \n }); \n }); \n } \n // PGE ------------- end modification --------------- \n \n // adding intents \n if (_.isObject(payload.intents)) { \n\n\n","x":460,"y":1260,"wires":[]},{"id":"d9fb77d6.5e5928","type":"comment","z":"e094ee4e.c5b5","name":"Intents","info":"","x":730,"y":1260,"wires":[]},{"id":"2033f758.779808","type":"comment","z":"e094ee4e.c5b5","name":"Entities","info":"","x":970,"y":1260,"wires":[]},{"id":"e4214436.c62b38","type":"comment","z":"e094ee4e.c5b5","name":"Train","info":"","x":1450,"y":1260,"wires":[]},{"id":"314a1e7e.ea15f2","type":"comment","z":"e094ee4e.c5b5","name":"Save","info":"","x":1670,"y":1260,"wires":[]},{"id":"1cdaed41.06c803","type":"comment","z":"e094ee4e.c5b5","name":"Slotting (hardcoded in chatbot-nlp-train.js","info":"for including slotting I just copied the javascript example from github \n{{fruit}} and {{person}} are entities added allready by the corpus\n\n// PGE : ---------- add slot filling example ----------- \n console.log('[PGE]------- include slotting script -----------'); \n \n manager.addDocument('en', 'I saw %person% eat a %fruit%', 'person.eatingfruit'); \n manager.nlp.slotManager.addSlot('person.eatingfruit', 'person', true, { en: 'Who did you see?' }); \n manager.nlp.slotManager.addSlot('person.eatingfruit', 'fruit', true, { en: 'What was {{ person }} eating?' });\n manager.addAnswer('en', 'person.eatingfruit', 'Wow! You saw {{ person }} eat {{ fruit }}!'); \n \n// PGE : ---------- end of modification -------------- \n \n await manager.train(); \n manager.save(); \n // store globally \n global.set('nlp_' + (!_.isEmpty(name) ? name : 'default'), manager); ","x":1220,"y":1260,"wires":[]},{"id":"98a67f86.829a5","type":"chatbot-telegram-node","botname":"redbot69bot","usernames":"","providerToken":"","polling":"1000","store":"","log":"","debug":true,"webHook":"","connectMode":"polling"}]

pmjgeraeds commented 3 years ago

Hi @guidone, i have slotting running in node-red. pointed in the right direction by: https://github.com/axa-group/nlp.js/blob/master/docs/v3/nlp-manager.md#context

The problem was, the context was not provided when running the nlp.process Therefore it could not remember the allready derived entities and complete the slotting routine and kept running in a loop.

For this I needed to make a few minor changes to the chatbot-nlp.js code:

before you run NLP.process code var MyContext = global.get('context');

run NLP.process const response = await manager.process(language, content, MyContext);

and after it finished global.set("context",MyContext);

Because at reset of node-red the global.context variable will not be available, you need to create it with an injection node image

image

Next step is to create an easy loader using a function node, like the corpus loader in chatbot-train.js

gr. Pascal

pmjgeraeds commented 3 years ago

Hi @guidone,

With a small modification to @nlpjs/nlp.js file, it will also accept slotting features in the corpus.json file:

// ---------------- modification by PGE : add slotting feature in corpus.json files ------------
  addData(data, locale, domain) {
    //console.log('[PGE] ----- @nlpjs/nlp.js addData ----------');  
    for (let i = 0; i < data.length; i += 1) {
      const current = data[i];
      const { intent, utterances, answers, slots} = current;  // slots added to corpus interpretation
      for (let j = 0; j < utterances.length; j += 1) {
        if (domain) {
          this.assignDomain(locale, intent, domain.name);
        }
        this.addDocument(locale, utterances[j], intent);
      }
      if (answers) {
        for (let j = 0; j < answers.length; j += 1) {
          const answer = answers[j];
          if (typeof answer === 'string') {
            this.addAnswer(locale, intent, answer);
          } else {
            this.addAnswer(locale, intent, answer.answer, answer.opts);
          }
        }
      }
      // this is the NEW feature, that allows slots to be added in the corpus.json
      if (slots) {
    //console.log('SLOTTING :' + JSON.stringify(slots, null, 4)); 
        for (let j = 0; j < slots.length; j += 1) {
      const slot = slots[j];
          console.log('slot'+j +': ' + JSON.stringify(slot, null, 4));
      const entity = slot.entity;
      const mandatory = slot.mandatory;
      const questions = slot.questions;
          //console.log('intent: ' + intent + ', entity: ' + entity + ', mandatory: ' + mandatory + ', questions: ' + questions );
      this.slotManager.addSlot(intent, entity, mandatory ,questions); 
    }
      } 
    }   
  } 
//----------------- End of Modification ------------------------------

An example corpus which will be inserted using a function node (as described in issue 479),


    {
        "name": "Corpus-slotting",
        "locale": "en-US",
        "data": [
            {
                "intent": "person.eatingfruit",
                "utterances": [
                    "I saw %person% eat a %fruit%"
                ],
                "answers": [
                    {
                        "answer": "Wow! You saw {{ person }} eat {{ fruit }}!"
                    }
                ],
                "slots" : [
                    {
                        "entity": "person",
                        "mandatory" : true,
                        "questions" : { en: 'Who did you see {{ fruit }}?' }
                    },
                    {
                        "entity": "fruit",
                        "mandatory" : true,
                        "questions" : { en: 'What was {{ person }} eating?' }
                    }
                ]
            }
        ]
    }

return msg;```

This finalises the whole exercise.
I can now add slotting features using standard node-red components.
And using the context, it will remember previous entities hence it can complete a full dialog with slotting.

gr. Pascal
pmjgeraeds commented 3 years ago

@guidone,

because in the new situation, context is not empty anymore when starting the NLP process, we need to modify the @nlpjs/nlp.js code a little more to allow the contextManager to load the _data subject in the corpus.

//    if (!context) {                                                                                                           
     let sourceContext;                                                                                                         
     sourceContext = await this.contextManager.getContext(sourceInput);                                                         
//    } else {                                                                                                                  
//    }                                                                                                                         
    context._data = sourceContext._data;
guidone commented 2 years ago

Hi @pmjgeraeds , is this still an issue or did you find a workaround?