feat: add chatbot - model with name

This commit is contained in:
Mikołaj Gawron 2024-05-05 21:42:45 +02:00
parent 3e16a0a2ee
commit e19e88ace9
8 changed files with 113 additions and 0 deletions

3
chatbot/config.json Normal file
View File

@ -0,0 +1,3 @@
{
"data_path": "./data/intents.json"
}

12
chatbot/data/intents.json Normal file
View File

@ -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"
]
}

View File

@ -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ć?"
]
}

32
chatbot/main.py Normal file
View File

@ -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))

View File

@ -0,0 +1,4 @@
class NaturalLanguageGenerator:
@staticmethod
def generate(response: str) -> str:
return response

38
chatbot/modules/nlp.py Normal file
View File

@ -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"}

View File

@ -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

View File

@ -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ć?"