Hi,
I am trying to implement a Form with Slots that use custom mappings so that I can extract all the entities by myself. I got that working but there is something weird about having multiple extraction functions in a class that derives from FormValidationAction.
When the form loop starts and I get promoted to enter the first sentence/word or whatever I correctly detect that the first required slot has to be filled but after that, on every loop iteration all extract_ functions get called.
What I did to circumvent this problem is to implement the conditional statement
if tracker.slots["requested_slot"] == "one"
for every slot extraction function.
I don’t think that this behavior of calling every extract function on every loop is normal and I probably misconfigured something.
Please take look at my files and help me to find the error.
Domain:
actions:
- validate_test_form
intents:
- request_form
responses:
utter_ask_one:
- text: "give one"
utter_ask_two:
- text: "give two"
utter_ask_three:
- text: "give three"
slots:
one:
type: text
mappings:
- type: custom
conditions:
- active_loop: test_form
requested_slot: one
two:
type: text
mappings:
- type: custom
conditions:
- active_loop: test_form
requested_slot: two
three:
type: text
mappings:
- type: custom
conditions:
- active_loop: test_form
requested_slot: three
forms:
test_form:
required_slots:
- one
- two
- three
session_config:
session_expiration_time: 60
carry_over_slots_to_new_session: true
rules:
rules:
- rule: Activate form
steps:
- intent: request_form
- action: test_form
- active_loop: test_form
- slot_was_set:
- requested_slot: one
- requested_slot: two
- requested_slot: three
actions:
from typing import Any, Text, Dict, List
from rasa_sdk import Action, Tracker
from rasa_sdk.events import SlotSet, SessionStarted, ActionExecuted, EventType
from rasa_sdk import Tracker, FormValidationAction
from rasa_sdk.executor import CollectingDispatcher
class ValidateCustomSlotMappings(FormValidationAction):
def name(self) -> Text:
return "validate_test_form"
async def extract_one(self, dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict) -> Dict[Text, Any]:
print("extract one")
if tracker.slots["requested_slot"] == "one":
text_of_last_user_message = tracker.latest_message.get("text")
return {"one": text_of_last_user_message}
async def extract_two(self, dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict) -> Dict[Text, Any]:
print("extract two")
if tracker.slots["requested_slot"] == "two":
text_of_last_user_message = tracker.latest_message.get("text")
return {"two": text_of_last_user_message}
async def extract_three(self, dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict) -> Dict[Text, Any]:
print("extract three")
if tracker.slots["requested_slot"] == "three":
text_of_last_user_message = tracker.latest_message.get("text")
return {"three": text_of_last_user_message}
Thank you very much!