I am new to rasa stake and i want my chatbot to retrieve responses from the dataset below (i copy pasted the domain stories etc). now i am stuck on the actions.py part as i dont know how to implement the actions

rasa-core
(tatenda) #1

nlu_md = “”"

intent:order_pizza

  • pizza
  • i want pizza
  • may i have a pizza
  • i need pizza
  • lemme have pizza
  • ndikuda pizza
  • ngifun ipizza
  • ndoda pizzza
  • will have a pizza
  • me want pizza
  • order pizza
  • i want to order pizza
  • make a pizza order
  • some pizza
  • order
  • am hungry
  • hungry
  • i want lunch
  • i want to eat
  • i wnt pizza
  • may i hv pizza
  • i wnt order pizza
  • i nid sm pizza
  • i wnt to eat
  • i want piza

intent:what_is_pizza_cost

  • hw mch is pizza
  • hw much is a large pizza
  • how much duz small pizza cost
  • how much dz medium pizza cost
  • howmuch does family size pizza cost
  • cost of large pizza
  • cost of small pizza
  • cost of medium pizza
  • cost of extra large pizza

intent:what_is_available_pizza

  • whch type of pizza do you have
  • which kind of pizza do u have
  • wht pizza do you have
  • which pizza do u hve
  • what r the available pizza flavours
  • what are the available pizza flavours
  • wht r e avail pizza flavours
  • large pizza hw mch
  • large pizza how much
  • pizza cost

intent:greet

  • Hi
  • Hey
  • Hi
  • Hey
  • Hello
  • Good morning
  • watzup
  • wasup
  • wassup
  • wadup
  • hi there
  • hy
  • eta
  • watzap
  • heey

intent:thanks

  • Thanks
  • Thank you
  • Thank you so much
  • Thanks bot
  • Thanks for that
  • cheers
  • cheers
  • ok thanks!
  • perfect thank you
  • thanks a bunch for everything
  • thanks for the help
  • thanks a lot
  • amazing, thanks
  • cool, thanks
  • cool thank you

intent:affirm

  • yes
  • yes sure
  • absolutely
  • for sure
  • cool
  • definitely
  • yup
  • uhuh
  • yep
  • yeah

intent:deny

  • no
  • i dont want
  • nah
  • nope
  • please no
  • no thanks
  • nahuh
  • dont worry about that
  • dnt worry abt that
  • noooo

intent:order_pizza

intent:bye

  • bye
  • see ya
  • toodles
  • farewell
  • goodbye
  • next time
  • later
  • see you
  • c u
  • bye bye

“”"

%store nlu_md > nlu.md

stories_md = “”"

story_greet

  • greet
  • utter_greet

story_goodbye

  • goodbye
  • utter_goodbye

story_thanks

  • thanks
  • utter_thanks

story ask availale pizza

  • greet
  • utter_greet
  • what_is_available_pizza
  • utter_show_available_pizza

story ask pizza cost

  • greet
  • utter_greet
  • what_is_piza_cost
  • utter_show_pizza_cost

story order 1

  • greet
  • utter_greet
  • order_pizza -utter_ask_size
  • order_pizza{“size”:“small”}
  • utter_ask_type
  • order_pizza{“type”:“Hawaiian”}
  • utter_ask_toppings
  • affirm
  • utter_name_toppings
  • order_pizza{“toppings”:“mushrooms”}
  • utter_confirm_order1
  • thank OR bye
  • utter_thank

story order 2

  • order_pizza
  • utter_ask_size
  • order_pizza{“size”:“medium”}
  • utter_ask_type
  • order_pizza{“type”:“Buffalo chicken”}
  • utter_ask_toppings
  • deny
  • utter_confirm_order2
  • bye OR thanks
  • utter_bye

story order 3

  • greet
  • utter_greet
  • order_pizza{“type”:“BBQ”}
  • utter_ask_size
  • order_pizza{“size”:“large”}
  • utter_ask_toppings
  • affirm
  • utter_name_toppings
  • order_pizza{“toppings”:“sausage please”}
  • utter_confirm_order1
  • thank OR bye
  • utter_thank

