Yes, metadata can be accessed from your actions. The action_session_start
event can be used to capture this information from the metadata and load it into a slot when the user session begins.
Something like this:
class ActionSessionStart(Action):
def name(self) -> Text:
return "action_session_start"
@staticmethod
def _slot_set_events_from_tracker(
tracker: "DialogueStateTracker",
) -> List["SlotSet"]:
"""Fetch SlotSet events from tracker and carry over key, value and metadata."""
from rasa.core.events import SlotSet
return [
SlotSet(key=event.key, value=event.value, metadata=event.metadata)
for event in tracker.applied_events()
if isinstance(event, SlotSet)
]
async def run(
self,
dispatcher: CollectingDispatcher,
tracker: Tracker,
domain: Dict[Text, Any],
) -> List[EventType]:
events = [SessionStarted()]
# any slots that should be carried over should come after the
# `session_started` event`
events.extend(self._slot_set_events_from_tracker(tracker))
# Grab slots from metadata
message_metadata = []
for e in tracker.events[::-1]:
# Does this tracker event have metadata?
if "metadata" in e and e["metadata"] != None:
message_metadata = e["metadata"]
# Does this metadata have slots?
if message_metadata and "slots" in message_metadata:
for key, value in message_metadata["slots"].items():
logger.info(f"{key} | {value}")
if value is not None:
events.append(SlotSet(key=key, value=value))
break
if len(message_metadata) == 0:
logger.warn(f"session_start but no metadata, tracker.events: {tracker.events}")
# an `action_listen` should be added at the end as a user message follows
events.append(ActionExecuted("action_listen"))
return events