Closed tchax3742 closed 5 years ago
could you post the actual error it's throwing?
it just displays "ERROR:rasa_core.processor:Encountered an exception while running action 'pizza_form'. Bot will continue, but the actions events are lost. Make sure to fix the exception in your custom code.", even when i run the bot using python nothing more. print("Your bot is ready to talk! Type your messages here or send 'stop'") while True: a = input() if a == 'stop': break responses = agent.handle_message(a) for response in responses: print(response["text"]) My custom action code(for FormAction) does not show any errors, when i greet the bot, it responds properly, but when i enter other intents that's when it posts the error. I got the code from your FormAction examples code on github.
WARNING:rasa_core.agent:Passing a text to agent.handle_message(...)
is deprecated. Rather use agent.handle_text(...)
.
ERROR:rasa_core.processor:Encountered an exception while running action 'pizza_form'. Bot will continue, but the actions events are lost. Make sure to fix the exception in your custom code.
You have ordered the following pizza:
can you post the error from the action server? because this is just the error from rasa_core, which doesn't tell us much apart from the fact that the action execution failed
i only see that when i run python -m rasa_core_sdk.endpoint --actions actions, no errors
that looks like it's not actually being executed then, what's the contents of your endpoints yaml?
action_endpoint: url: http://localhost:5055/webhook
it's properly indented though in my yaml file
I have now included --endpoints endpoints.ym while running the model, like this, python -m rasa_core.run -d models/dialogue -u models/nlu/default/current --endpoints endpoints.yml, and it shows displays the error below, i think that's where the problem is
@akelad the action server is showing that the error is in actions.py slot mappings File "/home/tatenda/finalbot/finalbot0_env/actions.py", line 46, in slot_mappings not_intent="chitchat"), TypeError: from_intent() got an unexpected keyword argument 'entity' and this is the code
# 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()]}
and i would like to know if this is even the right way to implement actions.py
# -*- coding: utf-8 -*-
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","num_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 sizes
return ["large",
"extra large",
"medium",
"small"]
def toppings_db():
# type: () -> List[Text]
#Database of supported toppings
return ["onions",
"mushrooms",
"extra cheese",
"sausage",
"green peppers"]
def pizzatype_db():
# type: () -> List[Text]
# Database of supported pizzatypes
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.size_db():
dispatcher.utter_template('utter_wrong_size', tracker)
# validation failed, set slot to None
slot_values[slot] = None
elif slot == 'pizzatype':
if value.lower() not in self.pizzatype_db():
dispatcher.utter_template('utter_wrong_pizzatype', 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_toppings1',
tracker)
# validation failed, set slot to None
slot_values[slot] = None
elif slot == 'toppings':
if value.lower() not in self.toppings_db():
dispatcher.utter_template('utter_wrong_toppings2', 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
# 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 []
@tchax3742 you already asked this question on a different issue so i'm going to close this. Please avoid creating duplicate issues in future