story order 4

  • greet
  • utter_greet
  • order_pizza
  • utter_ask_size
  • order_pizza{“size”:“extra large”}
  • utter_ask_type
  • order_pizza{“type”:“bacon cheeseburger”}
  • utter_ask_toppings
  • affirm
  • utter_name_toppings
  • order_pizza{“toppings”:“green peppers”}
  • utter_confirm_order1
  • thank OR bye
  • utter_thank

story order 5

  • greet
  • utter_greet
  • order_pizza
  • utter_confirm_order1
  • thank OR bye
  • utter_thank

story_joke_01

  • joke
  • action_joke

“”"

%store stories_md > stories.md

domain_yml = “”" intents: # add your intents - greet - thank - bye - deny - affirm - what_is_available_pizza - what_is_pizza_cost - order_pizza

  entities:
   - size
   - type
   - toppings
  
  slots:
   size:
    type: text
   type:
    type: text
   toppings:
    type: text
   what_is_pizza_cost:
    type: text
   what_is_available_pizza:
    type: text
    
  
  templates:
   # templates the bot should respond with
   utter_greet:
    - "Hey there, welcome to Tatenda's pizzabpot, how can I help you"
   utter_thank:
    - "You're welcome!"
   utter_bye:
    - "Goodbye"
   utter_ask_size:
    - "what pizza size do you want?"
    - "which size would you like?"
   utter_ask_type:
    - "We have BBQ, Hawaiian, Bacon Cheeseburger, and Buffalo chicken pizzas, 		which one do you want"
   utter_ask_toppings:
    - "Do you want any toppings?"
   utter_name_toppings:
    - "We have mushrooms, onions, bacon, green peppers and sausage toppings, 		which 	would you like?
   utter_confirm_order1:
    - "You just ordered a {size} {type} pizza with {toppings}. We will 			contact you when we are the closest place to the given address."
    utter_confirm_order2:
    - "You just ordered a {size} {type} pizza. We will 			contact you when we are at the closest place to the given address."
   utter_fallback:
    - "sorry, I did not get you..."
   utter_show_available_pizza:
    - 'We have BBQ, Hawaiian, Bacon CheeseBurger and Buffalo Chicken pizzas 		in all sizes, small, medium, large and extra large'
   utter_show_pizza_cost:
    - 'All small pizzas cost $13. Medium BBQ, Bacon and Buffalo pizzas cost 		$20. Their large sizes cost $30 and extra large is $37. Medium Hawaiian is 		$23, while the large one is $35. The large Hawaiian is $40'
  
  actions:
   # all the utter actions from the templates, plus any custom actions
   - utter_greet
   - utter_thank
   - utter_bye
   - utter_show_pizza_cost
   - utter_show_available_pizza
   - utter_confirm_order1
   - utter_confirm_order2
   - utter_name_toppings
   - utter_ask_toppings
   - utter_ask_size
   -utter_ask_type
   -utter_fallback
   - action_get_new_slots
   - action_listen

“”"

%store domain_yml > domain.yml

(Srikar) #2

Did you already create an actions.py file?

If you did, then you need to run the action server. In your endpoints.yml file, include the action endpoint URL. For example, something like this.

action_endpoint:
   url: http://localhost:5055/webhook

While running the core, make sure to include the endpoint file by uisng --endpoints endpoints.yml.

Also run the action server python3 -m rasa_core_sdk.endpoint --actions temp

(tatenda) #3

Thanks srikar but i havent created the action.py. actually i was following a tutorial for a chatbot that checks the mood of the user and sends an image by using API calls, which worked well. then i had customise it and ended up scrapping off the customAction code since i wont be using any APIs. I have seen something like UtterAction class but im not getting how it really works. So what i am really asking is how do i write code for the action.py.

(Srikar) #4

So the actions.py is called whenever a custom action is triggered in the story. The file looks something like this:

from rasa_core_sdk import Action
from rasa_core_sdk.events import *
...
...

You import the sdks’s and then create classes for each custom action. If you want an action to be triggered to place the pizza order using an API then you have to create something like below which will have the name and run methods.

class ActionOrderPizza(Action):
    def name(self):
        return 'action_order_pizza'
    def run(self, dispatcher, tracker, domain):
        YOUR CODE

You can also take a look at this: custom actions

(tatenda) #5

