You are right.
I could think of a workaround, it requires a little bit of hacking. You can avoid writing 250 utter_slot_name
by overriding request_next_slot
method of the FormAction
class inside your own FormAction, here is the original definition:
def request_next_slot(
self,
dispatcher: "CollectingDispatcher",
tracker: "Tracker",
domain: Dict[Text, Any],
) -> Optional[List[EventType]]:
"""Request the next slot and utter template if needed,
else return None"""
for slot in self.required_slots(tracker):
if self._should_request_slot(tracker, slot):
logger.debug(f"Request next slot '{slot}'")
dispatcher.utter_message(template=f"utter_ask_{slot}", **tracker.slots)
return [SlotSet(REQUESTED_SLOT, slot)]
# no more required slots to fill
return None
You can customize the dispatcher.utter_message
method as per your requirement.
You can also avoid writing 250 validation_slot_name
functions by overriding the validate_slots
method. Here is the original definition:
async def validate_slots(
self,
slot_dict: Dict[Text, Any],
dispatcher: "CollectingDispatcher",
tracker: "Tracker",
domain: Dict[Text, Any],
) -> List[EventType]:
"""Validate slots using helper validation functions.
Call validate_{slot} function for each slot, value pair to be validated.
If this function is not implemented, set the slot to the value.
"""
for slot, value in list(slot_dict.items()):
validate_func = getattr(self, f"validate_{slot}", lambda *x: {slot: value})
if utils.is_coroutine_action(validate_func):
validation_output = await validate_func(
value, dispatcher, tracker, domain
)
else:
validation_output = validate_func(value, dispatcher, tracker, domain)
if not isinstance(validation_output, dict):
logger.warning(
"Returning values in helper validation methods is deprecated. "
+ f"Your `validate_{slot}()` method should return "
+ "a dict of {'slot_name': value} instead."
)
validation_output = {slot: validation_output}
slot_dict.update(validation_output)
# validation succeed, set slots to extracted values
return [SlotSet(slot, value) for slot, value in slot_dict.items()]
As you can see, this function calls the corresponding validate_slot_name
function for a given slot. You can customize this to do the appending here itself for a given slot.
I couldn’t think of a way to avoid writing 250 slots though.
Hope that helps.