From e19e88ace980946f2714edabd5ef541f808e55b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Gawron?= Date: Sun, 5 May 2024 21:42:45 +0200 Subject: [PATCH] feat: add chatbot - model with name --- chatbot/config.json | 3 +++ chatbot/data/intents.json | 12 ++++++++++ chatbot/data/response.json | 11 +++++++++ chatbot/main.py | 32 +++++++++++++++++++++++++++ chatbot/modules/generator.py | 4 ++++ chatbot/modules/nlp.py | 38 ++++++++++++++++++++++++++++++++ chatbot/modules/state_monitor.py | 6 +++++ chatbot/modules/strategy.py | 7 ++++++ 8 files changed, 113 insertions(+) create mode 100644 chatbot/config.json create mode 100644 chatbot/data/intents.json create mode 100644 chatbot/data/response.json create mode 100644 chatbot/main.py create mode 100644 chatbot/modules/generator.py create mode 100644 chatbot/modules/nlp.py create mode 100644 chatbot/modules/state_monitor.py create mode 100644 chatbot/modules/strategy.py diff --git a/chatbot/config.json b/chatbot/config.json new file mode 100644 index 0000000..0567631 --- /dev/null +++ b/chatbot/config.json @@ -0,0 +1,3 @@ +{ + "data_path": "./data/intents.json" +} diff --git a/chatbot/data/intents.json b/chatbot/data/intents.json new file mode 100644 index 0000000..a12f1d5 --- /dev/null +++ b/chatbot/data/intents.json @@ -0,0 +1,12 @@ +{ + "name_query": [ + "jak masz na imię", + "jak się nazywasz", + "twoje imię", + "jak mogę cię wołać", + "jak do ciebie mówić", + "jak cię zwać", + "jak cię nazywać", + "jak masz na imie" + ] +} \ No newline at end of file diff --git a/chatbot/data/response.json b/chatbot/data/response.json new file mode 100644 index 0000000..a138516 --- /dev/null +++ b/chatbot/data/response.json @@ -0,0 +1,11 @@ +{ + "ask_name": [ + "Witaj, nazywam się Dia.", + "Cześć! Jestem Dia.", + "Hej, jestem Dia." + ], + "unknown": [ + "Przepraszam, nie rozumiem. Możesz to powtórzyć?", + "Nie jestem pewien, co masz na myśli. Czy możesz to wyjaśnić?" + ] +} diff --git a/chatbot/main.py b/chatbot/main.py new file mode 100644 index 0000000..5e59c27 --- /dev/null +++ b/chatbot/main.py @@ -0,0 +1,32 @@ +from modules.nlp import NaturalLanguageProcessor, Config +from modules.state_monitor import DialogueStateMonitor +from modules.strategy import DialogueStrategy +from modules.generator import NaturalLanguageGenerator +import colorama +from colorama import Fore, Style + +colorama.init(autoreset=True) + + +def chatbot_response(input_text: str, nlp: NaturalLanguageProcessor) -> str: + dialogue_monitor = DialogueStateMonitor() + analysis = nlp.analyze(input_text) + dialogue_monitor.update_state(analysis['intent']) + response = DialogueStrategy.decide_response(dialogue_monitor.state) + final_response = NaturalLanguageGenerator.generate(response) + + return final_response + + +if __name__ == "__main__": + config = Config() + nlp = NaturalLanguageProcessor(config) + print(Fore.YELLOW + "Wpisz 'quit' aby zakończyć program.\n") + + while True: + user_input = input(Fore.GREEN + "Ty: " + Style.RESET_ALL) + if user_input.lower() == "quit": + print(Fore.RED + "Zamykanie chatbota...") + break + + print(Fore.CYAN + "Bot: " + chatbot_response(user_input, nlp)) diff --git a/chatbot/modules/generator.py b/chatbot/modules/generator.py new file mode 100644 index 0000000..f78f792 --- /dev/null +++ b/chatbot/modules/generator.py @@ -0,0 +1,4 @@ +class NaturalLanguageGenerator: + @staticmethod + def generate(response: str) -> str: + return response diff --git a/chatbot/modules/nlp.py b/chatbot/modules/nlp.py new file mode 100644 index 0000000..0276df2 --- /dev/null +++ b/chatbot/modules/nlp.py @@ -0,0 +1,38 @@ +import json +import os +from typing import Any, Dict, Literal + + +class Config: + def __init__(self) -> None: + try: + config_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'config.json') + with open(config_path, 'r', encoding='utf-8') as config_file: + self.config_data: Dict[str, Any] = json.load(config_file) + except FileNotFoundError: + print("Config file not found.") + self.config_data = {} + except json.JSONDecodeError: + print("Invalid JSON.") + self.config_data = {} + + def get_data_path(self) -> str: + data_path = self.config_data.get('data_path', '') + if not isinstance(data_path, str): + raise ValueError("Data path must be a string.") + return os.path.join(os.path.dirname(os.path.dirname(__file__)), data_path) + + +class NaturalLanguageProcessor: + def __init__(self, config: Config) -> None: + self.config = config + data_path = self.config.get_data_path() + with open(data_path, 'r', encoding='utf-8') as file: + self.intents: Dict[str, Any] = json.load(file) + + def analyze(self, input_text: str) -> Dict[str, Literal['ask_name', 'unknown']]: + lower_text = input_text.lower() + for phrase in self.intents.get('name_query', []): + if phrase in lower_text: + return {"intent": "ask_name"} + return {"intent": "unknown"} diff --git a/chatbot/modules/state_monitor.py b/chatbot/modules/state_monitor.py new file mode 100644 index 0000000..56ca56a --- /dev/null +++ b/chatbot/modules/state_monitor.py @@ -0,0 +1,6 @@ +class DialogueStateMonitor: + def __init__(self) -> None: + self.state = {'last_intent': 'unknown'} + + def update_state(self, intent: str) -> None: + self.state['last_intent'] = intent diff --git a/chatbot/modules/strategy.py b/chatbot/modules/strategy.py new file mode 100644 index 0000000..385741c --- /dev/null +++ b/chatbot/modules/strategy.py @@ -0,0 +1,7 @@ +class DialogueStrategy: + @staticmethod + def decide_response(state: dict) -> str: + if state['last_intent'] == 'ask_name': + return "Witaj, nazywam się Dia." + else: + return "Przepraszam, nie rozumiem. Możesz to powtórzyć?"