Okay let me work on it, will get back to you

(tatenda) #6

hey i have decided to use formAction and this is my actions.py code

from typing import Dict, Text, Any, List, Union

from rasa_core_sdk import ActionExecutionRejection from rasa_core_sdk import Tracker from rasa_core_sdk.events import SlotSet from rasa_core_sdk.executor import CollectingDispatcher from rasa_core_sdk.forms import FormAction, REQUESTED_SLOT

class PizzaForm(FormAction): “”“Example of a custom form action”""

def name(self):
    # type: () -> Text
    """Unique identifier of the form"""

    return "pizza_form"

@staticmethod
def required_slots(tracker: Tracker) -> List[Text]:
    """A list of required slots that the form has to fill"""

    return ["size", "pizzatype", "ask_toppings", "toppings", "pizzatype",
            "what_is_pizza_cost", "what_is_available_pizza"]

def slot_mappings(self):
    # type: () -> Dict[Text: Union[Dict, List[Dict]]]
    """A dictionary to map required slots to
        - an extracted entity
        - intent: value pairs
        - a whole message
        or a list of them, where a first match will be picked"""

    return {"size": [self.from_entity(entity="size",
                                      not_intent="chitchat"),
            "pizzatype": [self.from_entity(entity="pizzatype",
                                           not_intent="chitchat")],
            "ask_toppings": [self.from_entity(entity="toppings"),
                                self.from_intent(intent='affirm',
                                                 value=True),
                                self.from_intent(intent='deny',
                                                 value=False)],
            "toppings": [self.from_intent(entity="toppings",
                                          not_intent="chitchat"),
            "num_pizza": [self.from_entity(entity="num_pizza",
                                           intent=["inform",
                                                    "order_pizza"]),
                          self.from_entity(entity="number")],
            "feedback": [self.from_entity(entity="feedback"),
                         self.from_text()]}
                         
@staticmethod
def size_db():
    # type: () -> List[Text]
    """Database of supported cuisines"""
    return ["large",
            "extra large",
            "medium",
            "small"]

def toppings_db():
    # type: () -> List[Text]
    """Database of supported cuisines"""
    return ["onions",
            "mushrooms",
            "extra cheese",
            "sausage",
            "green peppers"]

def pizzatype_db():
    # type: () -> List[Text]
    """Database of supported cuisines"""
    return ["BBQ",
            "Buffalo chicken",
            "Hawaiian",
            "cheese"]




@staticmethod
def is_int(string: Text) -> bool:
    """Check if a string is an integer"""
    try:
        int(string)
        return True
    except ValueError:
        return False

def validate(self,
             dispatcher: CollectingDispatcher,
             tracker: Tracker,
             domain: Dict[Text, Any]) -> List[Dict]:
    """Validate extracted requested slot
        else reject the execution of the form action
    """
    # extract other slots that were not requested
    # but set by corresponding entity
    slot_values = self.extract_other_slots(dispatcher, tracker, domain)

    # extract requested slot
    slot_to_fill = tracker.get_slot(REQUESTED_SLOT)
    if slot_to_fill:
        slot_values.update(self.extract_requested_slot(dispatcher,
                                                       tracker, domain))
        if not slot_values:
            # reject form action execution
            # if some slot was requested but nothing was extracted
            # it will allow other policies to predict another action
            raise ActionExecutionRejection(self.name(),
                                           "Failed to validate slot {0} "
                                           "with action {1}"
                                           "".format(slot_to_fill,
                                                     self.name()))

    # we'll check when validation failed in order
    # to add appropriate utterances
    for slot, value in slot_values.items():
        if slot == 'size':
            if value.lower() not in self.cuisine_db():
                dispatcher.utter_template('utter_wrong_size', tracker)
                # validation failed, set slot to None
                slot_values[slot] = None

        elif slot == 'num_pizza':
            if not self.is_int(value) or int(value) <= 0:
                dispatcher.utter_template('utter_wrong_num_pizza',
                                          tracker)
                # validation failed, set slot to None
                slot_values[slot] = None

        elif slot == 'ask_toppings':
            if isinstance(value, str):
                if 'yes' in value:
                    # convert "out..." to True
                    slot_values[slot] = True
                elif 'no' in value:
                    # convert "in..." to False
                    slot_values[slot] = False
                else:
                    dispatcher.utter_template('utter_wrong_toppings',
                                              tracker)
                    # validation failed, set slot to None
                    slot_values[slot] = None

    # validation succeed, set the slots values to the extracted values
    return [SlotSet(slot, value) for slot, value in slot_values.items()]

def submit(self,
           dispatcher: CollectingDispatcher,
           tracker: Tracker,
           domain: Dict[Text, Any]) -> List[Dict]:
    """Define what the form has to do
        after all required slots are filled"""

    # utter submit template
    dispatcher.utter_template('utter_affirm', tracker)
    return []

however, i get the following error File “”, line 36 “pizzatype”: [self.from_entity(entity=“pizzatype”, ^ SyntaxError: invalid syntax

i am using rasa_core 0.13.3

(Srikar) #7

Hello,

You forgot to close the bracket here:

That is what is causing the error.

(tatenda) #8

they thanks i managed to debug and created endpoints.yml file. Now i’ve trying all day to train the dialogue model with

from rasa_core.policies.fallback import FallbackPolicy from rasa_core.policies.keras_policy import KerasPolicy from rasa_core.policies.memoization import MemoizationPolicy from rasa_core.agent import Agent

fallback = FallbackPolicy(fallback_action_name=“action_default_fallback”, core_threshold=0.3, nlu_threshold=0.3)

agent = Agent(“domain.yml”, policies=[KerasPolicy(), MemoizationPolicy(), fallback]) data = agent.load_data(“stories.md”) agent.train(data) agent.persist(‘models/dialogue’)

and i get the following error

ParserError Traceback (most recent call last) in 8 nlu_threshold=0.3) 9 —> 10 agent = Agent(“domain.yml”, policies=[KerasPolicy(), MemoizationPolicy(), fallback]) … ParserError: while parsing a block mapping in “<unicode string>”, line 2, column 1 did not find expected key in “<unicode string>”, line 16, column 7

What am i missing?

(Srikar) #9

Can you show the config file?

(tatenda) #10

You mean this one ?

policies_yaml = “”" policies:

  • name: “KerasPolicy” featurizer:
    • name: MaxHistoryTrackerFeaturizer max_history: 5 state_featurizer:
      • name: BinarySingleStateFeaturizer
  • name: “MemoizationPolicy” max_history: 5
  • name: “FallbackPolicy” nlu_threshold: 0.3 core_threshold: 0.3 fallback_action_name: “my_fallback_action” “”" %store policies_yaml > policies.yaml

actually i think i am confused as to how and where i’m supposed to place the above configurations and what i should name the file. i read the rasa docs but i dont get how im exactly supposed to put it together

(Srikar) #11

Hello,

Yes, I actually meant the policy.yml file. The file seems right to me. While training the core include these files. Something like this (change the names accordingly):

python3 -m rasa_core.train -d domain.yml -s stories.md -o models/dialogue -c policies.yml
python3 -m rasa_nlu.train -c config.yml --data nlu.md -o models --fixed_model_name nlu --project current --verbose

Change it to your fallback action name and try.

(tatenda) #12

from cmd it shows the same error, however when i change agent = Agent(‘stories.yml’, policies=[MemoizationPolicy(), KerasPolicy(), fallback]) to agent = Agent(‘config.yml’, policies=[MemoizationPolicy(), KerasPolicy(), fallback]) and it does this

Processed Story Blocks: 0%| | 0/10 [00:00<?, ?it/s] Processed Story Blocks: 0%| | 0/10 [00:00<?, ?it/s, # trackers=1] Processed Story Blocks: 0%| | 0/10 [00:00<?, ?it/s, # trackers=1] Processed Story Blocks: 0%| | 0/10 [00:00<?, ?it/s, # trackers=1] Processed Story Blocks: 0%| | 0/10 [00:00<?, ?it/s, # trackers=1] Processed Story Blocks: 0%| | 0/10 [00:00<?, ?it/s, # trackers=1] Processed Story Blocks: 0%| | 0/10 [00:00<?, ?it/s, # trackers=1] Processed Story Blocks: 0%| | 0/10 [00:00<?, ?it/s, # trackers=1] Processed Story Blocks: 0%| | 0/10 [00:00<?, ?it/s, # trackers=1] Processed Story Blocks: 0%| | 0/10 [00:00<?, ?it/s, # trackers=1] Processed Story Blocks: 0%| | 0/10 [00:00<?, ?it/s, # trackers=1] Processed Story Blocks: 100%|██████████| 10/10 [00:00<00:00, 143.17it/s, # trackers=1] Processed Story Blocks: 0%| | 0/10 [00:00<?, ?it/s] Processed Story Blocks: 0%| | 0/10 [00:00<?, ?it/s, # trackers=7] Processed Story Blocks: 0%| | 0/10 [00:00<?, ?it/s, # trackers=7] Processed Story Blocks: 0%| | 0/10 [00:00<?, ?it/s, # trackers=7] Processed Story Blocks: 0%| | 0/10 [00:00<?, ?it/s, # trackers=7] Processed Story Blocks: 0%| | 0/10 [00:00<?, ?it/s, # trackers=7] Processed Story Blocks: 0%| | 0/10 [00:00<?, ?it/s, # trackers=7] Processed Story Blocks: 0%| | 0/10 [00:00<?, ?it/s, # trackers=7] Processed Story Blocks: 0%| | 0/10 [00:00<?, ?it/s, # trackers=7] Processed Story Blocks: 80%|████████ | 8/10 [00:00<00:00, 76.81it/s, # trackers=7] Processed Story Blocks: 80%|████████ | 8/10 [00:00<00:00, 76.81it/s, # trackers=7] Processed Story Blocks: 80%|████████ | 8/10 [00:00<00:00, 76.81it/s, # trackers=7] Processed Story Blocks: 100%|██████████| 10/10 [00:00<00:00, 67.61it/s, # trackers=7] Processed Story Blocks: 0%| | 0/10 [00:00<?, ?it/s] Processed Story Blocks: 0%| | 0/10 [00:00<?, ?it/s, # trackers=6] Processed Story Blocks: 0%| | 0/10 [00:00<?, ?it/s, # trackers=6] Processed Story Blocks: 0%| | 0/10 [00:00<?, ?it/s, # trackers=6] Processed Story Blocks: 0%| | 0/10 [00:00<?, ?it/s, # trackers=6] Processed Story Blocks: 0%| | 0/10 [00:00<?, ?it/s, # trackers=6] Processed Story Blocks: 0%| | 0/10 [00:00<?, ?it/s, # trackers=6] Processed Story Blocks: 0%| | 0/10 [00:00<?, ?it/s, # trackers=6] Processed Story Blocks: 70%|███████ | 7/10 [00:00<00:00, 66.23it/s, # trackers=6] Processed Story Blocks: 70%|███████ | 7/10 [00:00<00:00, 66.23it/s, # trackers=6] Processed Story Blocks: 70%|███████ | 7/10 [00:00<00:00, 66.23it/s, # trackers=6] Processed Story Blocks: 70%|███████ | 7/10 [00:00<00:00, 66.23it/s, # trackers=6] Processed Story Blocks: 100%|██████████| 10/10 [00:00<00:00, 57.56it/s, # trackers=6] Processed Story Blocks: 0%| | 0/10 [00:00<?, ?it/s] Processed Story Blocks: 0%| | 0/10 [00:00<?, ?it/s, # trackers=7] Processed Story Blocks: 0%| | 0/10 [00:00<?, ?it/s, # trackers=7] Processed Story Blocks: 0%| | 0/10 [00:00<?, ?it/s, # trackers=7] Processed Story Blocks: 0%| | 0/10 [00:00<?, ?it/s, # trackers=7] Processed Story Blocks: 0%| | 0/10 [00:00<?, ?it/s, # trackers=7] Processed Story Blocks: 0%| | 0/10 [00:00<?, ?it/s, # trackers=7] Processed Story Blocks: 60%|██████ | 6/10 [00:00<00:00, 58.79it/s, # trackers=7] Processed Story Blocks: 60%|██████ | 6/10 [00:00<00:00, 58.79it/s, # trackers=7] Processed Story Blocks: 60%|██████ | 6/10 [00:00<00:00, 58.79it/s, # trackers=7] Processed Story Blocks: 60%|██████ | 6/10 [00:00<00:00, 58.79it/s, # trackers=7] Processed Story Blocks: 60%|██████ | 6/10 [00:00<00:00, 58.79it/s, # trackers=7] Processed Story Blocks: 100%|██████████| 10/10 [00:00<00:00, 50.46it/s, # trackers=7] Processed actions: 0it [00:00, ?it/s] Processed actions: 0it [00:00, ?it/s, # examples=1]

ValueError Traceback (most recent call last) ~/finalbot/finalbot0_env/lib/python3.6/site-packages/rasa_core/domain.py in index_for_action(self, action_name) 314 try: –> 315 return self.action_names.index(action_name) 316 except ValueError:

ValueError: ‘pizza_form’ is not in list

During handling of the above exception, another exception occurred:

NameError Traceback (most recent call last) in 13 training_data = agent.load_data(‘stories.md’) 14 —> 15 agent.train(training_data) 16 17 agent.persist(‘models/dialogue’)

~/finalbot/finalbot0_env/lib/python3.6/site-packages/rasa_core/agent.py in train(self, training_trackers, **kwargs) 518 519 self.policy_ensemble.train(training_trackers, self.domain, –> 520 **kwargs) 521 self._set_fingerprint() 522

~/finalbot/finalbot0_env/lib/python3.6/site-packages/rasa_core/policies/ensemble.py in train(self, training_trackers, domain, **kwargs) 61 if training_trackers: 62 for policy in self.policies: —> 63 policy.train(training_trackers, domain, **kwargs) 64 else: 65 logger.info("Skipped training, because there are no "

~/finalbot/finalbot0_env/lib/python3.6/site-packages/rasa_core/policies/memoization.py in train(self, training_trackers, domain, **kwargs) 139 training_trackers, domain) 140 self._add_states_to_lookup(trackers_as_states, trackers_as_actions, –> 141 domain) 142 logger.debug(“Memorized {} unique examples.” 143 “”.format(len(self.lookup)))

~/finalbot/finalbot0_env/lib/python3.6/site-packages/rasa_core/policies/memoization.py in _add_states_to_lookup(self, trackers_as_states, trackers_as_actions, domain, online) 95 96 feature_key = self._create_feature_key(states) —> 97 feature_item = domain.index_for_action(action) 98 99 if feature_key not in ambiguous_feature_keys:

~/finalbot/finalbot0_env/lib/python3.6/site-packages/rasa_core/domain.py in index_for_action(self, action_name) 315 return self.action_names.index(action_name) 316 except ValueError: –> 317 self._raise_action_not_found_exception(action_name) 318 319 def _raise_action_not_found_exception(self, action_name):

~/finalbot/finalbot0_env/lib/python3.6/site-packages/rasa_core/domain.py in _raise_action_not_found_exception(self, action_name) 324 "action for this domain. " 325 “Available actions are: \n{}” –> 326 “”.format(action_name, action_names)) 327 328 def random_template_for(self, utter_action):

NameError: Cannot access action ‘pizza_form’, as that name is not a registered action for this domain. Available actions are: - action_listen - action_restart - action_default_fallback - action_deactivate_form - action_revert_fallback_events - action_default_ask_affirmation - action_default_ask_rephrase i do not have those actions in my domain

(Srikar) #13

You need to add the form policy to the policy.yml file.

Add this line:

- name: FormPolicy

(tatenda) #14

hey i discovered that i had bad indentation in my domain.yml file and i corrected. right now it seems like there is something wrong with my templates and slots values because when i try to train on cmd i get the following

. these are my data files domain.yml (2.9 KB) nlu.md (5.2 KB) stories.md (2.2 KB)

(Srikar) #15

Try changing this:

utter_slots_values:
        - text: "You have ordered the following pizza:

             - size: {size}

             - pizzatype: {pizzatype}

             - num_pizza: {num_pizza}

             - toppings: {toppings}

             - feedback: {feedback}"

With this:

utter_slots_values:
        - text: "You have ordered the following pizza:/nsize: {size}/npizzatype: {pizzatype}\nnum_pizza: {num_pizza}\ntoppings: {toppings}\nfeedback: {feedback}"