Extracting Date and Time from DucklingHTTPExtractor

Hi, I want to extract date and time from the DucklingHTTPExtractor for appointment booking. It is going in the same loop and asking the same question and not setting up the slot. Any help @akelad, @Juste, @mloubser

def name(self) -> Text:
    """" Unique form name """
    return "book_appt_form"

@staticmethod
def required_slots(tracker: Tracker) -> List[Text]:

    return ["location", "appt_date", "appt_time"]

def slot_mappings(self) -> 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 {
        "location": [
            self.from_entity(entity="location"),
            self.from_text(intent="location"),
        ],
        "appt_date": [
            self.from_entity(entity="date")
        ],
        "appt_time": [
            self.from_entity(entity="time")
        ]
    }

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"""

    logger.info("Book appointment form")
    dispatcher.utter_message(template="utter_appt_thanks")
    dispatcher.utter_message(template="utter_ask_notes")
    return [AllSlotsReset()]

entities:

  • gender
  • quantity
  • number
  • location
  • date
  • time

config

pipeline:

  • name: WhitespaceTokenizer
  • name: CRFEntityExtractor
  • name: EntitySynonymMapper
  • name: CountVectorsFeaturizer token_pattern: (?u)\b\w+\b
  • name: DIETClassifier
  • name: SpacyNLP model: en_core_web_md
  • name: SpacyEntityExtractor dimensions:
  • PERSON
  • name: DucklingHTTPExtractor url: http://localhost:8000 dimensions:
  • date
  • number
  • date
  • time timezone: “US/Pacific”

policies:

  • name: FallbackPolicy
  • name: AugmentedMemoizationPolicy
  • name: FormPolicy
  • name: MappingPolicy
  • name: EmbeddingPolicy epochs: 100

logs

2020-05-06 09:20:31 DEBUG rasa.core.lock_store - Deleted lock for conversation ‘a6671406b83f4c8694a97d12f0d79ef9’. When do you prefer to meet the doctor?

Your input → monday at 5 pm

2020-05-06 09:20:38 DEBUG rasa.core.tracker_store - Recreating tracker for id ‘a6671406b83f4c8694a97d12f0d79ef9’

2020-05-06 09:20:39 DEBUG rasa.core.processor - Received user message ‘monday at 5 pm’ with intent ‘{‘name’: ‘out_of_scope’, ‘confidence’: 0.9830948710441589}’ and entities ‘[{‘start’: 0, ‘end’: 14, ‘text’: ‘monday at 5 pm’, ‘value’: ‘monday at 5 pm’, ‘confidence’: 1.0, ‘additional_info’: {‘values’: [{‘value’: ‘2020-05-11T17:00:00.000+00:00’, ‘grain’: ‘hour’, ‘type’: ‘value’}, {‘value’: ‘2020-05-18T17:00:00.000+00:00’, ‘grain’: ‘hour’, ‘type’: ‘value’}, {‘value’: ‘2020-05-25T17:00:00.000+00:00’, ‘grain’: ‘hour’, ‘type’: ‘value’}], ‘value’: ‘2020-05-11T17:00:00.000+00:00’, ‘grain’: ‘hour’, ‘type’: ‘value’}, ‘entity’: ‘time’, ‘extractor’: ‘DucklingHTTPExtractor’}]’

2020-05-06 09:20:39 DEBUG rasa.core.processor - Current slot values: age_category: 2 appt_date: None appt_time: None date: None days_old: 12 location: california name: Shawn phone: 555-555-5555 requested_slot: date time: monday at 5 pm 2020-05-06 09:20:39 DEBUG rasa.core.processor - Logged UserUtterance - tracker now has 30 events. 2020-05-06 09:20:39 DEBUG rasa.core.policies.fallback - NLU confidence threshold met, confidence of fallback action set to core threshold (0.3). 2020-05-06 09:20:39 DEBUG rasa.core.policies.memoization - Current tracker state [{‘intent_greet’: 1.0, ‘slot_age_category_1’: 1.0, ‘prev_utter_doc_appt’: 1.0}, {‘intent_affirm’: 1.0, ‘prev_action_listen’: 1.0, ‘slot_age_category_1’: 1.0}, {‘prev_utter_appt_req’: 1.0, ‘intent_affirm’: 1.0, ‘slot_age_category_1’: 1.0}, {‘prev_book_appt_form’: 1.0, ‘intent_affirm’: 1.0, ‘active_form_book_appt_form’: 1.0, ‘slot_age_category_1’: 1.0}, {‘intent_out_of_scope’: 1.0, ‘entity_time’: 1.0, ‘prev_action_listen’: 1.0, ‘active_form_book_appt_form’: 1.0, ‘slot_age_category_1’: 1.0}] 2020-05-06 09:20:39 DEBUG rasa.core.policies.memoization - Launch DeLorean… 2020-05-06 09:20:39 DEBUG rasa.core.policies.memoization - Current tracker state [None, None, None, {}, {‘intent_out_of_scope’: 1.0, ‘entity_time’: 1.0, ‘prev_action_listen’: 1.0}] 2020-05-06 09:20:39 DEBUG rasa.core.policies.memoization - There is no memorised next action 2020-05-06 09:20:39 DEBUG rasa.core.policies.form_policy - There is an active form ‘book_appt_form’ 2020-05-06 09:20:39 DEBUG rasa.core.policies.ensemble - Predicted next action using policy_2_FormPolicy 2020-05-06 09:20:39 DEBUG rasa.core.processor - Predicted next action ‘book_appt_form’ with confidence 1.00. 2020-05-06 09:20:39 DEBUG rasa.core.actions.action - Calling action endpoint to run action ‘book_appt_form’. 2020-05-06 09:20:39 DEBUG rasa.core.processor - Action ‘book_appt_form’ ended with events ‘[BotUttered(‘When do you prefer to meet the doctor?’, {“elements”: null, “quick_replies”: null, “buttons”: null, “attachment”: null, “image”: null, “custom”: null}, {“age_category”: “2”, “days_old”: 12, “location”: “california”, “name”: “Shawn”, “phone”: “555-555-5555”, “requested_slot”: “date”, “time”: “monday at 5 pm”}, 1588737039.100034), <rasa.core.events.SlotSet object at 0x0000023E21AE6648>, <rasa.core.events.SlotSet object at 0x0000023E215CC848>]’. 2020-05-06 09:20:39 DEBUG rasa.core.processor - Current slot values: age_category: 2 appt_date: None appt_time: None date: None days_old: 12 location: california name: Shawn phone: 555-555-5555 requested_slot: date time: monday at 5 pm 2020-05-06 09:20:39 DEBUG rasa.core.policies.fallback - NLU confidence threshold met, confidence of fallback action set to core threshold (0.3). 2020-05-06 09:20:39 DEBUG rasa.core.policies.memoization - Current tracker state [{‘intent_greet’: 1.0, ‘prev_action_listen’: 1.0}, {‘intent_greet’: 1.0, ‘prev_action_fetch_profile’: 1.0, ‘slot_age_category_1’: 1.0}, {‘intent_greet’: 1.0, ‘slot_age_category_1’: 1.0, ‘prev_utter_doc_appt’: 1.0}, {‘intent_affirm’: 1.0, ‘prev_action_listen’: 1.0, ‘slot_age_category_1’: 1.0}, {‘prev_utter_appt_req’: 1.0, ‘intent_affirm’: 1.0, ‘slot_age_category_1’: 1.0}] 2020-05-06 09:20:39 DEBUG rasa.core.policies.memoization - Launch DeLorean… 2020-05-06 09:20:39 DEBUG rasa.core.policies.memoization - Current tracker state [None, None, None, None, {}] 2020-05-06 09:20:39 DEBUG rasa.core.policies.memoization - There is a memorised next action ‘action_listen’ 2020-05-06 09:20:39 DEBUG rasa.core.policies.form_policy - There is an active form ‘book_appt_form’ 2020-05-06 09:20:39 DEBUG rasa.core.policies.mapping_policy - There is no mapped action for the predicted intent, ‘out_of_scope’. 2020-05-06 09:20:39 DEBUG rasa.core.policies.ensemble - Predicted next action using policy_2_FormPolicy 2020-05-06 09:20:39 DEBUG rasa.core.processor - Predicted next action ‘action_listen’ with confidence 1.00. 2020-05-06 09:20:39 DEBUG rasa.core.processor - Action ‘action_listen’ ended with events ‘’. 2020-05-06 09:20:39 DEBUG rasa.core.lock_store - Deleted lock for conversation ‘a6671406b83f4c8694a97d12f0d79ef9’.

When do you prefer to meet the doctor?

@shubh802 the correct entity name here is time, rather than date. You’ll need to adjust that in the dimensions in your config as well.

Hi @akelad

I have changed the entity to time and if I enter 14 May at 2PM . I want to get the values from the slot and separate the date and time from there. Trying to get the slot in the submit call but I am getting the error and also the value i see in the time slot is 14 May at 2PM. Actually i need the internal value from the entities i.e.

‘entities’: [{‘entity’: ‘date’, ‘start’: 0, ‘end’: 13, ‘value’: ‘14 May at 2PM’, ‘extractor’: ‘DIETClassifier’}, {‘start’: 0, ‘end’: 13, ‘text’: ‘14 May at 2PM’, ‘value’: ‘14 May at 2PM’, ‘confidence’: 1.0, ‘additional_info’: {‘values’: [{‘value’: ‘2020-05-14T14:00:00.000+00:00’, ‘grain’: ‘hour’, ‘type’: ‘value’}, {‘value’: ‘2021-05-14T14:00:00.000+00:00’, ‘grain’: ‘hour’, ‘type’: ‘value’}, {‘value’: ‘2022-05-14T14:00:00.000+00:00’, ‘grain’: ‘hour’, ‘type’: ‘value’}], ‘value’: ‘2020-05-14T14:00:00.000+00:00’, ‘grain’: ‘hour’, ‘type’: ‘value’}, ‘entity’: ‘time’, ‘extractor’: ‘DucklingHTTPExtractor’}].

In the tracker of submit action i cannot find these entities to be fetched from time slot

def slot_mappings(self) -> Dict[Text, Union[Dict, List[Dict]]]:
  
    logger.info("slot_mappings method called :")
    print("slot_mappings method called :")
    return {
        "location": [
            self.from_entity(entity="location"),
            self.from_text(intent="location"),
        ],
        "time": [
            self.from_entity(entity="time")
        ]
    }
def submit(self, dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict[Text, Any]) -> List[Dict]:

    logger.info("Submit method called :")
    return_slots = []
    datetime_slot = tracker.get_slot("time")
    logger.info("Date time captured: ", datetime_slot)

actions logs

2020-05-10 17:18:10 DEBUG rasa_sdk.forms - Request next slot ‘time’ 2020-05-10 17:18:10 DEBUG rasa_sdk.executor - Finished running ‘book_appt_form’ 2020-05-10 17:18:20 DEBUG rasa_sdk.executor - Received request to run ‘book_appt_form’ 2020-05-10 17:18:20 DEBUG rasa_sdk.forms - The form ‘{‘name’: ‘book_appt_form’, ‘validate’: True, ‘rejected’: False, ‘trigger_message’: {‘intent’: {‘name’: ‘affirm’, ‘confidence’: 0.999999046325683}, ‘entities’: , ‘intent_ranking’: [{‘name’: ‘affirm’, ‘confidence’: 0.999999046325683}, {‘name’: ‘location’, ‘confidence’: 5.739761377299146e-07}, {‘name’: ‘date_time’, ‘confidence’: 2.017072091575755e-07}, {‘name’: ‘enter_data’, ‘confidence’: 1.776541012077359e-07}, {‘name’: ‘thankyou’, ‘confidence’: 4.710589251999408e-08}, {‘name’: ‘goodbye’, ‘confidence’: 2.863871451097566e-08}, {‘name’: ‘deny’, ‘confidence’: 1.386349701704148e-08}, {‘name’: ‘out_of_scope’, ‘confidence’: 9.622472596504394e-09}, {‘name’: ‘greet’, ‘confidence’: 3.69346109252433e-10}], ‘text’: ‘yes’}}’ is active 2020-05-10 17:18:20 DEBUG rasa_sdk.forms - Validating user input ‘{‘intent’: {‘name’: ‘date_time’, ‘confidence’: 0.9999809265136711}, ‘entities’: [{‘entity’: ‘date’, ‘start’: 0, ‘end’: 13, ‘value’: ‘14 May at 2PM’, ‘extractor’: ‘DIETClassifier’}, {‘start’: 0, ‘end’: 13, ‘text’: ‘14 May at 2PM’, ‘value’: ‘14 May at 2PM’, ‘confidence’: 1.0, ‘additional_info’: {‘values’: [{‘value’: ‘2020-05-14T14:00:00.000+00:00’, ‘grain’: ‘hour’, ‘type’: ‘value’}, {‘value’: ‘2021-05-14T14:00:00.000+00:00’, ‘grain’: ‘hour’, ‘type’: ‘value’}, {‘value’: ‘2022-05-14T14:00:00.000+00:00’, ‘grain’: ‘hour’, ‘type’: ‘value’}], ‘value’: ‘2020-05-14T14:00:00.000+00:00’, ‘grain’: ‘hour’, ‘type’: ‘value’}, ‘entity’: ‘time’, ‘extractor’: ‘DucklingHTTPExtractor’}], ‘intent_ranking’: [{‘name’: ‘date_time’, ‘confidence’: 0.9999809265136711}, {‘name’: ‘thankyou’, ‘confidence’: 8.867796168487985e-06}, {‘name’: ‘greet’, ‘confidence’: 5.750810942117823e-06}, {‘name’: ‘enter_data’, ‘confidence’: 4.027298473374685e-06}, {‘name’: ‘deny’, ‘confidence’: 2.764683131317724e-07}, {‘name’: ‘goodbye’, ‘confidence’: 7.516631939097351e-08}, {‘name’: ‘location’, ‘confidence’: 7.041304428412332e-08}, {‘name’: ‘out_of_scope’, ‘confidence’: 2.956074141025055e-08}, {‘name’: ‘affirm’, ‘confidence’: 1.966047413759497e-08}], ‘text’: ‘14 May at 2PM’}’

2020-05-10 17:18:20 INFO actions - required_slots method called : required_slots method called : 2020-05-10 17:18:20 INFO actions - slot_mappings method called : slot_mappings method called : 2020-05-10 17:18:20 DEBUG rasa_sdk.forms - Trying to extract requested slot ‘time’ … 2020-05-10 17:18:20 INFO actions - slot_mappings method called : slot_mappings method called : 2020-05-10 17:18:20 DEBUG rasa_sdk.forms - Got mapping ‘{‘type’: ‘from_entity’, ‘entity’: ‘time’, ‘intent’: , ‘not_intent’: , ‘role’: None, ‘group’: None}’ 2020-05-10 17:18:20 DEBUG rasa_sdk.forms - Successfully extracted ‘14 May at 2PM’ for requested slot ‘time’ 2020-05-10 17:18:20 DEBUG rasa_sdk.forms - Validating extracted slots: {‘time’: ‘14 May at 2PM’} 2020-05-10 17:18:20 INFO actions - required_slots method called : required_slots method called : 2020-05-10 17:18:20 INFO actions - required_slots method called : required_slots method called : 2020-05-10 17:18:20 DEBUG rasa_sdk.forms - No slots left to request, all required slots are filled: location: california time: 14 May at 2PM

2020-05-10 17:18:20 DEBUG rasa_sdk.forms - Submitting the form ‘book_appt_form’ 2020-05-10 17:18:20 INFO actions - Submit method called : Submit method called : — Logging error — Traceback (most recent call last): File “c:\users\ag20459\appdata\local\continuum\anaconda3\envs\rasax\lib\logging_init_.py”, line 1025, in emit msg = self.format(record) File “c:\users\ag20459\appdata\local\continuum\anaconda3\envs\rasax\lib\logging_init_.py”, line 869, in format return fmt.format(record) File “c:\users\ag20459\appdata\local\continuum\anaconda3\envs\rasax\lib\site-packages\coloredlogs_init_.py”, line 1116, in format return logging.Formatter.format(self, record) File “c:\users\ag20459\appdata\local\continuum\anaconda3\envs\rasax\lib\logging_init_.py”, line 608, in format record.message = record.getMessage() File “c:\users\ag20459\appdata\local\continuum\anaconda3\envs\rasax\lib\logging_init_.py”, line 369, in getMessage msg = msg % self.args TypeError: not all arguments converted during string formatting Call stack: File “c:\users\ag20459\appdata\local\continuum\anaconda3\envs\rasax\lib\runpy.py”, line 193, in run_module_as_main “main”, mod_spec) File “c:\users\ag20459\appdata\local\continuum\anaconda3\envs\rasax\lib\runpy.py”, line 85, in run_code exec(code, run_globals) File "C:\Users\AG20459\AppData\Local\Continuum\anaconda3\envs\rasax\Scripts\rasa.exe_main.py", line 7, in sys.exit(main()) File "c:\users\ag20459\appdata\local\continuum\anaconda3\envs\rasax\lib\site-packages\rasa_main.py", line 91, in main cmdline_arguments.func(cmdline_arguments) File “c:\users\ag20459\appdata\local\continuum\anaconda3\envs\rasax\lib\site-packages\rasa\cli\run.py”, line 52, in run_actions sdk.main_from_args(args) File “c:\users\ag20459\appdata\local\continuum\anaconda3\envs\rasax\lib\site-packages\rasa_sdk_main_.py”, line 21, in main_from_args args.auto_reload, File “c:\users\ag20459\appdata\local\continuum\anaconda3\envs\rasax\lib\site-packages\rasa_sdk\endpoint.py”, line 141, in run app.run(“0.0.0.0”, port, ssl=ssl_context, workers=utils.number_of_sanic_workers()) File “c:\users\ag20459\appdata\local\continuum\anaconda3\envs\rasax\lib\site-packages\sanic\app.py”, line 1167, in run serve(**server_settings) File “c:\users\ag20459\appdata\local\continuum\anaconda3\envs\rasax\lib\site-packages\sanic\server.py”, line 920, in serve loop.run_forever() File “c:\users\ag20459\appdata\local\continuum\anaconda3\envs\rasax\lib\asyncio\base_events.py”, line 541, in run_forever self._run_once() File “c:\users\ag20459\appdata\local\continuum\anaconda3\envs\rasax\lib\asyncio\base_events.py”, line 1786, in _run_once handle._run() File “c:\users\ag20459\appdata\local\continuum\anaconda3\envs\rasax\lib\asyncio\events.py”, line 88, in _run self._context.run(self._callback, *self._args) File “c:\users\ag20459\appdata\local\continuum\anaconda3\envs\rasax\lib\site-packages\spf\framework.py”, line 554, in _handle_request stream_callback) File “c:\users\ag20459\appdata\local\continuum\anaconda3\envs\rasax\lib\site-packages\sanic\app.py”, line 976, in handle_request response = await response File “c:\users\ag20459\appdata\local\continuum\anaconda3\envs\rasax\lib\site-packages\rasa_sdk\endpoint.py”, line 102, in webhook result = await executor.run(action_call) File “c:\users\ag20459\appdata\local\continuum\anaconda3\envs\rasax\lib\site-packages\rasa_sdk\executor.py”, line 387, in run events = await action(dispatcher, tracker, domain) File “c:\users\ag20459\appdata\local\continuum\anaconda3\envs\rasax\lib\site-packages\rasa_sdk\forms.py”, line 606, in run events.extend(self.submit(dispatcher, temp_tracker, domain)) File “C:\Shubham\Office\Project\Anthem AI\rasa training\backup\5_6\a15\actions.py”, line 108, in submit logger.info("Date time captured: ", datetime_slot) Message: 'Date time captured: ’ Arguments: (‘14 May at 2PM’,)

@shubh802 it seems like you annotated the entity in your nlu training data file, you should avoid doing that. And the error you’re getting seems to have to do with the way you’re using the logger function.

I think something you’ll need to do is define a validate_time function (as described in the docs), where you extract the date/time from the entity recognised by duckling using the datetime package.

Thanks you very much @akelad, it worked. Removed the training data of time from nlu also

def validate_time(self,
                  value: Text,
                  dispatcher: CollectingDispatcher,
                  tracker: Tracker,
                  domain: Dict[Text, Any],
                  ) -> Dict[Text, Any]:
    return_slots = []
    if value != None:
        datetime_obj = dateutil.parser.parse(value)
        apptDate= datetime_obj.strftime('%m-%d-%Y')
        logger.info("humanDate value: {}".format(apptDate))
        time = datetime_obj.strftime('%H:%M:%S')
        logger.info("time value: {}".format(time))
        return_slots.append(SlotSet("appt_date", apptDate))
        return_slots.append(SlotSet("appt_time", time))

    return return_slots

I am getting below warning of not to setup the slot in the validate. I hope I can live with it.

2020-05-12 08:21:54 WARNING rasa_sdk.forms - Returning values in helper validation methods is deprecated. Your validate_time() method should return a dict of {‘slot_name’: value} instead.

You can live with it for now, but the better method is to turn your list into a dictionary :slight_smile:

so doing return {"appt_date": value, "appt_time": value}