Skip to content

Commit

Permalink
Merge pull request #50 from RasaHQ/ver0.12.2
Browse files Browse the repository at this point in the history
Cherrypick for Version 0.12.2
  • Loading branch information
MetcalfeTom authored Feb 17, 2019
2 parents 316a37b + 15341dd commit 671c08c
Show file tree
Hide file tree
Showing 13 changed files with 197 additions and 35 deletions.
16 changes: 16 additions & 0 deletions .github/ISSUE_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<!-- THIS INFORMATION IS MANDATORY - YOUR ISSUE WILL BE CLOSED IF IT IS MISSING. If you don't know your Rasa Core SDK version, use `pip list | grep rasa_core_sdk`. Removing the below information is allowed for FEATURE REQUESTS. -->

**Rasa Core SDK version**:

**Python version**:

**Operating system** (windows, osx, ...):

**Issue**:



**Content of domain file** (if used & relevant):
```yaml

```
8 changes: 8 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
**Proposed changes**:
- ...

**Status (please check what you already did)**:
- [ ] made PR ready for code review
- [ ] added some tests for the functionality
- [ ] updated the documentation
- [ ] updated the changelog
12 changes: 12 additions & 0 deletions .github/no-response.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Configuration for probot-no-response - https://github.com/probot/no-response

# Number of days of inactivity before an Issue is closed for lack of response
daysUntilClose: 14
# Label requiring a response
responseRequiredLabel: more-information-needed
# Comment to post when closing an Issue for lack of response. Set to `false` to disable
closeComment: >
This issue has been automatically closed because there has been no response
to our request for more information from the original author. Without this,
we don't have enough information to help you. Please comment below with the
requested information if you still need help.
22 changes: 22 additions & 0 deletions .github/stale.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Number of days of inactivity before an issue becomes stale
daysUntilStale: 90
# Number of days of inactivity before a stale issue is closed
daysUntilClose: 7
# Issues with these labels will never be considered stale
exemptLabels:
- enhancement
- discussion
# Label to use when marking an issue as stale
staleLabel: stale
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions.
# Comment to post when closing a stale issue. Set to `false` to disable
closeComment: >
This issue has been automatically closed due to inactivity. Please create
a new issue if you need more help.
# limit to only issues
only: issues
23 changes: 10 additions & 13 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,28 @@ Change Log
All notable changes to this project will be documented in this file.
This project adheres to `Semantic Versioning`_ starting with version 0.11.0.

.. _master-release:

[Unreleased 0.12.0.aX] - `master`_
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. note:: This version is not yet released and is under active development.
[0.12.2] - 2019-02-17
^^^^^^^^^^^^^^^^^^^^^

Added
-----

Removed
-------
- add optional `validate_{slot}` methods to `FormAction`
- forms can now be deactivated during the validation function by returning
`self.deactivate()`
- Function to get latest input channel from the tracker with
``tracker.get_latest_input_channel()``

Changed
-------

Fixed
-----
- ``self._deactivate()`` method from the ``FormAction`` class has been
renamed to ``self.deactivate()``

[0.12.1] - 2018-11-11
^^^^^^^^^^^^^^^^^^^^^

Fixed
-----
- doc formatting preventing successfull rasa core travis build
- doc formatting preventing successful rasa core travis build

[0.12.0] - 2018-11-11
^^^^^^^^^^^^^^^^^^^^^
Expand Down
9 changes: 9 additions & 0 deletions rasa_core_sdk/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ def current_state(self):
"latest_event_time": latest_event_time,
"paused": self.is_paused(),
"events": self.events,
"latest_input_channel": self.get_latest_input_channel(),
"active_form": self.active_form,
"latest_action_name": self.latest_action_name
}
Expand Down Expand Up @@ -104,6 +105,14 @@ def get_latest_entity_values(self, entity_type):
for x in entities
if x.get("entity") == entity_type)

def get_latest_input_channel(self):
# type: () -> Optional[Text]
"""Get the name of the input_channel of the latest UserUttered event"""

for e in reversed(self.events):
if e.get("event") == "user":
return e.get("input_channel")

def is_paused(self):
# type: () -> bool
"""State whether the tracker is currently paused."""
Expand Down
5 changes: 5 additions & 0 deletions rasa_core_sdk/endpoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
from rasa_core_sdk.executor import ActionExecutor
from rasa_core_sdk import ActionExecutionRejection

from rasa_core_sdk import utils

DEFAULT_SERVER_PORT = 5055

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -50,6 +52,7 @@ def create_argument_parser():
default=None,
help="name of action package to be loaded"
)
utils.add_logging_option_arguments(parser)
return parser


Expand Down Expand Up @@ -101,6 +104,8 @@ def webhook():
logging.basicConfig(level=logging.DEBUG)
logging.getLogger('matplotlib').setLevel(logging.WARN)

utils.configure_colored_logging(cmdline_args.loglevel)

logger.info("Starting action endpoint server...")
edp_app = endpoint_app(cors_origins=cmdline_args.cors,
action_package_name=cmdline_args.actions)
Expand Down
4 changes: 3 additions & 1 deletion rasa_core_sdk/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@
# noinspection PyPep8Naming
def UserUttered(text,
parse_data=None,
timestamp=None):
timestamp=None,
input_channel=None):
return {
"event": "user",
"timestamp": timestamp,
"text": text,
"parse_data": parse_data,
"input_channel": input_channel
}


