async def run(self, output_channel, nlg, tracker, domain) -> List[Event]: json_body = self._action_call_format(tracker, domain) if not self.action_endpoint: logger.error("The model predicted the custom action '{}', " "but you didn't configure an endpoint to " "run this custom action. Please take a look at " "the docs and set an endpoint configuration via the " "--endpoints flag. " "{}/core/actions" "".format(self.name(), DOCS_BASE_URL)) raise Exception("Failed to execute custom action.") try: logger.debug("Calling action endpoint to run action '{}'.".format( self.name())) response = await self.action_endpoint.request( json=json_body, method="post", timeout=DEFAULT_REQUEST_TIMEOUT) self._validate_action_result(response) events_json = response.get("events", []) responses = response.get("responses", []) bot_messages = await self._utter_responses(responses, output_channel, nlg, tracker) evts = events.deserialise_events(events_json) return bot_messages + evts except ClientResponseError as e: if e.status == 400: response_data = json.loads(e.text) exception = ActionExecutionRejection( response_data["action_name"], response_data.get("error")) logger.error(exception.message) raise exception else: raise Exception("Failed to execute custom action.") from e except aiohttp.ClientConnectionError as e: logger.error("Failed to run custom action '{}'. Couldn't connect " "to the server at '{}'. Is the server running? " "Error: {}".format(self.name(), self.action_endpoint.url, e)) raise Exception("Failed to execute custom action.") except aiohttp.ClientError as e: # not all errors have a status attribute, but # helpful to log if they got it # noinspection PyUnresolvedReferences status = getattr(e, "status", None) logger.error("Failed to run custom action '{}'. Action server " "responded with a non 200 status code of {}. " "Make sure your action server properly runs actions " "and returns a 200 once the action is executed. " "Error: {}".format(self.name(), status, e)) raise Exception("Failed to execute custom action.")
async def get_conversation_tracker_impl(request: Request, conversation_id: Text, user: Dict[Text, Any] = None): event_service = _event_service(request) if not _has_access_to_conversation(event_service, conversation_id, user): return rasa_x_utils.error(HTTPStatus.UNAUTHORIZED, "NoPermission", "Access denied") until_time = rasa_x_utils.float_arg(request, "until", None) since_time = rasa_x_utils.float_arg(request, "since", None) rasa_environment_query = rasa_x_utils.default_arg( request, "rasa_environment", DEFAULT_RASA_ENVIRONMENT) event_verbosity = _event_verbosity_from_request(request) exclude_leading_action_session_start = rasa_x_utils.bool_arg( request, "exclude_leading_action_session_start", False) tracker = event_service.get_tracker_with_message_flags( conversation_id, until_time, since_time, event_verbosity, rasa_environment_query, exclude_leading_action_session_start, ) if not tracker: return rasa_x_utils.error( HTTPStatus.NOT_FOUND, "ClientNotFound", f"Client for conversation_id '{conversation_id}' could not be found", ) requested_format = request.headers.get("Accept") if requested_format == "application/json": dispo = f"attachment;filename={conversation_id}-dump.json" return response.json( tracker, content_type="application/json", headers={"Content-Disposition": dispo}, ) elif requested_format == "text/markdown": _events = events.deserialise_events(tracker["events"]) story = Story.from_events(_events) exported = story.as_story_string(flat=True) return response.text( exported, content_type="text/markdown", headers={ "Content-Disposition": f"attachment;filename={conversation_id}-story.md" }, ) else: return response.json(tracker, headers={"Content-Disposition": "inline"})
async def _write_stories_to_file(export_story_path: Text, evts: List[Dict[Text, Any]]) -> None: """Write the conversation of the sender_id to the file paths.""" sub_conversations = _split_conversation_at_restarts(evts) with open(export_story_path, "a", encoding="utf-8") as f: for conversation in sub_conversations: parsed_events = events.deserialise_events(conversation) s = Story.from_events(parsed_events) f.write(s.as_story_string(flat=True) + "\n")
def from_dict(cls, sender_id: Text, events_as_dict: List[Dict[Text, Any]], slots: List[Slot], max_event_history: Optional[int] = None ) -> 'DialogueStateTracker': """Create a tracker from dump. The dump should be an array of dumped events. When restoring the tracker, these events will be replayed to recreate the state.""" evts = events.deserialise_events(events_as_dict) return cls.from_events(sender_id, evts, slots, max_event_history)
def test_put_tracker(app): data = json.dumps([event.as_dict() for event in test_events]) _, response = app.put("/conversations/pushtracker/tracker/events", data=data, headers={"Content-Type": "application/json"}) content = response.json assert response.status == 200 assert len(content["events"]) == len(test_events) assert content["sender_id"] == "pushtracker" _, tracker_response = app.get("/conversations/pushtracker/tracker") tracker = tracker_response.json assert tracker is not None evts = tracker.get("events") assert events.deserialise_events(evts) == test_events
async def _fetch_events(sender_ids: List[Union[Text, List[Event]]], endpoint: EndpointConfig) -> List[List[Event]]: """Retrieve all event trackers from the endpoint for all sender ids.""" event_sequences = [] for sender_id in sender_ids: if isinstance(sender_id, str): tracker = await retrieve_tracker(endpoint, sender_id) evts = tracker.get("events", []) for conversation in _split_conversation_at_restarts(evts): parsed_events = events.deserialise_events(conversation) event_sequences.append(parsed_events) else: event_sequences.append(sender_id) return event_sequences
def test_put_tracker(rasa_app: SanicTestClient): data = [event.as_dict() for event in test_events] _, response = rasa_app.put( "/conversations/pushtracker/tracker/events", json=data, headers={"Content-Type": rasa.server.JSON_CONTENT_TYPE}, ) content = response.json assert response.status == 200 assert len(content["events"]) == len(test_events) assert content["sender_id"] == "pushtracker" _, tracker_response = rasa_app.get("/conversations/pushtracker/tracker") tracker = tracker_response.json assert tracker is not None evts = tracker.get("events") assert events.deserialise_events(evts) == test_events
async def _write_stories_to_file( export_story_path: Text, evts: List[Dict[Text, Any]] ) -> None: """Write the conversation of the sender_id to the file paths.""" sub_conversations = _split_conversation_at_restarts(evts) create_path(export_story_path) if os.path.exists(export_story_path): append_write = "a" # append if already exists else: append_write = "w" # make a new file if not with open(export_story_path, append_write, encoding="utf-8") as f: for conversation in sub_conversations: parsed_events = events.deserialise_events(conversation) s = Story.from_events(parsed_events) f.write("\n" + s.as_story_string(flat=True))
def execute(self, action_name, text, get_tracker=False): """ $ python -m sagas.bots.action_runner execute action_about_date '找音乐会' $ python -m sagas.bots.action_runner execute action_about_date '找音乐会' True $ python -m sagas.bots.action_runner execute action_joke '找音乐会' :param action_name: :param text: :return: """ # tracker = DialogueStateTracker("default", domain.slots) tracker = self.prepare(text) dispatcher = CollectingDispatcher() action = self.executor.actions.get(action_name) events = action(dispatcher, tracker, self.domain) resp = self.create_api_response(events, dispatcher.messages) if get_tracker: evs = deserialise_events(events) for ev in evs: tracker.update(ev) return resp, tracker else: return resp