dream
81 строка · 3.4 Кб
1import logging
2from copy import deepcopy
3
4import common.dff.integration.context as int_ctx
5import scenario.response_funcs as response_funcs
6from common.robot import command_intents
7from common.utils import get_intents
8from df_engine.core import Actor, Context
9
10
11logger = logging.getLogger(__name__)
12
13
14def command_selector_response(ctx: Context, actor: Actor, *args, **kwargs) -> str:
15annotated_utterance = int_ctx.get_last_human_utterance(ctx, actor)
16intention, confidence = get_detected_intents(annotated_utterance)
17logger.info(f"Detected intents: {intention}")
18
19response, conf, human_attr, bot_attr, attr = "", 0.0, {}, {}, {}
20if intention is not None and confidence > 0 and intention in response_funcs.get_respond_funcs():
21logger.debug(f"Intent is defined as {intention}")
22dialog = int_ctx.get_dialog(ctx, actor)
23dialog["seen"] = dialog["called_intents"][intention]
24funcs = response_funcs.get_respond_funcs()[intention]
25response = funcs(ctx, actor)
26if not isinstance(response, str):
27conf = deepcopy(response[1])
28human_attr = deepcopy(response[2])
29bot_attr = deepcopy(response[3])
30attr = deepcopy(response[4])
31response = deepcopy(response[0])
32# Special formatter which used in AWS Lambda to identify what was the intent
33while "#+#" in response:
34response = response[: response.rfind(" #+#")]
35logger.info(f"Response: {response}; intent_name: {intention}")
36try:
37response += " #+#{}".format(intention)
38except TypeError:
39logger.error(f"TypeError intent_name: {intention} response: {response};")
40response = "Hmmm... #+#{}".format(intention)
41# todo: we need to know what intent was called
42# current workaround is to use only one intent if several were detected
43# and to append special token with intent_name
44else:
45logger.debug("Intent is not defined")
46
47if response == "":
48intents = get_intents(annotated_utterance, probs=True, which="intent_catcher")
49logger.error(f"response is empty for intents: {intents}")
50elif conf == 0.0:
51return response
52return [[response, conf, human_attr, bot_attr, attr]]
53
54
55def default_response(ctx: Context, actor: Actor, *args, **kwargs) -> str:
56annotated_utterance = int_ctx.get_last_human_utterance(ctx, actor)
57
58intents = get_intents(annotated_utterance, probs=True, which="intent_catcher")
59logger.error(f"response is empty for intents: {intents}")
60return ""
61
62
63def set_confidence_from_input(ctx: Context, actor: Actor, *args, **kwargs) -> Context:
64intent, confidence = get_detected_intents(int_ctx.get_last_human_utterance(ctx, actor))
65if intent in command_intents:
66int_ctx.set_confidence(ctx, actor, 1.0)
67else:
68int_ctx.set_confidence(ctx, actor, confidence)
69return ctx
70
71
72def get_detected_intents(annotated_utterance):
73intents = get_intents(annotated_utterance, probs=True, which="intent_catcher")
74intent, confidence = None, 0.0
75for intent_name, intent_conf in intents.items():
76if intent_conf > 0 and intent_name in response_funcs.get_respond_funcs():
77confidence_current = intent_conf
78if confidence_current > confidence:
79intent, confidence = intent_name, float(confidence_current)
80
81return intent, confidence
82