Added basic entity support
parent
4d2a4dacdd
commit
98a4f5349d
64
__init__.py
64
__init__.py
|
@ -3,15 +3,73 @@ from opsdroid.matchers import match_rasanlu, match_parse
|
|||
import random
|
||||
|
||||
class Respond(Skill):
|
||||
# Constructor gets configs for the skill and applies the decorator
|
||||
# to match using rasa.
|
||||
def __init__(self, opsdroid, config):
|
||||
super().__init__(opsdroid, config)
|
||||
self.intent = self.config.get("intent")
|
||||
self._get_configs()
|
||||
self.respond = match_rasanlu(self.intent)(self.respond)
|
||||
|
||||
# This utility function will grab the relevent config variables
|
||||
# for this skill to function.
|
||||
def _get_configs(self):
|
||||
# The intent to match.
|
||||
self.intent = self.config.get("intent")
|
||||
# Possible responses given a match.
|
||||
self.response_options = self.config.get("response_options")
|
||||
# A bool to check if we want to use entities in our response.
|
||||
self.use_entities = self.config.get("use_entities", False)
|
||||
# Fallback responses if we do not get the required entities
|
||||
# from Rasa.
|
||||
self.fallback_response_options = self.config.get("fallback_response_options",
|
||||
["Sorry, Rasa did not extract sufficient entities to fulfil your request"])
|
||||
|
||||
|
||||
# Extract the entities from the rasanlu response
|
||||
def _get_entities(self, message):
|
||||
# This includes data such as the extractor used, which we
|
||||
# don't need.
|
||||
raw_entities = message.rasanlu["entities"]
|
||||
entities = {}
|
||||
for entity in raw_entities:
|
||||
entity_type = entity["entity"]
|
||||
unique_entity_type = self._get_unique_key(entity_type, entities)
|
||||
entity_value = entity["value"]
|
||||
entities[unique_entity_type] = entity_value
|
||||
return entities
|
||||
|
||||
|
||||
# Appends the smallest integer to the name of the key in order to
|
||||
# create a new key that is not already in the dictionary.
|
||||
def _get_unique_key(self, base_key, dictionary):
|
||||
counter = 0
|
||||
while True:
|
||||
unique_key_attempt = base_key + str(counter)
|
||||
if unique_key_attempt in dictionary:
|
||||
counter += 1
|
||||
continue
|
||||
return unique_key_attempt
|
||||
|
||||
|
||||
# Takes the response and attempts to replace all entities in it
|
||||
# with the extracted entities. Failing that, we will fall back to a
|
||||
# fallback response.
|
||||
def _substitute_entities(self, response, entities):
|
||||
try:
|
||||
response = response.format(**entities)
|
||||
except KeyError as e:
|
||||
chosen_fallback = random.choice(self.fallback_response_options)
|
||||
return chosen_fallback
|
||||
return response
|
||||
|
||||
|
||||
# This line is to add properties to respond on declaration
|
||||
# as doing this in __init__ would cause an exception to be
|
||||
# raised. If you don't believe me, remove it!
|
||||
@match_parse("hgftgyhjknbvhgftyuihjkvhgftyuijkbjhgtyyuijhkjghfdtrytyihujkbvncgfxdtrytuyiuhkbjvbhcfdytryuhjkbvhcfdyrtuyiuhkbhj")
|
||||
async def respond(self, message):
|
||||
response_options = self.config.get("response_options")
|
||||
await message.respond(random.choice(response_options))
|
||||
chosen_response = random.choice(self.response_options)
|
||||
if self.use_entities:
|
||||
entities = self._get_entities(message)
|
||||
chosen_response = self._substitute_entities(chosen_response, entities)
|
||||
await message.respond(random.choice(self.response_options))
|
||||
|
|
Loading…
Reference in New Issue