├── BOTDATA ├── book_a_room.top ├── get_a_bill_copy.top ├── room_service.top ├── simplecontrol.top ├── welcome.top └── wifi.top ├── LICENSE.md ├── README.md ├── RasaModels ├── entity_extractor.dat ├── intent_classifier.dat ├── metadata.json └── training_data.json └── files1.txt /BOTDATA/book_a_room.top: -------------------------------------------------------------------------------- 1 | topic: ~book_a_room repeat ["book a room"] 2 | 3 | u: (number of rooms _~number * bed type _~number *) ^keep() 4 | $nbRooms = _0 5 | $nbPeople = _1 6 | Understood, so you want $nbRooms rooms with $nbPeople beds! \n 7 | ^gambit(~debut) 8 | 9 | u: (<<"number of rooms" _~number>>) ^keep() 10 | $value = %originalsentence 11 | $nbRooms = _0 12 | Good, i register your booking for $nbRooms room! \n 13 | ^gambit(~debut) 14 | 15 | u: (<<"bed type" _~number>>) ^keep() 16 | $nbPeople = _0 17 | Alright, so you want to book a room with a bed for $nbPeople people! \n 18 | ^gambit(~debut) 19 | 20 | u: (room option) ^keep() 21 | Ok, i register this room option. \n 22 | ^gambit(~debut) 23 | 24 | u: ROOMS (book a room) ^keep() 25 | So, you want to book, how many rooms do you want? \n 26 | a: (_~number) 27 | $nbRooms = _0 28 | Good, i register your booking for $nbRooms room! \n 29 | ^gambit(~debut) -------------------------------------------------------------------------------- /BOTDATA/get_a_bill_copy.top: -------------------------------------------------------------------------------- 1 | topic: ~get_a_bill_copy repeat ["get a bill copy"] 2 | 3 | u: (send) ^keep() 4 | Yes, we can send you your bill copy the way you desire. \n 5 | ^gambit(~debut) 6 | 7 | u: (get a bill copy) ^keep() 8 | Sure, we will give you a bill copy right now. \n 9 | ^gambit(~debut) -------------------------------------------------------------------------------- /BOTDATA/room_service.top: -------------------------------------------------------------------------------- 1 | topic: ~room_service repeat ["room service"] 2 | 3 | u: (food) ^keep() 4 | No problem, we will send you all the food you need, with pleasure! \n 5 | ^gambit(~debut) 6 | 7 | u: (cleaning) ^keep() 8 | A cleaning service is done every morning at 11 A.M., just wait for it. \n 9 | ^gambit(~debut) 10 | 11 | u: (room service) ^keep() 12 | Yes, we can do that for you, just wait a moment please. \n 13 | ^gambit(~debut) -------------------------------------------------------------------------------- /BOTDATA/simplecontrol.top: -------------------------------------------------------------------------------- 1 | outputmacro: rasabot() 2 | $cs_token = #DO_INTERJECTION_SPLITTING | #DO_SUBSTITUTE_SYSTEM | #DO_NUMBER_MERGE | #DO_DATE_MERGE | #DO_PROPERNAME_MERGE | #DO_SPELLCHECK | #DO_PARSE 3 | $cs_control_main = ~control 4 | $userprompt = ^"%user: >" 5 | $botprompt = ^"rasabot: " 6 | 7 | table: defaultbot (^name) 8 | ^createfact(^name defaultbot defaultbot) 9 | DATA: 10 | rasabot 11 | 12 | outputmacro: ^fromoobtomain() 13 | ^next(INPUT) 14 | ^reuse(MAIN) 15 | 16 | outputmacro: ^rasaCall(^sentence) 17 | $$url = ^"http://127.0.0.1:5000/parse" 18 | $params = ^'{"q":"^sentence"}' 19 | $dataJson = ^jsonopen(POST $$url $params "") 20 | $inputEntities = $dataJson.intent.name 21 | $confidence = $dataJson.intent.confidence 22 | if ($confidence <= 0.4 and $confidence > 0.0) { 23 | ^reuse(~debut.WHAT) 24 | ^fail(RULE) 25 | } 26 | $_i = 0 27 | ^loop() { 28 | $_entityName = $dataJson.entities[$_i].entity 29 | $_entityValue = $dataJson.entities[$_i].value 30 | if ($_entityValue == null ) { 31 | ^end(loop) 32 | } 33 | $inputEntities = ^join($inputEntities ^' ' $_entityName ^' ' $_entityValue) 34 | $_i += 1 35 | } 36 | ^input( $inputEntities ) 37 | ^fail(SENTENCE) 38 | 39 | topic: ~control system () 40 | u: MAIN () 41 | if (%response == 0) 42 | { 43 | @8 = ^keywordtopics() 44 | loop() 45 | { 46 | $$topic = first(@8subject) 47 | nofail(TOPIC ^respond($$topic)) 48 | if (%response != 0) 49 | { 50 | ^end(RULE) 51 | } 52 | } 53 | } 54 | if (!%topic) { 55 | ^gambit(~debut) 56 | ^rasaCall(%originalsentence) 57 | ^end(RULE) 58 | } 59 | $_nbResponseBefore = %response 60 | $_nbResponseTransverse = %response - $_nbResponseBefore 61 | if ($_nbResponseTransverse == 0) { 62 | nofail(TOPIC ^rejoinder()) 63 | if (%response == $_nbResponseTransverse) { nofail(TOPIC ^respond(%topic)) } 64 | if (%response == $_nbResponseTransverse) 65 | { 66 | ^rasaCall(%originalsentence) 67 | } 68 | } else { 69 | nofail(TOPIC ^gambit(%topic)) 70 | } 71 | -------------------------------------------------------------------------------- /BOTDATA/welcome.top: -------------------------------------------------------------------------------- 1 | concept: ~yes[yes yep yeah ye y "why not"] 2 | concept: ~no[no nope nono nah] 3 | 4 | topic: ~debut repeat [start] 5 | 6 | t: () 7 | Hi i'am Cecilia, how can i help you? \n 8 | 9 | t: () ^keep() 10 | Do you have another question? \n 11 | 12 | u: WHAT (~emomisunderstand) ^keep() 13 | Sorry, i did not understand, try with another sentence please. \n 14 | ^gambit(~) -------------------------------------------------------------------------------- /BOTDATA/wifi.top: -------------------------------------------------------------------------------- 1 | topic: ~wifi repeat ["wifi"] 2 | 3 | u: CREDITENTIALS (password) ^keep() 4 | To connect to the wifi, you have to select the INDIA-X60-HOTEL, and the password is : welcomeinindia. \n 5 | ^gambit(~debut) 6 | 7 | u: WIFI ([wifi wi-fi]) ^keep() 8 | We have the wifi for free in the hotel, do you want the credentials? \n 9 | a: (~yes) 10 | ^reuse(CREDITENTIALS) 11 | a: (~no) 12 | No problem! \n 13 | ^gambit(~debut) -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Addventa 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Integration of rasaNLU in ChatScript 2 | 3 | ## Prerequisites: rasa server 4 | 5 | First, you need to have a rasa server running with our model: **RasaModels**. 6 | 7 | Follow the rasa NLU tutorial to deploy your rasa server. 8 | 9 | * [rasa NLU](http://rasa-nlu.readthedocs.io/en/stable/) - *rasa NLU installation & configuration.* 10 | 11 | You can look in the **training_data.json** to observe the rasa workout format as well as the sentences that the bot will be able to understand. 12 | 13 | The server must run on this **IP: 127.0.0.1:5000**. 14 | 15 | Configuration is possible in BOTDATA/**simplecontrol.top**. 16 | 17 | ## How does it works ? 18 | 19 | Each time you will talk to the bot, the string will be sent to rasa which will process it and which, depending on his learning, will return the intent as well as the entities it will have found to the Bot in a json object. 20 | 21 | Once we have the json object, we take the essentials, which we insert into a single string that we use like a normal user input. 22 | 23 | So the patterns of the topics are based on the intent. 24 | Each intention has its own subject in our case, and response models depend on entities 25 | 26 | ### The format of the string 27 | 28 | **[intent]** **[entity]** *[entity.value]* **[entity]** *[entity.value]* ... 29 | 30 | 31 | * intent = The intent that Bot considered most relevant. 32 | * entity = An entity is a category of words. For example tree can be in the nature entity. 33 | * entity.value = One or more words belonging to the detected entity. 34 | 35 | #### Examples 36 | 37 | ``` 38 | User input: "I want to book 3 rooms with 2 beds." 39 | New input after parsing: "'book a room' 'number of rooms' '3 rooms' 'bed type' '2 beds'" 40 | ChatScript result: "Understood, so you want 3 rooms with 2 beds!" 41 | ``` 42 | 43 | ``` 44 | User input: "Can i have wifi creditentials please?" 45 | New input after parsing: "'wifi' 'password' 'creditentials'" 46 | ChatScript result: "To connect to the wifi, you have to select the INDIA-X60-HOTEL, and the password is : welcomeinindia." 47 | ``` 48 | 49 | 50 | ## Play with it ! 51 | 52 | The training is really light for this example so the bot will not understand everything, but if you train it with more training data, you will be able to make it really good! 53 | 54 | The rasacall function in simplecontrol.top is where rasa is called (obvious), and you can set the minimum confidence that you think is acceptable. 55 | -------------------------------------------------------------------------------- /RasaModels/entity_extractor.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addventa/ChatScriptRasa/b4b5b93b3189e782e2d232086f110ee30b0bf7eb/RasaModels/entity_extractor.dat -------------------------------------------------------------------------------- /RasaModels/intent_classifier.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addventa/ChatScriptRasa/b4b5b93b3189e782e2d232086f110ee30b0bf7eb/RasaModels/intent_classifier.dat -------------------------------------------------------------------------------- /RasaModels/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "entity_synonyms": null, 3 | "pipeline": [ 4 | "nlp_mitie", 5 | "tokenizer_mitie", 6 | "ner_mitie", 7 | "ner_synonyms", 8 | "intent_classifier_mitie" 9 | ], 10 | "intent_classifier": "intent_classifier.dat", 11 | "entity_extractor": "entity_extractor.dat", 12 | "language": "en", 13 | "mitie_file": "./data/total_word_feature_extractor.dat", 14 | "trained_at": "20170421-114237", 15 | "training_data": "training_data.json", 16 | "mitie_feature_extractor_fingerprint": 10023965992282753551, 17 | "rasa_nlu_version": "0.8.0a8" 18 | } -------------------------------------------------------------------------------- /RasaModels/training_data.json: -------------------------------------------------------------------------------- 1 | { 2 | "rasa_nlu_data": { 3 | "common_examples": [ 4 | { 5 | "text": "I want to book a room", 6 | "intent": "book_a_room", 7 | "entities": [] 8 | }, 9 | { 10 | "text": "I want to have a room", 11 | "intent": "book_a_room", 12 | "entities": [] 13 | }, 14 | { 15 | "text": "Is a room available from xxx to yyy?", 16 | "intent": "book_a_room", 17 | "entities": [ 18 | { 19 | "start": 25, 20 | "end": 28, 21 | "value": "xxx", 22 | "entity": "time" 23 | }, 24 | { 25 | "start": 32, 26 | "end": 35, 27 | "value": "yyy", 28 | "entity": "time" 29 | } 30 | ] 31 | }, 32 | { 33 | "text": "i need a room for 2 persons", 34 | "intent": "book_a_room", 35 | "entities": [ 36 | { 37 | "start": 18, 38 | "end": 27, 39 | "value": "2 persons", 40 | "entity": "bed_type" 41 | } 42 | ] 43 | }, 44 | { 45 | "text": "i need a room with a private bathroom", 46 | "intent": "book_a_room", 47 | "entities": [ 48 | { 49 | "start": 21, 50 | "end": 37, 51 | "value": "private bathroom", 52 | "entity": "room_option" 53 | } 54 | ] 55 | }, 56 | { 57 | "text": "i want a cheap room", 58 | "intent": "book_a_room", 59 | "entities": [ 60 | { 61 | "start": 9, 62 | "end": 14, 63 | "value": "cheap", 64 | "entity": "price" 65 | } 66 | ] 67 | }, 68 | { 69 | "text": "I want to cancel a booking", 70 | "intent": "book_a_room", 71 | "entities": [] 72 | }, 73 | { 74 | "text": "I want a 2 room with 2 beds", 75 | "intent": "book_a_room", 76 | "entities": [ 77 | { 78 | "start": 21, 79 | "end": 27, 80 | "value": "2 beds", 81 | "entity": "bed_type" 82 | }, 83 | { 84 | "start": 9, 85 | "end": 15, 86 | "value": "2 room", 87 | "entity": "number_of_rooms" 88 | } 89 | ] 90 | }, 91 | { 92 | "text": "I want a smoking room", 93 | "intent": "book_a_room", 94 | "entities": [ 95 | { 96 | "start": 9, 97 | "end": 21, 98 | "value": "smoking room", 99 | "entity": "room_option" 100 | } 101 | ] 102 | }, 103 | { 104 | "text": "Do you have rooms available?", 105 | "intent": "book_a_room", 106 | "entities": [] 107 | }, 108 | { 109 | "text": "How can I connect to WIFI ?", 110 | "intent": "wifi", 111 | "entities": [ 112 | { 113 | "start": 10, 114 | "end": 17, 115 | "value": "connect", 116 | "entity": "wifi_connection" 117 | } 118 | ] 119 | }, 120 | { 121 | "text": "What are the wifi credentials", 122 | "intent": "wifi", 123 | "entities": [ 124 | { 125 | "start": 18, 126 | "end": 29, 127 | "value": "credentials", 128 | "entity": "password" 129 | } 130 | ] 131 | }, 132 | { 133 | "text": "I need the passswords for the Wifi", 134 | "intent": "wifi", 135 | "entities": [ 136 | { 137 | "start": 11, 138 | "end": 21, 139 | "value": "passswords", 140 | "entity": "password" 141 | } 142 | ] 143 | }, 144 | { 145 | "text": "Do you have wifi in the rooms?", 146 | "intent": "wifi", 147 | "entities": [] 148 | }, 149 | { 150 | "text": "how to activate the wifi", 151 | "intent": "wifi", 152 | "entities": [ 153 | { 154 | "start": 7, 155 | "end": 15, 156 | "value": "activate", 157 | "entity": "wifi_connection" 158 | } 159 | ] 160 | }, 161 | { 162 | "text": "i want the wifi", 163 | "intent": "wifi", 164 | "entities": [] 165 | }, 166 | { 167 | "text": "wifi doesn't work", 168 | "intent": "wifi", 169 | "entities": [] 170 | }, 171 | { 172 | "text": "what's the password for the internet", 173 | "intent": "wifi", 174 | "entities": [ 175 | { 176 | "start": 11, 177 | "end": 19, 178 | "value": "password", 179 | "entity": "password" 180 | } 181 | ] 182 | }, 183 | { 184 | "text": "i need internet", 185 | "intent": "wifi", 186 | "entities": [] 187 | }, 188 | { 189 | "text": "The wifi is slow can you help me?", 190 | "intent": "wifi", 191 | "entities": [] 192 | }, 193 | { 194 | "text": "I cannot connect to the wifi", 195 | "intent": "wifi", 196 | "entities": [] 197 | }, 198 | { 199 | "text": "Do I need to pay for the wifi", 200 | "intent": "wifi", 201 | "entities": [ 202 | { 203 | "start": 13, 204 | "end": 16, 205 | "value": "pay", 206 | "entity": "price" 207 | } 208 | ] 209 | }, 210 | { 211 | "text": "Is there free wifi", 212 | "intent": "wifi", 213 | "entities": [ 214 | { 215 | "start": 9, 216 | "end": 13, 217 | "value": "free", 218 | "entity": "price" 219 | } 220 | ] 221 | }, 222 | { 223 | "text": "How do I get to the wifi", 224 | "intent": "wifi", 225 | "entities": [] 226 | }, 227 | { 228 | "text": "Can you send someone in my room ?", 229 | "intent": "room_service", 230 | "entities": [] 231 | }, 232 | { 233 | "text": "How can I reach room service ?", 234 | "intent": "room_service", 235 | "entities": [] 236 | }, 237 | { 238 | "text": "i want to eat something", 239 | "intent": "room_service", 240 | "entities": [ 241 | { 242 | "start": 10, 243 | "end": 13, 244 | "value": "eat", 245 | "entity": "food" 246 | } 247 | ] 248 | }, 249 | { 250 | "text": "i am hungry", 251 | "intent": "room_service", 252 | "entities": [ 253 | { 254 | "start": 5, 255 | "end": 11, 256 | "value": "hungry", 257 | "entity": "food" 258 | } 259 | ] 260 | }, 261 | { 262 | "text": "room service please", 263 | "intent": "room_service", 264 | "entities": [] 265 | }, 266 | { 267 | "text": "i want some champagne", 268 | "intent": "room_service", 269 | "entities": [ 270 | { 271 | "start": 12, 272 | "end": 21, 273 | "value": "champagne", 274 | "entity": "food" 275 | } 276 | ] 277 | }, 278 | { 279 | "text": "wine please", 280 | "intent": "room_service", 281 | "entities": [ 282 | { 283 | "start": 0, 284 | "end": 4, 285 | "value": "wine", 286 | "entity": "food" 287 | } 288 | ] 289 | }, 290 | { 291 | "text": "sandwich please", 292 | "intent": "room_service", 293 | "entities": [ 294 | { 295 | "start": 0, 296 | "end": 8, 297 | "value": "sandwich", 298 | "entity": "food" 299 | } 300 | ] 301 | }, 302 | { 303 | "text": "breakfast", 304 | "intent": "room_service", 305 | "entities": [ 306 | { 307 | "start": 0, 308 | "end": 9, 309 | "value": "breakfast", 310 | "entity": "food" 311 | } 312 | ] 313 | }, 314 | { 315 | "text": "clean the room", 316 | "intent": "room_service", 317 | "entities": [ 318 | { 319 | "start": 0, 320 | "end": 5, 321 | "value": "clean", 322 | "entity": "cleaning" 323 | } 324 | ] 325 | }, 326 | { 327 | "text": "I would like to complain about the room service / cleaning", 328 | "intent": "room_service", 329 | "entities": [ 330 | { 331 | "start": 16, 332 | "end": 24, 333 | "value": "complain", 334 | "entity": "complain" 335 | } 336 | ] 337 | }, 338 | { 339 | "text": "Can someone pickup my laundry", 340 | "intent": "room_service", 341 | "entities": [ 342 | { 343 | "start": 22, 344 | "end": 29, 345 | "value": "laundry", 346 | "entity": "cleaning" 347 | } 348 | ] 349 | }, 350 | { 351 | "text": "What time does roomservice starts/ends", 352 | "intent": "room_service", 353 | "entities": [ 354 | { 355 | "start": 5, 356 | "end": 9, 357 | "value": "time", 358 | "entity": "time" 359 | } 360 | ] 361 | }, 362 | { 363 | "text": "What is the menu for room services", 364 | "intent": "room_service", 365 | "entities": [ 366 | { 367 | "start": 12, 368 | "end": 16, 369 | "value": "menu", 370 | "entity": "food" 371 | } 372 | ] 373 | }, 374 | { 375 | "text": "Can I have breakfast in bed?", 376 | "intent": "room_service", 377 | "entities": [ 378 | { 379 | "start": 11, 380 | "end": 20, 381 | "value": "breakfast", 382 | "entity": "food" 383 | } 384 | ] 385 | }, 386 | { 387 | "text": "Can you give me a bill copy ?", 388 | "intent": "get_a_bill_copy", 389 | "entities": [] 390 | }, 391 | { 392 | "text": "I want a bill copy, please", 393 | "intent": "get_a_bill_copy", 394 | "entities": [] 395 | }, 396 | { 397 | "text": "Could you print another copy of the bill ?", 398 | "intent": "get_a_bill_copy", 399 | "entities": [] 400 | }, 401 | { 402 | "text": "Could you fax a copy of the bill ?", 403 | "intent": "get_a_bill_copy", 404 | "entities": [ 405 | { 406 | "start": 10, 407 | "end": 13, 408 | "value": "fax", 409 | "entity": "send" 410 | } 411 | ] 412 | }, 413 | { 414 | "text": "Can you mail me a copy of the bill ?", 415 | "intent": "get_a_bill_copy", 416 | "entities": [ 417 | { 418 | "start": 8, 419 | "end": 12, 420 | "value": "mail", 421 | "entity": "send" 422 | } 423 | ] 424 | }, 425 | { 426 | "text": "I would like to get my bill via email", 427 | "intent": "get_a_bill_copy", 428 | "entities": [ 429 | { 430 | "start": 32, 431 | "end": 38, 432 | "value": "email", 433 | "entity": "send" 434 | } 435 | ] 436 | }, 437 | { 438 | "text": "I have lost my bill please resend me a copy", 439 | "intent": "get_a_bill_copy", 440 | "entities": [ 441 | { 442 | "start": 27, 443 | "end": 33, 444 | "value": "resend", 445 | "entity": "send" 446 | } 447 | ] 448 | }, 449 | { 450 | "text": "I have not received my hotel bill can I still receive this?", 451 | "intent": "get_a_bill_copy", 452 | "entities": [] 453 | }, 454 | { 455 | "text": "The Bill is incorrect can I get a new one", 456 | "intent": "get_a_bill_copy", 457 | "entities": [] 458 | }, 459 | { 460 | "text": "Is the bill VAT included", 461 | "intent": "get_a_bill_copy", 462 | "entities": [ 463 | { 464 | "start": 12, 465 | "end": 15, 466 | "value": "VAT", 467 | "entity": "price" 468 | } 469 | ] 470 | }, 471 | { 472 | "text": "When will the Bill be ready", 473 | "intent": "get_a_bill_copy", 474 | "entities": [ 475 | { 476 | "start": 0, 477 | "end": 4, 478 | "value": "When", 479 | "entity": "time" 480 | } 481 | ] 482 | } 483 | ], 484 | "entity_examples": [], 485 | "intent_examples": [] 486 | } 487 | } -------------------------------------------------------------------------------- /files1.txt: -------------------------------------------------------------------------------- 1 | ../../BOTS/ChatScriptRasa/BOTDATA/ --------------------------------------------------------------------------------