Expand Down
53 changes: 33 additions & 20 deletions rasa_core_sdk/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -251,8 +251,14 @@ def validate(self, dispatcher, tracker, domain):
# extract requested slot
slot_to_fill = tracker.get_slot(REQUESTED_SLOT)
if slot_to_fill:
slot_values.update(self.extract_requested_slot(dispatcher,
tracker, domain))
for slot, value in self.extract_requested_slot(dispatcher,
tracker,
domain).items():
validate_func = getattr(self, "validate_{}".format(slot),
lambda *x: value)
slot_values[slot] = validate_func(value, dispatcher, tracker,
domain)

if not slot_values:
# reject to execute the form action
# if some slot was requested but nothing was extracted
Expand All @@ -279,7 +285,10 @@ def request_next_slot(self,
for slot in self.required_slots(tracker):
if self._should_request_slot(tracker, slot):
logger.debug("Request next slot '{}'".format(slot))
dispatcher.utter_template("utter_ask_{}".format(slot), tracker)
dispatcher.utter_template("utter_ask_{}".format(slot),
tracker,
silent_fail=False,
**tracker.slots)
return [SlotSet(REQUESTED_SLOT, slot)]

logger.debug("No slots left to request")
Expand Down Expand Up @@ -360,7 +369,7 @@ def _should_request_slot(tracker, slot_name):

return tracker.get_slot(slot_name) is None

def _deactivate(self):
def deactivate(self):
# type: () -> List[Dict]
"""Return `Form` event with `None` as name to deactivate the form
and reset the requested slot"""
Expand All @@ -382,22 +391,26 @@ def run(self, dispatcher, tracker, domain):
# validate user input
events.extend(self._validate_if_required(dispatcher, tracker, domain))

# create temp tracker with populated slots from `validate` method
temp_tracker = tracker.copy()
for e in events:
if e['event'] == 'slot':
temp_tracker.slots[e["name"]] = e["value"]

next_slot_events = self.request_next_slot(dispatcher, temp_tracker,
domain)
if next_slot_events is not None:
# request next slot
events.extend(next_slot_events)
else:
# there is nothing more to request, so we can submit
events.extend(self.submit(dispatcher, temp_tracker, domain))
# deactivate the form after submission
events.extend(self._deactivate())
# check that the form wasn't deactivated in validation
if Form(None) not in events:

# create temp tracker with populated slots from `validate` method
temp_tracker = tracker.copy()
for e in events:
if e['event'] == 'slot':
temp_tracker.slots[e["name"]] = e["value"]

next_slot_events = self.request_next_slot(dispatcher, temp_tracker,
domain)

if next_slot_events is not None:
# request next slot
events.extend(next_slot_events)
else:
# there is nothing more to request, so we can submit
events.extend(self.submit(dispatcher, temp_tracker, domain))
# deactivate the form after submission
events.extend(self.deactivate())

return events

Expand Down
31 changes: 31 additions & 0 deletions rasa_core_sdk/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

from typing import Any, List

import logging


def all_subclasses(cls):
# type: (Any) -> List[Any]
Expand All @@ -16,6 +18,35 @@ def all_subclasses(cls):
for g in all_subclasses(s)]


def add_logging_option_arguments(parser):
"""Add options to an argument parser to configure logging levels."""

# arguments for logging configuration
parser.add_argument(
'-v', '--verbose',
help="Be verbose. Sets logging level to INFO",
action="store_const",
dest="loglevel",
const=logging.INFO,
default=logging.INFO,
)
parser.add_argument(
'-vv', '--debug',
help="Print lots of debugging statements. "
"Sets logging level to DEBUG",
action="store_const",
dest="loglevel",
const=logging.DEBUG,
)
parser.add_argument(
'--quiet',
help="Be quiet! Sets logging level to WARNING",
action="store_const",
dest="loglevel",
const=logging.WARNING,
)


def configure_colored_logging(loglevel):
import coloredlogs
field_styles = coloredlogs.DEFAULT_FIELD_STYLES.copy()
Expand Down
2 changes: 1 addition & 1 deletion rasa_core_sdk/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@
from __future__ import absolute_import


__version__ = '0.12.1a1'
__version__ = '0.12.2'
29 changes: 29 additions & 0 deletions tests/test_forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -472,3 +472,32 @@ def required_slots(_tracker):
# check that validation was skipped
# because previous action is not action_listen
assert events == []


def test_early_deactivation():
# noinspection PyAbstractClass
class CustomFormAction(FormAction):
def name(self):
return "some_form"

@staticmethod
def required_slots(_tracker):
return ["some_slot", "some_other_slot"]

def validate(self, dispatcher, tracker, domain):
return self.deactivate()

form = CustomFormAction()

tracker = Tracker('default', {'some_slot': 'some_value'},
{'intent': 'greet'},
[], False, None,
{'name': 'some_form',
'validate': True, 'rejected': False},
'action_listen')

events = form.run(dispatcher=None, tracker=tracker, domain=None)

# check that form was deactivated before requesting next slot
assert events == [Form(None), SlotSet('requested_slot', None)]
assert SlotSet('requested_slot', "some_other_slot") not in events
18 changes: 18 additions & 0 deletions tests/test_tracker.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals

from rasa_core_sdk import Tracker
from rasa_core_sdk.events import ActionExecuted, UserUttered


def test_latest_input_channel():
tracker = Tracker('default', {},
{'intent': {'name': 'some_intent', 'confidence': 1.0}},
[UserUttered("my message text",
input_channel="superchat"),
ActionExecuted("action_listen")],
False, None, {}, 'action_listen')

assert tracker.get_latest_input_channel() == "superchat"

0 comments on commit 671c08c

Please sign in to comment.