From f90d7a30a2e65189ec06b208910f9580645ef2f9 Mon Sep 17 00:00:00 2001 From: Nolwenn Bernard <28621493+NoB0@users.noreply.github.com> Date: Thu, 7 Nov 2024 10:14:31 -0600 Subject: [PATCH] Update `display_agent_utterance` to consider agent and recipient ID (#265) * Update `display_agent_utterance` to consider agent and recipient ID Fixes #252 * Fix pre-commit * Update pre-commit requirements * Address review comments --- .pre-commit-config.yaml | 5 ++++- dialoguekit/connector/dialogue_connector.py | 7 ++++--- dialoguekit/core/annotated_utterance.py | 6 +++--- dialoguekit/core/feedback.py | 6 +++--- dialoguekit/nlu/disjoint_dialogue_act_extractor.py | 4 ++-- dialoguekit/nlu/intent_classifier.py | 6 +++--- dialoguekit/participant/user.py | 3 +-- dialoguekit/participant/user_preferences.py | 4 ++-- dialoguekit/platforms/flask_socket_platform.py | 9 +++++---- dialoguekit/platforms/platform.py | 9 +++++++-- dialoguekit/platforms/terminal_platform.py | 10 ++++++---- dialoguekit/utils/annotation_converter.py | 4 ++-- requirements/pre_commit.txt | 2 +- sample_agents/rasa_parrot_agent.py | 4 ++-- sample_agents/woz_agent.py | 5 ++--- tests/nlg/test_conditional_nlg.py | 3 +-- tests/platforms/test_flask_socketio_platform.py | 10 ++++++---- 17 files changed, 54 insertions(+), 43 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a9bd1c2e..001137c7 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -15,7 +15,10 @@ repos: name: docformatter description: "Formats docstrings to follow PEP 257." entry: docformatter - args: [--in-place] + args: + - --in-place + - --wrap-summaries=80 + - --wrap-descriptions=80 language: python types: [python] diff --git a/dialoguekit/connector/dialogue_connector.py b/dialoguekit/connector/dialogue_connector.py index e278238c..20b33839 100644 --- a/dialoguekit/connector/dialogue_connector.py +++ b/dialoguekit/connector/dialogue_connector.py @@ -13,6 +13,7 @@ the User, the DialogueConnector sends it to the other party by calling their `receive_{agent/user}_utterance()` method. """ + from __future__ import annotations import json @@ -107,7 +108,7 @@ def register_agent_utterance( """ self._dialogue_history.add_utterance(annotated_utterance) self._platform.display_agent_utterance( - self._user.id, annotated_utterance + annotated_utterance, self._agent.id, self._user.id ) if self._agent.stop_intent in annotated_utterance.get_intents(): self.close() @@ -137,8 +138,8 @@ def start(self) -> None: def close(self) -> None: """Closes the conversation. - If '_save_dialogue_history' is set to True it will export the - dialogue history. + If '_save_dialogue_history' is set to True it will export the dialogue + history. """ if self._save_dialogue_history: self._dump_dialogue_history() diff --git a/dialoguekit/core/annotated_utterance.py b/dialoguekit/core/annotated_utterance.py index 5b81ff44..466590a3 100644 --- a/dialoguekit/core/annotated_utterance.py +++ b/dialoguekit/core/annotated_utterance.py @@ -13,9 +13,9 @@ class AnnotatedUtterance(Utterance): """Represents an utterance, with annotations. - The AnnotatedUtterance is a Utterance with additional information. - In some cases we want to send an utterance with dialogue acts and/or - Annotations. Dialogue acts are a specific type of annotation. + The AnnotatedUtterance is a Utterance with additional information. In some + cases we want to send an utterance with dialogue acts and/or Annotations. + Dialogue acts are a specific type of annotation. """ dialogue_acts: List[DialogueAct] = field( diff --git a/dialoguekit/core/feedback.py b/dialoguekit/core/feedback.py index 6525b484..a5890ec0 100644 --- a/dialoguekit/core/feedback.py +++ b/dialoguekit/core/feedback.py @@ -1,8 +1,8 @@ """Interface representing user's feedback. -Currently only binary feedback is supported on the utterance level. -Later, it might be extended to graded feedback as well as with -conversation-level feedback. +Currently only binary feedback is supported on the utterance level. Later, it +might be extended to graded feedback as well as with conversation-level +feedback. """ from dataclasses import dataclass, field from enum import Enum diff --git a/dialoguekit/nlu/disjoint_dialogue_act_extractor.py b/dialoguekit/nlu/disjoint_dialogue_act_extractor.py index 7681374f..52b92941 100644 --- a/dialoguekit/nlu/disjoint_dialogue_act_extractor.py +++ b/dialoguekit/nlu/disjoint_dialogue_act_extractor.py @@ -1,8 +1,8 @@ """Dialogue act extractor with disjoint intent classification and slot filling. It is assumed that the intent classifier assigns a single intent to the -utterance that corresponds to the slot-value pairs extracted by the -slot-value annotators. +utterance that corresponds to the slot-value pairs extracted by the slot-value +annotators. """ from __future__ import annotations diff --git a/dialoguekit/nlu/intent_classifier.py b/dialoguekit/nlu/intent_classifier.py index e37333f8..407a6967 100644 --- a/dialoguekit/nlu/intent_classifier.py +++ b/dialoguekit/nlu/intent_classifier.py @@ -1,8 +1,8 @@ """Abstract interface for intent classification. -This interface assumes a single intent per utterance, i.e., approaches -the task as a single-label classification problem. The generalization to -multi-label classification is left to future work. +This interface assumes a single intent per utterance, i.e., approaches the task +as a single-label classification problem. The generalization to multi-label +classification is left to future work. """ from abc import ABC, abstractmethod diff --git a/dialoguekit/participant/user.py b/dialoguekit/participant/user.py index bdd66eca..28033222 100644 --- a/dialoguekit/participant/user.py +++ b/dialoguekit/participant/user.py @@ -1,8 +1,7 @@ """Abstract representation of core user-related data and functionality. For communicating with an agent, the specific user instance needs to be -connected with a DialogueConnector by invoking -`register_dialogue_connector()`. +connected with a DialogueConnector by invoking `register_dialogue_connector()`. """ from __future__ import annotations diff --git a/dialoguekit/participant/user_preferences.py b/dialoguekit/participant/user_preferences.py index 2e58fe00..93b324e2 100644 --- a/dialoguekit/participant/user_preferences.py +++ b/dialoguekit/participant/user_preferences.py @@ -1,7 +1,7 @@ """General representation of user preferences. -Preferences are given to key-value pairs in terms of real values in the -range [-1,1]. +Preferences are given to key-value pairs in terms of real values in the range +[-1,1]. """ from collections import defaultdict diff --git a/dialoguekit/platforms/flask_socket_platform.py b/dialoguekit/platforms/flask_socket_platform.py index f57fdddc..0f2e45b6 100644 --- a/dialoguekit/platforms/flask_socket_platform.py +++ b/dialoguekit/platforms/flask_socket_platform.py @@ -58,7 +58,7 @@ def from_utterance(self, utterance: Utterance) -> Message: @dataclass class Response: - recipient: str + sender: str message: Message @@ -84,17 +84,18 @@ def start(self, host: str = "127.0.0.1", port: str = "5000") -> None: self.socketio.run(self.app, host=host, port=port) def display_agent_utterance( - self, user_id: str, utterance: Utterance + self, utterance: Utterance, agent_id: str, user_id: str ) -> None: """Emits agent utterance to the client. Args: - user_id: User ID. utterance: An instance of Utterance. + agent_id: Agent ID. + user_id: User ID of the recipient. """ message = Message.from_utterance(utterance) self.socketio.send( - asdict(Response(user_id, message)), + asdict(Response(agent_id, message)), room=user_id, ) diff --git a/dialoguekit/platforms/platform.py b/dialoguekit/platforms/platform.py index d8350edf..7db870ee 100644 --- a/dialoguekit/platforms/platform.py +++ b/dialoguekit/platforms/platform.py @@ -1,4 +1,5 @@ """The Platform facilitates displaying of the conversation.""" + from abc import ABC, abstractmethod from typing import Dict, Type @@ -30,13 +31,17 @@ def start(self) -> None: @abstractmethod def display_agent_utterance( - self, user_id: str, utterance: Utterance + self, utterance: Utterance, agent_id: str, user_id: str ) -> None: """Displays an agent utterance. + Considering that an agent can interact with multiple users, the + user_id is provided to identify the recipient. + Args: - user_id: User ID. utterance: An instance of Utterance. + agent_id: Agent ID. + user_id: User ID of the recipient. Raises: NotImplementedError: If the method is not implemented. diff --git a/dialoguekit/platforms/terminal_platform.py b/dialoguekit/platforms/terminal_platform.py index 584f7c33..0198a9b9 100644 --- a/dialoguekit/platforms/terminal_platform.py +++ b/dialoguekit/platforms/terminal_platform.py @@ -1,8 +1,9 @@ """Terminal platform. -This platform is used for getting user input and displaying agent -responses in the terminal. +This platform is used for getting user input and displaying agent responses in +the terminal. """ + from typing import Type from dialoguekit.core import Utterance @@ -36,13 +37,14 @@ def start(self) -> None: self.disconnect(self._user_id) def display_agent_utterance( - self, user_id: str, utterance: Utterance + self, utterance: Utterance, agent_id: str, user_id: str = None ) -> None: """Displays an agent utterance. Args: - user_id: User ID. utterance: An instance of Utterance. + agent_id: Agent ID. + user_id: User ID of the recipient. Defaults to None. """ print(f"AGENT: {utterance.text}") diff --git a/dialoguekit/utils/annotation_converter.py b/dialoguekit/utils/annotation_converter.py index 75b7944d..29ea77b1 100644 --- a/dialoguekit/utils/annotation_converter.py +++ b/dialoguekit/utils/annotation_converter.py @@ -1,7 +1,7 @@ """Annotation converter interface. -As the different modules used for NLU use different formats for -training, file converters are needed. +As the different modules used for NLU use different formats for training, file +converters are needed. """ from abc import ABC, abstractmethod diff --git a/requirements/pre_commit.txt b/requirements/pre_commit.txt index 6b957a69..9800f8b3 100644 --- a/requirements/pre_commit.txt +++ b/requirements/pre_commit.txt @@ -1,4 +1,4 @@ -pre-commit +pre-commit==3.8.0 black==21.7b0 #Tensorflow 2.6.1 requires typing-extensions~=3.7.4 requires black<=21.7b0 click>=8.0.2 # Fixes black error https://github.com/psf/black/issues/2964 flake8==5.0.4 diff --git a/sample_agents/rasa_parrot_agent.py b/sample_agents/rasa_parrot_agent.py index f251f8f7..9e359584 100644 --- a/sample_agents/rasa_parrot_agent.py +++ b/sample_agents/rasa_parrot_agent.py @@ -1,7 +1,7 @@ """Simplest possible agent that parrots back everything the user says. -This agent depends on Rasa parrot project to parrot back. See -'docs/rasa-parrot.md' for more information +This agent depends on Rasa parrot project to parrot back. See 'docs/rasa- +parrot.md' for more information """ import requests diff --git a/sample_agents/woz_agent.py b/sample_agents/woz_agent.py index d0061261..4ee9932c 100644 --- a/sample_agents/woz_agent.py +++ b/sample_agents/woz_agent.py @@ -1,8 +1,7 @@ """Wizard-of-Oz (WoZ) agent. -A WoZ agent is one that is controlled by a human operator. It can be -especially useful for human-human data collection or for testing -simulated users. +A WoZ agent is one that is controlled by a human operator. It can be especially +useful for human-human data collection or for testing simulated users. """ from typing import List, Optional diff --git a/tests/nlg/test_conditional_nlg.py b/tests/nlg/test_conditional_nlg.py index 6314c87e..9416f156 100644 --- a/tests/nlg/test_conditional_nlg.py +++ b/tests/nlg/test_conditional_nlg.py @@ -21,8 +21,7 @@ def nlg_class() -> ConditionalNLG: """Tests class init. - This method is also a testing fixture used for the rest of the - tests. + This method is also a testing fixture used for the rest of the tests. """ template = extract_utterance_template( annotated_dialogue_file=ANNOTATED_DIALOGUE_FILE, diff --git a/tests/platforms/test_flask_socketio_platform.py b/tests/platforms/test_flask_socketio_platform.py index 3ef4c23a..a37b190c 100644 --- a/tests/platforms/test_flask_socketio_platform.py +++ b/tests/platforms/test_flask_socketio_platform.py @@ -124,10 +124,11 @@ def test_display_agent_utterance(send, platform): text = "Hello, I'm an agent!" utterance = Utterance(text, DialogueParticipant.AGENT) - platform.display_agent_utterance(user_id, utterance) + agent_id = "test_agent_id" + platform.display_agent_utterance(utterance, agent_id, user_id) send.assert_called_once_with( { - "recipient": user_id, + "sender": agent_id, "message": {"text": text, "dialogue_acts": None}, }, room=user_id, @@ -150,10 +151,11 @@ def test_display_agent_annotated_utterance(send, platform): ], ) - platform.display_agent_utterance(user_id, utterance) + agent_id = "test_agent_id" + platform.display_agent_utterance(utterance, agent_id, user_id) send.assert_called_once_with( { - "recipient": user_id, + "sender": agent_id, "message": { "text": text, "dialogue_acts": [