diff --git a/actions/__pycache__/actions.cpython-310.pyc b/actions/__pycache__/actions.cpython-310.pyc index a9ce39a6d0ada2182ecddbd9e534e516856060dd..f5ed2efd0528945d1a94ab2f124d919e7cf84b32 100644 Binary files a/actions/__pycache__/actions.cpython-310.pyc and b/actions/__pycache__/actions.cpython-310.pyc differ diff --git a/actions/__pycache__/get_genres.cpython-310.pyc b/actions/__pycache__/get_genres.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5f5bb9fc3570386acbb0ab2181262fbaf2661fd7 Binary files /dev/null and b/actions/__pycache__/get_genres.cpython-310.pyc differ diff --git a/actions/__pycache__/get_movie_details.cpython-310.pyc b/actions/__pycache__/get_movie_details.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..189d03d2809b2d6573694d7a21267d081be66e30 Binary files /dev/null and b/actions/__pycache__/get_movie_details.cpython-310.pyc differ diff --git a/actions/__pycache__/get_movies.cpython-310.pyc b/actions/__pycache__/get_movies.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7c7f05ab99e0481814e71c09d946136b86d801df Binary files /dev/null and b/actions/__pycache__/get_movies.cpython-310.pyc differ diff --git a/actions/actions back up.txt b/actions/actions back up.txt new file mode 100644 index 0000000000000000000000000000000000000000..4ff195410de4410855b8cc6acf6b73dd5ee74819 --- /dev/null +++ b/actions/actions back up.txt @@ -0,0 +1,354 @@ +from typing import Any, Text, Dict, List +from rasa_sdk import Action, Tracker +from rasa_sdk.executor import CollectingDispatcher +import requests + +API_KEY = "9e7b704d5e4076508535d9ed2519e59b" +BASE_URL = "https://api.themoviedb.org/3" + +# Dynamische Filmempfehlung +class ActionFilmEmpfehlen(Action): + def name(self): + return "action_film_empfehlen" + + def run(self, dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict[Text, Any]) -> List[Dict[Text, Any]]: + genre = tracker.get_slot("film_genre") + + if not genre: + dispatcher.utter_message(text="Welches Filmgenre interessiert dich?") + return [] + + genre_mapping = { + "Action": 28, + "Komödie": 35, + "Romantik": 10749, + "Horror": 27, + "Thriller": 53, + "Sci-fi": 878, + "Fantasy": 14, + "Kinder": 16, + "Drama": 18 + } + + genre_id = genre_mapping.get(genre.lower()) + if not genre_id: + dispatcher.utter_message(text=f"Das Filmgenre '{genre}' kenne ich nicht.") + return [] + + url = f"{BASE_URL}/discover/movie?api_key={API_KEY}&with_genres={genre_id}" + response = requests.get(url) + + if response.status_code == 200: + filme = response.json().get("results", [])[:3] + if filme: + message = f"Hier sind einige Filme aus dem Genre {genre}:\n" + for film in filme: + message += f"- {film['title']} (Bewertung: {film['vote_average']})\n" + else: + message = f"Leider konnte ich keine Filme aus dem Genre {genre} finden." + else: + message = "Es gab ein Problem mit der Verbindung zur Film-Datenbank." + + dispatcher.utter_message(text=message) + return [] + +# Dynamische Serienempfehlung +class ActionSerieEmpfehlen(Action): + def name(self): + return "action_serie_empfehlen" + + def run(self, dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict[Text, Any]) -> List[Dict[Text, Any]]: + genre = tracker.get_slot("serie_genre") + + if not genre: + dispatcher.utter_message(text="Welches Seriengenre interessiert dich?") + return [] + + genre_mapping = { + "action": 28, + "komödie": 35, + "romantik": 10749, + "horror": 27, + "thriller": 53, + "sci-fi": 878, + "fantasy": 14, + "kinder": 16, + "drama": 18 + } + + genre_id = genre_mapping.get(genre.lower()) + if not genre_id: + dispatcher.utter_message(text=f"Das Seriengenre '{genre}' kenne ich nicht.") + return [] + + url = f"{BASE_URL}/discover/tv?api_key={API_KEY}&with_genres={genre_id}" + response = requests.get(url) + + if response.status_code == 200: + serien = response.json().get("results", [])[:3] + if serien: + message = f"Hier sind einige Serien aus dem Genre {genre}:\n" + for serie in serien: + message += f"- {serie['name']} (Bewertung: {serie['vote_average']})\n" + else: + message = f"Leider konnte ich keine Serien aus dem Genre {genre} finden." + else: + message = "Es gab ein Problem mit der Verbindung zur Serien-Datenbank." + + dispatcher.utter_message(text=message) + return [] + +# Filme oder Serien nach Genre +class ActionEmpfehlungNachGenre(Action): + def name(self): + return "action_empfehlung_nach_genre" + + def run(self, dispatcher, tracker, domain): + # Genre und Typ (Film oder Serie) abrufen + film_genre = tracker.get_slot("film_genre") + serie_genre = tracker.get_slot("serie_genre") + + # Festlegen, ob es um Filme oder Serien geht + if film_genre: + genre = film_genre + content_type = "movie" + elif serie_genre: + genre = serie_genre + content_type = "tv" + else: + dispatcher.utter_message(text="Welches Genre interessiert dich?") + return [] + + # Genre-Mapping + genre_mapping = { + "Action": 28, + "Komödie": 35, + "Romantik": 10749, + "Horror": 27, + "Thriller": 53, + "Sci-fi": 878, + "Fantasy": 14, + "Kinder": 16, + "Drama": 18 + } + genre_id = genre_mapping.get(genre.lower()) + if not genre_id: + dispatcher.utter_message(text=f"Das Genre '{genre}' kenne ich nicht.") + return [] + + # API-Aufruf + url = f"{BASE_URL}/discover/{content_type}?api_key={API_KEY}&with_genres={genre_id}" + response = requests.get(url) + if response.status_code == 200: + items = response.json().get("results", [])[:3] + if items: + message = f"Hier sind einige Empfehlungen im Genre {genre} ({'Filme' if content_type == 'movie' else 'Serien'}):\n" + for item in items: + message += f"- {item['title' if content_type == 'movie' else 'name']} (Bewertung: {item['vote_average']})\n" + else: + message = f"Leider konnte ich keine Inhalte im Genre {genre} finden." + else: + message = "Es gab ein Problem mit der Verbindung zur Film-Datenbank." + + dispatcher.utter_message(text=message) + return [] + + +# Empfehlungen nach Streamingdienst +class ActionEmpfehlungNachStreamingdienst(Action): + def name(self): + return "action_empfehlung_nach_streamingdienst" + + def run(self, dispatcher, tracker, domain): + streamingdienst = tracker.get_slot("streamingdienst") + if not streamingdienst: + dispatcher.utter_message(text="Bitte nenne mir einen Streamingdienst.") + return [] + + provider_mapping = {"netflix": 8, "prime": 9, "disney+": 337} + provider_id = provider_mapping.get(streamingdienst.lower()) + if not provider_id: + dispatcher.utter_message(text=f"Ich kenne den Streamingdienst '{streamingdienst}' nicht.") + return [] + + url = f"{BASE_URL}/discover/movie?api_key={API_KEY}&with_watch_providers={provider_id}&watch_region=DE" + response = requests.get(url) + if response.status_code == 200: + filme = response.json().get("results", [])[:3] + if filme: + message = f"Hier sind Filme auf {streamingdienst}:\n" + for film in filme: + message += f"- {film['title']} (Bewertung: {film['vote_average']})\n" + else: + message = f"Ich konnte keine passenden Filme auf {streamingdienst} finden." + else: + message = "Es gab ein Problem mit der Verbindung zur TMDb-API." + + dispatcher.utter_message(text=message) + return [] + +# Details zu einem Film +class ActionFilmDetails(Action): + def name(self): + return "action_film_details" + + def run(self, dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict[Text, Any]) -> List[Dict[Text, Any]]: + film_name = tracker.get_slot("film_name") + + if not film_name: + dispatcher.utter_message(text="Bitte gib mir den Namen des Films, zu dem du Details suchst.") + return [] + + search_url = f"{BASE_URL}/search/movie?api_key={API_KEY}&query={film_name}" + response = requests.get(search_url) + + if response.status_code == 200: + results = response.json().get("results", []) + if results: + film_id = results[0]["id"] + detail_url = f"{BASE_URL}/movie/{film_id}?api_key={API_KEY}" + detail_response = requests.get(detail_url) + + if detail_response.status_code == 200: + details = detail_response.json() + message = f"Hier sind die Details zu '{film_name}':\n" + message += f"Titel: {details['title']}\n" + message += f"Bewertung: {details['vote_average']}\n" + message += f"Beschreibung: {details['overview']}\n" + else: + message = f"Ich konnte keine weiteren Details zu '{film_name}' finden." + else: + message = f"Ich konnte keinen Film mit dem Namen '{film_name}' finden." + else: + message = "Es gab ein Problem mit der Verbindung zur Film-Datenbank." + + dispatcher.utter_message(text=message) + return [] + +class ActionSerieDetails(Action): + def name(self): + return "action_serie_details" + + def run(self, dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict[Text, Any]) -> List[Dict[Text, Any]]: + serie_name = tracker.get_slot("serie_name") + + if not serie_name: + dispatcher.utter_message(text="Bitte gib mir den Namen der Serie, zu der du Details suchst.") + return [] + + search_url = f"{BASE_URL}/search/tv?api_key={API_KEY}&query={serie_name}" + response = requests.get(search_url) + + if response.status_code == 200: + results = response.json().get("results", []) + if results: + serie_id = results[0]["id"] + detail_url = f"{BASE_URL}/tv/{serie_id}?api_key={API_KEY}" + detail_response = requests.get(detail_url) + + if detail_response.status_code == 200: + details = detail_response.json() + message = f"Hier sind die Details zu '{serie_name}':\n" + message += f"Titel: {details['name']}\n" + message += f"Bewertung: {details['vote_average']}\n" + message += f"Beschreibung: {details['overview']}\n" + else: + message = f"Ich konnte keine weiteren Details zu '{serie_name}' finden." + else: + message = f"Ich konnte keine Serie mit dem Namen '{serie_name}' finden." + else: + message = "Es gab ein Problem mit der Verbindung zur Serien-Datenbank." + + dispatcher.utter_message(text=message) + return [] + + +# Beliebte Inhalte (Filme und Serien) +class ActionWasIstBeliebt(Action): + def name(self): + return "action_was_ist_beliebt" + + def run(self, dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict[Text, Any]) -> List[Dict[Text, Any]]: + # API-Aufruf für beliebte Filme + url_movies = f"{BASE_URL}/trending/movie/day?api_key={API_KEY}" + response_movies = requests.get(url_movies) + + # API-Aufruf für beliebte Serien + url_series = f"{BASE_URL}/trending/tv/day?api_key={API_KEY}" + response_series = requests.get(url_series) + + if response_movies.status_code == 200 and response_series.status_code == 200: + popular_movies = response_movies.json().get("results", [])[:3] + popular_series = response_series.json().get("results", [])[:3] + + message = "Hier sind die aktuell beliebtesten Inhalte:\n\n" + + if popular_movies: + message += "Beliebte Filme:\n" + for movie in popular_movies: + message += f"- {movie['title']} (Bewertung: {movie['vote_average']})\n" + else: + message += "Keine beliebten Filme gefunden.\n" + + message += "\n" + + if popular_series: + message += "Beliebte Serien:\n" + for series in popular_series: + message += f"- {series['name']} (Bewertung: {series['vote_average']})\n" + else: + message += "Keine beliebten Serien gefunden.\n" + else: + message = "Es gab ein Problem mit der Verbindung zur Film- und Serien-Datenbank." + + dispatcher.utter_message(text=message) + return [] + + +# Filmklassiker empfehlen +class ActionFilmklassikerEmpfehlen(Action): + def name(self): + return "action_filmklassiker_empfehlen" + + def run(self, dispatcher, tracker, domain): + # Filme mit hohem Rating und älterem Veröffentlichungsdatum + url = f"{BASE_URL}/discover/movie?api_key={API_KEY}&sort_by=vote_average.desc&vote_count.gte=1000&release_date.lte=2000-01-01" + + response = requests.get(url) + if response.status_code == 200: + filme = response.json().get("results", [])[:3] + if filme: + message = "Hier sind einige zeitlose Filmklassiker:\n" + for film in filme: + message += f"- {film['title']} (Bewertung: {film['vote_average']}, Erscheinungsdatum: {film['release_date']})\n" + else: + message = "Ich konnte keine passenden Klassiker finden." + else: + message = "Es gab ein Problem mit der Verbindung zur TMDb-API." + + dispatcher.utter_message(text=message) + return [] + +# Aktuelle Kinohits anzeigen +class ActionAktuelleKinohits(Action): + def name(self): + return "action_aktuelle_kinohits" + + def run(self, dispatcher, tracker, domain): + # Filme, die aktuell in den Kinos laufen + url = f"{BASE_URL}/movie/now_playing?api_key={API_KEY}®ion=DE" + + response = requests.get(url) + if response.status_code == 200: + filme = response.json().get("results", [])[:3] + if filme: + message = "Hier sind einige aktuelle Kinohits:\n" + for film in filme: + message += f"- {film['title']} (Bewertung: {film['vote_average']}, Erscheinungsdatum: {film['release_date']})\n" + else: + message = "Ich konnte keine aktuellen Kinohits finden." + else: + message = "Es gab ein Problem mit der Verbindung zur TMDb-API." + + dispatcher.utter_message(text=message) + return [] diff --git a/actions/actions.py b/actions/actions.py index 59d375a884a4331b34315ea0dd450fb89f7d756d..49a66602f39b7421223ba7989383ec0b7df34009 100644 --- a/actions/actions.py +++ b/actions/actions.py @@ -1,219 +1,288 @@ from typing import Any, Text, Dict, List from rasa_sdk import Action, Tracker from rasa_sdk.executor import CollectingDispatcher -from rasa_sdk.events import SlotSet import requests API_KEY = "9e7b704d5e4076508535d9ed2519e59b" BASE_URL = "https://api.themoviedb.org/3" -# Dynamische Filmempfehlung + +# Hilfsfunktionen +def fetch_data_from_tmdb(endpoint: str, params: dict) -> dict: + """ + Führt einen API-Aufruf zu TMDb durch. + + :param endpoint: Der Endpoint der TMDb-API + :param params: Query-Parameter für den Aufruf + :return: JSON-Antwort als Dictionary + """ + params["api_key"] = API_KEY + response = requests.get(f"{BASE_URL}/{endpoint}", params=params) + if response.status_code == 200: + return response.json() + return {"error": f"Fehler: {response.status_code} - {response.text}"} + +def get_random_movies_or_series(content_type="movie", language="de") -> List[Dict]: + """ + Ruft zufällige Filme oder Serien ab. + + :param content_type: "movie" für Filme, "tv" für Serien + :param language: Sprache der Ergebnisse + :return: Liste der Inhalte + """ + endpoint = f"discover/{content_type}" + params = {"language": language, "sort_by": "popularity.desc"} + data = fetch_data_from_tmdb(endpoint, params) + return data.get("results", []) if "error" not in data else [] + +def get_movies_or_series_by_genre(genre_id: int, content_type="movie", language="de") -> List[Dict]: + """ + Ruft Inhalte basierend auf einem Genre ab. + + :param genre_id: ID des Genres + :param content_type: "movie" für Filme, "tv" für Serien + :param language: Sprache der Ergebnisse + :return: Liste der Inhalte + """ + endpoint = f"discover/{content_type}" + params = {"language": language, "with_genres": genre_id} + data = fetch_data_from_tmdb(endpoint, params) + return data.get("results", []) if "error" not in data else [] + +def get_classic_movies(before_date="1980-01-01", language="de") -> List[Dict]: + """ + Ruft klassische Filme ab, die vor einem bestimmten Datum veröffentlicht wurden. + + :param before_date: Veröffentlichungsdatum (z. B. "1980-01-01") + :param language: Sprache der Ergebnisse + :return: Liste der klassischen Filme + """ + endpoint = "discover/movie" + params = { + "language": language, + "sort_by": "release_date.asc", + "release_date.lte": before_date + } + data = fetch_data_from_tmdb(endpoint, params) + return data.get("results", []) if "error" not in data else [] + +def get_current_movies(start_date, end_date, language="de") -> List[Dict]: + """ + Ruft aktuelle Filme ab, die in einem bestimmten Zeitraum veröffentlicht wurden. + + :param start_date: Startdatum des Zeitraums (z. B. "2024-01-01") + :param end_date: Enddatum des Zeitraums (z. B. "2024-12-31") + :param language: Sprache der Ergebnisse + :return: Liste der aktuellen Filme + """ + endpoint = "discover/movie" + params = { + "language": language, + "sort_by": "popularity.desc", + "release_date.gte": start_date, + "release_date.lte": end_date + } + data = fetch_data_from_tmdb(endpoint, params) + return data.get("results", []) if "error" not in data else [] + +def get_movies_by_streaming_provider(provider_id, language="de", region="DE") -> List[Dict]: + """ + Ruft Filme ab, die auf einem bestimmten Streamingdienst verfügbar sind. + + :param provider_id: TMDb-Provider-ID des Streamingdienstes (z. B. 8 für Netflix) + :param language: Sprache der Ergebnisse + :param region: Region für die Verfügbarkeit (z. B. "DE") + :return: Liste der Filme + """ + endpoint = "discover/movie" + params = { + "language": language, + "with_watch_providers": provider_id, + "watch_region": region + } + data = fetch_data_from_tmdb(endpoint, params) + return data.get("results", []) if "error" not in data else [] + +# Actions class ActionFilmEmpfehlen(Action): def name(self): return "action_film_empfehlen" - def run(self, dispatcher, tracker, domain): - url = f"{BASE_URL}/movie/popular?api_key={API_KEY}" - - response = requests.get(url) - if response.status_code == 200: - filme = response.json().get("results", [])[:3] - if filme: - message = "Hier sind einige Filme, die ich empfehlen kann:\n" - for film in filme: - message += f"- {film['title']} (Bewertung: {film['vote_average']})\n" - else: - message = "Ich konnte keine passenden Filme finden." + def run(self, dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict[Text, Any]) -> List[Dict[Text, Any]]: + filme = get_random_movies_or_series("movie")[:5] + if filme: + message = "Hier sind einige Filme, die ich empfehlen kann:\n" + for film in filme: + message += f"- {film['title']} (Bewertung: {film['vote_average']})\n" else: - message = "Es gab ein Problem mit der Verbindung zur TMDb-API." + message = "Ich konnte leider keine Filme finden." dispatcher.utter_message(text=message) return [] -# Dynamische Serienempfehlung class ActionSerieEmpfehlen(Action): def name(self): return "action_serie_empfehlen" - def run(self, dispatcher, tracker, domain): - url = f"{BASE_URL}/tv/popular?api_key={API_KEY}" - - response = requests.get(url) - if response.status_code == 200: - serien = response.json().get("results", [])[:3] - if serien: - message = "Hier sind einige Serien, die ich empfehlen kann:\n" - for serie in serien: - message += f"- {serie['name']} (Bewertung: {serie['vote_average']})\n" - else: - message = "Ich konnte keine passenden Serien finden." + def run(self, dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict[Text, Any]) -> List[Dict[Text, Any]]: + serien = get_random_movies_or_series("tv")[:5] + if serien: + message = "Hier sind einige Serien, die ich empfehlen kann:\n" + for serie in serien: + message += f"- {serie['name']} (Bewertung: {serie['vote_average']})\n" else: - message = "Es gab ein Problem mit der Verbindung zur TMDb-API." + message = "Ich konnte leider keine Serien finden." dispatcher.utter_message(text=message) return [] -# Filme oder Serien nach Genre class ActionEmpfehlungNachGenre(Action): def name(self): return "action_empfehlung_nach_genre" - def run(self, dispatcher, tracker, domain): - genre = tracker.get_slot("film_genre") or tracker.get_slot("serie_genre") + def run(self, dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict[Text, Any]) -> List[Dict[Text, Any]]: + genre = tracker.get_slot("genre") if not genre: - dispatcher.utter_message(text="Bitte nenne mir ein Genre.") + dispatcher.utter_message(text="Bitte gib ein Genre an.") return [] - genre_mapping = {"action": 28, "comedy": 35, "drama": 18} + genre_mapping = {"action": 28, "komödie": 35, "thriller": 53, "drama": 18} genre_id = genre_mapping.get(genre.lower()) + if not genre_id: - dispatcher.utter_message(text=f"Das Genre '{genre}' kenne ich nicht.") + dispatcher.utter_message(text=f"Das Genre '{genre}' kenne ich leider nicht.") return [] - url = f"{BASE_URL}/discover/movie?api_key={API_KEY}&with_genres={genre_id}" - response = requests.get(url) - if response.status_code == 200: - filme = response.json().get("results", [])[:3] - if filme: - message = f"Hier sind einige {genre}-Filme, die ich empfehlen kann:\n" - for film in filme: - message += f"- {film['title']} (Bewertung: {film['vote_average']})\n" - else: - message = f"Ich konnte keine passenden {genre}-Filme finden." + movies = get_movies_or_series_by_genre(genre_id, "movie") + if movies: + message = f"Hier sind einige Filme im Genre {genre}:\n" + for movie in movies[:5]: + message += f"- {movie['title']} (Bewertung: {movie['vote_average']})\n" else: - message = "Es gab ein Problem mit der Verbindung zur TMDb-API." + message = f"Ich konnte keine Filme im Genre {genre} finden." dispatcher.utter_message(text=message) return [] -# Empfehlungen nach Streamingdienst -class ActionEmpfehlungNachStreamingdienst(Action): - def name(self): - return "action_empfehlung_nach_streamingdienst" - def run(self, dispatcher, tracker, domain): - streamingdienst = tracker.get_slot("streamingdienst") - if not streamingdienst: - dispatcher.utter_message(text="Bitte nenne mir einen Streamingdienst.") - return [] - provider_mapping = {"netflix": 8, "prime": 9, "disney+": 337} - provider_id = provider_mapping.get(streamingdienst.lower()) - if not provider_id: - dispatcher.utter_message(text=f"Ich kenne den Streamingdienst '{streamingdienst}' nicht.") - return [] +class ActionWasIstBeliebt(Action): + def name(self): + return "action_was_ist_beliebt" - url = f"{BASE_URL}/discover/movie?api_key={API_KEY}&with_watch_providers={provider_id}&watch_region=DE" - response = requests.get(url) - if response.status_code == 200: - filme = response.json().get("results", [])[:3] - if filme: - message = f"Hier sind Filme auf {streamingdienst}:\n" - for film in filme: - message += f"- {film['title']} (Bewertung: {film['vote_average']})\n" - else: - message = f"Ich konnte keine passenden Filme auf {streamingdienst} finden." + def run(self, dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict[Text, Any]) -> List[Dict[Text, Any]]: + content_type = tracker.get_slot("content_type") or "movie" + beliebte_inhalte = get_random_movies_or_series(content_type)[:5] + if beliebte_inhalte: + message = f"Hier sind einige beliebte {content_type}s:\n" + for inhalt in beliebte_inhalte: + title_key = "title" if content_type == "movie" else "name" + message += f"- {inhalt[title_key]} (Bewertung: {inhalt['vote_average']})\n" else: - message = "Es gab ein Problem mit der Verbindung zur TMDb-API." + message = f"Ich konnte keine beliebten {content_type}s finden." dispatcher.utter_message(text=message) return [] -# Details zu einem Film class ActionFilmDetails(Action): def name(self): return "action_film_details" - def run(self, dispatcher, tracker, domain): + def run(self, dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict[Text, Any]) -> List[Dict[Text, Any]]: film_name = tracker.get_slot("film_name") if not film_name: - dispatcher.utter_message(text="Bitte nenne mir den Namen des Films.") + dispatcher.utter_message(text="Bitte nenne den Namen des Films, zu dem du Details suchst.") return [] - search_url = f"{BASE_URL}/search/movie?api_key={API_KEY}&query={film_name}" - search_response = requests.get(search_url) - if search_response.status_code == 200: - results = search_response.json().get("results", []) - if results: - film = results[0] - message = f"Hier sind Details zu '{film['title']}':\n" - message += f"- Erscheinungsdatum: {film['release_date']}\n" - message += f"- Bewertung: {film['vote_average']}\n" - message += f"- Beschreibung: {film['overview']}" - else: - message = f"Ich konnte keinen Film mit dem Namen '{film_name}' finden." - else: - message = "Es gab ein Problem mit der Verbindung zur TMDb-API." + search_results = fetch_data_from_tmdb("search/movie", {"query": film_name, "language": "de"}) + if "error" in search_results or not search_results.get("results"): + dispatcher.utter_message(text=f"Ich konnte keinen Film mit dem Namen '{film_name}' finden.") + return [] + film = search_results["results"][0] + message = f"Details zu '{film['title']}':\n- Bewertung: {film['vote_average']}\n- Beschreibung: {film['overview']}" dispatcher.utter_message(text=message) return [] -# Beliebte Inhalte (Filme und Serien) -class ActionWasIstBeliebt(Action): +class ActionSerieDetails(Action): def name(self): - return "action_was_ist_beliebt" + return "action_serie_details" - def run(self, dispatcher, tracker, domain): - url = f"{BASE_URL}/trending/movie/day?api_key={API_KEY}" - response = requests.get(url) - if response.status_code == 200: - filme = response.json().get("results", [])[:3] - if filme: - message = "Hier sind die aktuell beliebtesten Filme:\n" - for film in filme: - message += f"- {film['title']} (Bewertung: {film['vote_average']})\n" - else: - message = "Ich konnte keine beliebten Filme finden." - else: - message = "Es gab ein Problem mit der Verbindung zur TMDb-API." + def run(self, dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict[Text, Any]) -> List[Dict[Text, Any]]: + serie_name = tracker.get_slot("serie_name") + if not serie_name: + dispatcher.utter_message(text="Bitte nenne den Namen der Serie, zu der du Details suchst.") + return [] + search_results = fetch_data_from_tmdb("search/tv", {"query": serie_name, "language": "de"}) + if "error" in search_results or not search_results.get("results"): + dispatcher.utter_message(text=f"Ich konnte keine Serie mit dem Namen '{serie_name}' finden.") + return [] + + serie = search_results["results"][0] + message = f"Details zu '{serie['name']}':\n- Bewertung: {serie['vote_average']}\n- Beschreibung: {serie['overview']}" dispatcher.utter_message(text=message) return [] -# Filmklassiker empfehlen class ActionFilmklassikerEmpfehlen(Action): def name(self): return "action_filmklassiker_empfehlen" - def run(self, dispatcher, tracker, domain): - # Filme mit hohem Rating und älterem Veröffentlichungsdatum - url = f"{BASE_URL}/discover/movie?api_key={API_KEY}&sort_by=vote_average.desc&vote_count.gte=1000&release_date.lte=2000-01-01" - - response = requests.get(url) - if response.status_code == 200: - filme = response.json().get("results", [])[:3] - if filme: - message = "Hier sind einige zeitlose Filmklassiker:\n" - for film in filme: - message += f"- {film['title']} (Bewertung: {film['vote_average']}, Erscheinungsdatum: {film['release_date']})\n" - else: - message = "Ich konnte keine passenden Klassiker finden." + def run(self, dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict[Text, Any]) -> List[Dict[Text, Any]]: + klassiker = get_classic_movies(before_date="1980-01-01") + if klassiker: + message = "Hier sind einige Filmklassiker:\n" + for film in klassiker[:5]: + message += f"- {film['title']} (Veröffentlicht: {film.get('release_date', 'N/A')})\n" else: - message = "Es gab ein Problem mit der Verbindung zur TMDb-API." - + message = "Ich konnte keine Filmklassiker finden." dispatcher.utter_message(text=message) return [] -# Aktuelle Kinohits anzeigen class ActionAktuelleKinohits(Action): def name(self): return "action_aktuelle_kinohits" - def run(self, dispatcher, tracker, domain): - # Filme, die aktuell in den Kinos laufen - url = f"{BASE_URL}/movie/now_playing?api_key={API_KEY}®ion=DE" - - response = requests.get(url) - if response.status_code == 200: - filme = response.json().get("results", [])[:3] - if filme: - message = "Hier sind einige aktuelle Kinohits:\n" - for film in filme: - message += f"- {film['title']} (Bewertung: {film['vote_average']}, Erscheinungsdatum: {film['release_date']})\n" - else: - message = "Ich konnte keine aktuellen Kinohits finden." + def run(self, dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict[Text, Any]) -> List[Dict[Text, Any]]: + kinohits = get_current_movies(start_date="2024-01-01", end_date="2024-12-31") + if kinohits: + message = "Hier sind die aktuellen Kinohits:\n" + for film in kinohits[:5]: + message += f"- {film['title']} (Bewertung: {film['vote_average']}, Release: {film.get('release_date', 'N/A')})\n" + else: + message = "Ich konnte keine aktuellen Kinohits finden." + dispatcher.utter_message(text=message) + return [] + +class ActionEmpfehlungNachStreamingdienst(Action): + def name(self): + return "action_empfehlung_nach_streamingdienst" + + def run(self, dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict[Text, Any]) -> List[Dict[Text, Any]]: + streamingdienst = tracker.get_slot("streamingdienst") + if not streamingdienst: + dispatcher.utter_message(text="Bitte nenne einen Streamingdienst, nach dem ich suchen soll.") + return [] + + provider_mapping = { + "netflix": 8, + "amazon prime": 9, + "disney+": 337, + "hbo max": 384, + "apple tv+": 350 + } + provider_id = provider_mapping.get(streamingdienst.lower()) + if not provider_id: + dispatcher.utter_message(text=f"Ich kenne den Streamingdienst '{streamingdienst}' nicht.") + return [] + + filme = get_movies_by_streaming_provider(provider_id) + if filme: + message = f"Hier sind Filme, die auf {streamingdienst} verfügbar sind:\n" + for film in filme[:5]: + message += f"- {film['title']} (Bewertung: {film['vote_average']})\n" else: - message = "Es gab ein Problem mit der Verbindung zur TMDb-API." + message = f"Ich konnte keine Filme auf {streamingdienst} finden." dispatcher.utter_message(text=message) return [] diff --git a/actions/get_genres.py b/actions/get_genres.py new file mode 100644 index 0000000000000000000000000000000000000000..6f8933bce81c6790ef529f9877dcfc6130106766 --- /dev/null +++ b/actions/get_genres.py @@ -0,0 +1,36 @@ +import requests + +# Dein API-Key hier einfügen +API_KEY = "9e7b704d5e4076508535d9ed2519e59b" + +def get_genres(content_type="movie", language="de"): + """ + Ruft die Genres von TMDb ab. + + :param content_type: "movie" für Filme, "tv" für Serien + :param language: Sprache für die Ausgabe (z. B. "de" für Deutsch) + :return: Liste der Genres mit ID und Name + """ + url = f"https://api.themoviedb.org/3/genre/{content_type}/list" + params = {"api_key": API_KEY, "language": language} + + response = requests.get(url, params=params) + + if response.status_code == 200: + genres = response.json().get("genres", []) + return genres + else: + print(f"Fehler: {response.status_code} - {response.text}") + return [] + +# Test: Genres abrufen +if __name__ == "__main__": + movie_genres = get_genres("movie") + print("Genres für Filme:") + for genre in movie_genres: + print(f"{genre['id']}: {genre['name']}") + + tv_genres = get_genres("tv") + print("\nGenres für Serien:") + for genre in tv_genres: + print(f"{genre['id']}: {genre['name']}") diff --git a/actions/get_movie_details.py b/actions/get_movie_details.py new file mode 100644 index 0000000000000000000000000000000000000000..8e5eeb999ab043d026c5608d8fb15666b6f7c6e7 --- /dev/null +++ b/actions/get_movie_details.py @@ -0,0 +1,32 @@ +import requests + +# Deinen persönlichen API-Key hier einfügen +API_KEY = "9e7b704d5e4076508535d9ed2519e59b" + +def get_movie_details(movie_id, language="de"): + """ + Ruft Details zu einem Film basierend auf seiner ID ab. + + :param movie_id: ID des Films + :param language: Sprache für die Ausgabe + :return: Details des Films + """ + url = f"https://api.themoviedb.org/3/movie/{movie_id}" + params = {"api_key": API_KEY, "language": language} # Parameter mit API-Key + + response = requests.get(url, params=params) + + if response.status_code == 200: + return response.json() + else: + print(f"Fehler: {response.status_code} - {response.text}") + return {} + +# Test: Details zu einem Film abrufen +if __name__ == "__main__": + movie_id = 550 # Beispiel: Fight Club + details = get_movie_details(movie_id) + print(f"Details zu '{details.get('title', 'Unbekannt')}':") + print(f"Beschreibung: {details.get('overview', 'Keine Beschreibung verfügbar')}") + print(f"Bewertung: {details.get('vote_average', 'N/A')}") + diff --git a/actions/get_movies.py b/actions/get_movies.py new file mode 100644 index 0000000000000000000000000000000000000000..9a333195a8081db8506f619ec3f6ac8310e49a33 --- /dev/null +++ b/actions/get_movies.py @@ -0,0 +1,38 @@ +import requests + +# Dein API-Key hier einfügen +API_KEY = "9e7b704d5e4076508535d9ed2519e59b" + +def get_movies_by_genre(genre_id, content_type="movie", language="de"): + """ + Ruft Filme oder Serien basierend auf einem Genre ab. + + :param genre_id: ID des Genres + :param content_type: "movie" für Filme, "tv" für Serien + :param language: Sprache für die Ausgabe + :return: Liste der Ergebnisse + """ + url = f"https://api.themoviedb.org/3/discover/{content_type}" + params = { + "api_key": API_KEY, + "language": language, + "with_genres": genre_id + } + + response = requests.get(url, params=params) + + if response.status_code == 200: + results = response.json().get("results", []) + return results + else: + print(f"Fehler: {response.status_code} - {response.text}") + return [] + +# Test: Filme abrufen +if __name__ == "__main__": + genre_id = 35 # Komödie (siehe get_genres.py) + movies = get_movies_by_genre(genre_id, "movie") + + print("Filme im Genre Komödie:") + for movie in movies[:10]: # Zeige nur die ersten 10 Filme + print(f"{movie['title']} (Release: {movie.get('release_date', 'N/A')})") diff --git a/config.yml b/config.yml index a21a9ee711e67cacc55101dc7d2c3fe81d926bd2..03c483df9375517be5bd2e92b3c346239087a54b 100644 --- a/config.yml +++ b/config.yml @@ -1,50 +1,37 @@ -# The config recipe. -# https://rasa.com/docs/rasa/model-configuration/ recipe: default.v1 -# The assistant project unique identifier -# This default value must be replaced with a unique assistant name within your deployment -assistant_id: 20241127-202549-narrow-border +language: de -# Configuration for Rasa NLU. -# https://rasa.com/docs/rasa/nlu/components/ -language: en +pipeline: + - name: WhitespaceTokenizer + - name: RegexFeaturizer + - name: LexicalSyntacticFeaturizer + - name: CountVectorsFeaturizer + - name: CountVectorsFeaturizer + analyzer: char_wb + min_ngram: 1 + max_ngram: 4 + - name: DIETClassifier + epochs: 100 + constrain_similarities: true + - name: EntitySynonymMapper + + +policies: + - name: MemoizationPolicy + max_history: 5 + - name: RulePolicy + core_fallback_threshold: 0.4 + nlu_threshold: 0.4 + enable_fallback_prediction: true + - name: TEDPolicy + max_history: 5 + epochs: 100 + constrain_similarities: true + - name: UnexpecTEDIntentPolicy + max_history: 5 + epochs: 100 + +assistant_id: 20241213-215658-equidistant-hutch -pipeline: null -# # No configuration for the NLU pipeline was provided. The following default pipeline was used to train your model. -# # If you'd like to customize it, uncomment and adjust the pipeline. -# # See https://rasa.com/docs/rasa/tuning-your-model for more information. -# - name: WhitespaceTokenizer -# - name: RegexFeaturizer -# - name: LexicalSyntacticFeaturizer -# - name: CountVectorsFeaturizer -# - name: CountVectorsFeaturizer -# analyzer: char_wb -# min_ngram: 1 -# max_ngram: 4 -# - name: DIETClassifier -# epochs: 100 -# constrain_similarities: true -# - name: EntitySynonymMapper -# - name: ResponseSelector -# epochs: 100 -# constrain_similarities: true -# - name: FallbackClassifier -# threshold: 0.3 -# ambiguity_threshold: 0.1 -# Configuration for Rasa Core. -# https://rasa.com/docs/rasa/core/policies/ -policies: null -# # No configuration for policies was provided. The following default policies were used to train your model. -# # If you'd like to customize them, uncomment and adjust the policies. -# # See https://rasa.com/docs/rasa/policies for more information. -# - name: MemoizationPolicy -# - name: RulePolicy -# - name: UnexpecTEDIntentPolicy -# max_history: 5 -# epochs: 100 -# - name: TEDPolicy -# max_history: 5 -# epochs: 100 -# constrain_similarities: true diff --git a/data/nlu/nlu_basics.yml b/data/nlu/nlu_basics.yml index e17b815ddab537fd55953137278ae98f01c0f5ab..7da4b3b6965aba1e809ce7c2074b0f4b1711e358 100644 --- a/data/nlu/nlu_basics.yml +++ b/data/nlu/nlu_basics.yml @@ -360,7 +360,8 @@ nlu: - intent: frag_nach_fähigkeiten examples: | - - Was kannst du tun? + - Was genau kannst du? + - Was ist deine Aufgabe? - Kannst du mir etwas über deine Funktionen erzählen? - Welche Funktionen hast du? - Welche Dienstleistungen bietest du an? @@ -368,10 +369,8 @@ nlu: - Welche Aufgaben kannst du ausführen? - Kannst du deine Fähigkeiten erklären? - Was sind deine Stärken? - - Was kannst du nicht tun? - Was sind deine Grenzen? - Welche Aufgaben kannst du übernehmen? - - Was kannst du nicht leisten? - intent: frag_nach_zweck examples: | diff --git a/data/nlu/nlu_both.yml b/data/nlu/nlu_both.yml new file mode 100644 index 0000000000000000000000000000000000000000..8ad9f9c65017b5b650469c25acdebc80dd94cbc0 --- /dev/null +++ b/data/nlu/nlu_both.yml @@ -0,0 +1,30 @@ +version: "3.1" + +nlu: +- intent: frag_nach_streamingdienst + examples: | + - Welche Filme gibt es auf [Netflix](streamingdienst)? + - Hast du Serien für [Amazon Prime](streamingdienst)? + - Gibt es gute Filme auf [Disney+](streamingdienst)? + - Was läuft aktuell auf [Sky](streamingdienst)? + - Kannst du mir etwas auf [Apple TV](streamingdienst) empfehlen? + - Gibt es Vorschläge für [HBO Max](streamingdienst)? + - Welche Serien sind auf [Joyn](streamingdienst) sehenswert? + +- intent: was_ist_beliebt + examples: | + - Was ist gerade beliebt? + - Welche Filme sind gerade im Trend? + - Welche Serien schauen die Leute aktuell? + - Gibt es derzeit einen Hype um bestimmte Filme? + - Was schauen gerade alle? + - Was ist ein Must-Watch? + +- intent: bewertung_hinterlassen + examples: | + - Der Film war großartig! + - Das hat mir gar nicht gefallen. + - Die Serie war okay, aber nicht überragend. + - Ich fand den Vorschlag super, danke! + - Ich mag solche Filme nicht. + - Kannst du mir etwas Ähnliches wie den letzten Film zeigen? diff --git a/data/nlu/nlu_movies.yml b/data/nlu/nlu_movies.yml new file mode 100644 index 0000000000000000000000000000000000000000..235bcad5a2ab530bbab8409edc7e1e3c31007155 --- /dev/null +++ b/data/nlu/nlu_movies.yml @@ -0,0 +1,61 @@ +version: "3.1" + +nlu: +- intent: film_empfehlen + examples: | + - Kannst du mir einen Film empfehlen? + - Ich suche einen guten Film. + - Hast du einen Filmvorschlag für mich? + - Welcher Film ist gerade sehenswert? + - Zeig mir einen spannenden Film. + - Was ist ein guter Film für heute Abend? + - Hast du Filmideen? + - Empfiehl mir einen Film. + - Was ist dein Lieblingsfilm? + + +- intent: frag_nach_film_details + examples: | + - Was kannst du mir über [Inception](film_name) sagen? + - Erzähl mir mehr über den Film [Titanic](film_name) + - Gib mir Details zu [Avatar](film_name) + - Kannst du mir Infos zu [The Matrix](film_name) geben? + - Was weißt du über [Interstellar](film_name)? + - Welche Informationen hast du zu [Parasite](film_name)? + - Erzähl mir etwas über den Film [Joker](film_name) + - Gibt es interessante Fakten zu [Pulp Fiction](film_name)? + - Ich möchte mehr über [The Godfather](film_name) erfahren. + - Was ist die Handlung von [Shutter Island](film_name)? + - Kannst du mir etwas über den Film [The Dark Knight](film_name) erzählen? + - Ich suche Details zu [Forrest Gump](film_name). + - Gibt es eine Beschreibung zu [La La Land](film_name)? + - Gibt es eine Inhaltsangabe für [Fight Club](film_name)? + + +- intent: filmklassiker_empfehlen + examples: | + - Kannst du mir Filmklassiker empfehlen? + - Welche alten Filme sind sehenswert? + - Zeig mir zeitlose Klassiker. + - Ich suche Kultfilme. + - Was sind die besten Klassiker? + +- intent: frag_nach_genre_film + examples: | + - Ich suche einen [Action](genre)film + - Gibt es [Science-Fiction](genre)filme, die du empfehlen kannst? + - Zeig mir eine [Komödie](genre) + - Welche [Horror](genre)filme sind aktuell? + - Kannst du mir [Romantik](genre)filme empfehlen? + - Gibt es gute [Thriller](genre)? + - Empfiehl mir eine [Komödie](genre) + - Welche [Fantasy](genre)filme laufen derzeit? + - Ich möchte einen [Dokumentarfilm](genre) sehen + - Hast du Empfehlungen für [Abenteuer](genre)filme? + - Nenne mir ein paar [Animationsfilme](genre) + - Gibt es neue [Western](genre)filme? + - Zeig mir eine Liste von [Krimi](genre)filmen + - Gibt es [Drama](genre)filme, die dir gefallen? + - Welche [Musicals](genre) kannst du mir empfehlen? + - Gibt es [Historienfilme](genre), die sehenswert sind? + diff --git a/data/nlu/nlu_movies_series.yml b/data/nlu/nlu_movies_series.yml deleted file mode 100644 index 7716e15918f2e0929c0ec5f2f2b418dd76f09f25..0000000000000000000000000000000000000000 --- a/data/nlu/nlu_movies_series.yml +++ /dev/null @@ -1,233 +0,0 @@ -version: "3.1" - -nlu: -- intent: film_empfehlen - examples: | - - Kannst du mir einen Film empfehlen? - - Ich suche einen guten Film. - - Hast du einen Filmvorschlag für mich? - - Welcher Film ist gerade sehenswert? - - Zeig mir einen spannenden Film. - - Was ist ein guter Film für heute Abend? - - Hast du Filmideen? - - Empfiehl mir einen Film. - - Was ist dein Lieblingsfilm? - -- intent: serie_empfehlen - examples: | - - Kannst du mir eine Serie empfehlen? - - Ich suche eine spannende Serie. - - Was sind gerade die besten Serien? - - Welche Serie kannst du empfehlen? - - Hast du Vorschläge für gute Serien? - - Empfiehl mir eine interessante Serie. - - Welche Serie passt zu mir? - - Welche Serien sind aktuell beliebt? - - Ich möchte eine neue Serie anfangen, hast du Tipps? - -- intent: frag_nach_genre - examples: | - - Hast du Komödien für mich? - - Welche Horrorfilme kannst du empfehlen? - - Zeig mir romantische Filme. - - Ich suche spannende Thriller. - - Welche Science-Fiction-Serien kannst du vorschlagen? - - Hast du etwas Lustiges für mich? - - Ich möchte etwas Actionreiches sehen. - - Gibt es gute Dramen? - - Welche Dokumentationen empfiehlst du? - -- intent: frag_nach_streamingdienst - examples: | - - Welche Filme gibt es auf Netflix? - - Hast du Serien für Amazon Prime? - - Gibt es gute Filme auf Disney+? - - Was läuft aktuell auf Sky? - - Kannst du mir etwas auf Apple TV empfehlen? - - Gibt es Vorschläge für HBO Max? - - Welche Serien sind auf Joyn sehenswert? - - Was läuft auf meinem Streamingdienst? - -- intent: frag_nach_film_details - examples: | - - Kannst du mir mehr über den Film erzählen? - - Worum geht es in diesem Film? - - Wer spielt in diesem Film mit? - - Ist der Film gut bewertet? - - Welche Genres hat dieser Film? - - Ist dieser Film auf Netflix verfügbar? - - Gibt es eine kurze Zusammenfassung des Films? - -- intent: frag_nach_serie_details - examples: | - - Wie viele Staffeln hat die Serie? - - Kannst du mir die Handlung der Serie erklären? - - Gibt es neue Folgen dieser Serie? - - Wer sind die Hauptdarsteller in dieser Serie? - - Welche Bewertung hat die Serie? - - Kann man die Serie auf Prime Video schauen? - -- intent: was_ist_beliebt - examples: | - - Was ist gerade beliebt? - - Welche Filme sind gerade im Trend? - - Welche Serien schauen die Leute aktuell? - - Gibt es derzeit einen Hype um bestimmte Filme? - - Was schauen gerade alle? - - Was ist ein Must-Watch? - -- intent: empfehlung_basierend_auf_favoriten - examples: | - - Ich mag "Breaking Bad", hast du ähnliche Serien? - - Ich liebe "Inception", was könnte mir noch gefallen? - - Kannst du mir etwas Ähnliches wie "Game of Thrones" empfehlen? - - Gibt es Filme wie "Interstellar"? - - Hast du Serien, die zu "Friends" passen? - - Ich mag Marvel-Filme, was kannst du dazu empfehlen? - -- intent: empfehlung_für_stimmung - examples: | - - Ich brauche etwas Lustiges. - - Ich suche einen emotionalen Film. - - Hast du etwas Spannendes? - - Ich bin in der Stimmung für eine romantische Serie. - - Gibt es etwas Inspirierendes? - - Hast du etwas für gute Laune? - - Was passt zu einer melancholischen Stimmung? - -- intent: empfehlung_für_alter - examples: | - - Hast du Filme für Kinder? - - Welche Serien sind gut für Teenager? - - Gibt es Filme für die ganze Familie? - - Kannst du etwas für Erwachsene empfehlen? - - Welche Filme eignen sich für Senioren? - -- intent: empfehlung_für_anlass - examples: | - - Was eignet sich für einen Familienabend? - - Hast du Tipps für einen Filmabend mit Freunden? - - Welche Serie passt für ein romantisches Date? - - Ich suche etwas für einen verregneten Sonntag. - - Gibt es Filme für eine Party? - - Hast du etwas für einen gemütlichen Abend alleine? - -### **Interaktive Funktionen** - -- intent: bewertung_hinterlassen - examples: | - - Der Film war großartig! - - Das hat mir gar nicht gefallen. - - Die Serie war okay, aber nicht überragend. - - Ich fand den Vorschlag super, danke! - - Ich mag solche Filme nicht. - - Kannst du mir etwas Ähnliches wie den letzten Film zeigen? - -- intent: vorschläge_bewerten - examples: | - - Der dritte Film klingt gut. - - Vorschlag Nummer zwei gefällt mir. - - Zeig mir mehr Filme wie den ersten. - - Die Serienempfehlung war perfekt. - - Kannst du mir andere Optionen zeigen? - - Ich mag die Auswahl nicht, hast du etwas anderes? - -- intent: frage_nach_mehr - examples: | - - Zeig mir mehr Filme. - - Hast du noch andere Vorschläge? - - Gibt es noch weitere Serien? - - Kannst du mir mehr Empfehlungen geben? - - Ich brauche mehr Optionen. - - Was hast du noch im Angebot? - -- intent: frage_nach_bewertungen - examples: | - - Wie ist der IMDb-Score dieses Films? - - Hat der Film gute Bewertungen? - - Wie wird diese Serie auf Rotten Tomatoes bewertet? - - Kannst du mir die Kritiken zeigen? - - Wie populär ist dieser Film? - -- intent: frage_nach_trailern - examples: | - - Gibt es einen Trailer zu diesem Film? - - Kannst du mir die Vorschau zeigen? - - Ich möchte den Trailer zu dieser Serie sehen. - - Hast du einen Link zu einem Trailer? - - Gibt es eine Vorschau? - -- intent: frage_nach_dauer - examples: | - - Wie lange dauert der Film? - - Wie viele Episoden hat die Serie? - - Ist der Film kurz oder lang? - - Wie lang ist die Serie insgesamt? - - Kannst du mir die Spielzeit nennen? - -- intent: frage_nach_verfügbarkeit - examples: | - - Wo kann ich den Film schauen? - - Auf welchem Streamingdienst ist die Serie verfügbar? - - Gibt es den Film auf Netflix? - - Ist diese Serie auf Prime Video? - - Wo finde ich diese Empfehlung? - -### **Problemlösung** -- intent: problem_mit_vorschlägen - examples: | - - Das Genre mag ich nicht. - - Ich habe keinen Zugang zu Netflix. - - Hast du Vorschläge für andere Plattformen? - - Diese Filme interessieren mich nicht. - - Die Serienauswahl passt nicht zu meinem Geschmack. - - Kannst du etwas anderes zeigen? - -- intent: fehler_melden - examples: | - - Dein System hat einen Fehler. - - Der Vorschlag war nicht korrekt. - - Ich habe Probleme mit deiner Antwort. - - Etwas funktioniert nicht richtig. - - Kann ich einen Fehler melden? - - Es gibt ein Problem mit deinen Empfehlungen. - -- intent: filmklassiker_empfehlen - examples: | - - Kannst du mir Filmklassiker empfehlen? - - Welche alten Filme sind sehenswert? - - Zeig mir zeitlose Klassiker. - - Ich suche Kultfilme. - - Was sind die besten Klassiker? - -- intent: neuveröffentlichungen_empfehlen - examples: | - - Welche neuen Filme gibt es? - - Hast du Tipps für aktuelle Serien? - - Was ist neu auf Netflix? - - Welche Neuerscheinungen kannst du empfehlen? - - Zeig mir die neuesten Filme und Serien. - -- intent: frage_nach_aktuellen_kinohits - examples: | - - Was läuft gerade im Kino? - - Gibt es aktuelle Kinohits? - - Welche Filme sind momentan in den Kinos beliebt? - - Zeig mir die besten Filme im Kino. - - Was lohnt sich im Kino anzusehen? - -- intent: frage_nach_award_gewinnern - examples: | - - Gibt es Empfehlungen für Oscar-Gewinner? - - Welche preisgekrönten Filme kannst du empfehlen? - - Hast du Serien, die Emmys gewonnen haben? - - Was sind die besten Award-Gewinner? - - Zeig mir Filme mit Auszeichnungen. - -- intent: empfehlung_für_mehrsprachige_inhalte - examples: | - - Gibt es Filme auf Spanisch? - - Kannst du Serien in Englisch empfehlen? - - Ich suche etwas auf Französisch. - - Welche Filme gibt es in Originalsprache? - - Hast du Vorschläge für fremdsprachige Inhalte? \ No newline at end of file diff --git a/data/nlu/nlu_series.yml b/data/nlu/nlu_series.yml new file mode 100644 index 0000000000000000000000000000000000000000..cafe1820737cf97a82f83f973eacc3bc4dbe0fc9 --- /dev/null +++ b/data/nlu/nlu_series.yml @@ -0,0 +1,88 @@ +version: "3.1" + +nlu: +- intent: serie_empfehlen + examples: | + - Kannst du mir eine Serie empfehlen? + - Ich suche eine spannende Serie. + - Was sind gerade die besten Serien? + - Welche Serie kannst du empfehlen? + - Hast du Vorschläge für gute Serien? + - Empfiehl mir eine interessante Serie. + - Welche Serie passt zu mir? + - Welche Serien sind aktuell beliebt? + - Ich möchte eine neue Serie anfangen, hast du Tipps? + +- intent: frag_nach_serie_details + examples: | + - Was kannst du mir über [Breaking Bad](serie_name) sagen? + - Erzähl mir mehr über die Serie [Game of Thrones](serie_name). + - Gib mir Details zu [Stranger Things](serie_name). + - Kannst du mir Infos zu [The Witcher](serie_name) geben? + - Was weißt du über [The Crown](serie_name)? + - Welche Informationen hast du zu [Dark](serie_name)? + - Erzähl mir etwas über die Serie [Friends](serie_name). + - Gibt es interessante Fakten zu [The Mandalorian](serie_name)? + - Ich möchte mehr über [The Office](serie_name) erfahren. + - Was ist die Handlung von [House of the Dragon](serie_name)? + - Kannst du mir etwas über die Serie [Vikings](serie_name) erzählen? + - Ich suche Details zu [Westworld](serie_name). + - Gibt es eine Beschreibung zu [The Boys](serie_name)? + - Gibt es eine Inhaltsangabe für [Sherlock](serie_name)? + - Ich brauche Infos zu [Better Call Saul](serie_name). + + +### **Problemlösung** + +- intent: fehler_melden + examples: | + - Dein System hat einen Fehler. + - Der Vorschlag war nicht korrekt. + - Ich habe Probleme mit deiner Antwort. + - Etwas funktioniert nicht richtig. + - Kann ich einen Fehler melden? + - Es gibt ein Problem mit deinen Empfehlungen. + + +- intent: neuveröffentlichungen_empfehlen + examples: | + - Welche neuen Filme gibt es? + - Hast du Tipps für aktuelle Serien? + - Was ist neu auf Netflix? + - Welche Neuerscheinungen kannst du empfehlen? + - Zeig mir die neuesten Filme und Serien. + +- intent: frage_nach_aktuellen_kinohits + examples: | + - Was läuft gerade im Kino? + - Gibt es aktuelle Kinohits? + - Welche Filme sind momentan in den Kinos beliebt? + - Zeig mir die besten Filme im Kino. + - Was lohnt sich im Kino anzusehen? + + +- intent: empfehlung_für_mehrsprachige_inhalte + examples: | + - Gibt es Filme auf Spanisch? + - Kannst du Serien in Englisch empfehlen? + - Ich suche etwas auf Französisch. + - Welche Filme gibt es in Originalsprache? + - Hast du Vorschläge für fremdsprachige Inhalte? + +- intent: frag_nach_genre_serie + examples: | + - Welche [Thriller](genre)serien kannst du empfehlen? + - Zeig mir [Horror](genre)serien + - Gibt es [Fantasy](genre)serien? + - Kannst du mir [Science-Fiction](genre)serien zeigen? + - Welche [Action](genre)serien sind gut? + - Gibt es neue [Krimi](genre)serien? + - Hast du Vorschläge für [Romantik](genre)serien? + - Welche [Komödien](genre) kannst du mir empfehlen? + - Gibt es gute [Drama](genre)serien? + - Zeige mir [Dokumentation](genre)sserien + - Gibt es [Animation](genre)serien, die sehenswert sind? + - Welche [Abenteuer](genre)-Serien kannst du empfehlen? + - Gibt es [Musicals](genre)-Serien? + - Kannst du mir [Historien](genre)serien empfehlen? + - Gibt es [Western](genre)serien? diff --git a/data/rules.yml b/data/rules.yml index daa20c16c9c719b1394c3f0fcf9161139047c9a3..5a1f0d2386f99c60be6fb0c99fbab0ba39c5dfdc 100644 --- a/data/rules.yml +++ b/data/rules.yml @@ -16,3 +16,15 @@ rules: steps: - intent: erzähle_einen_witz - action: utter_erzähle_einen_witz + +- rule: User nicht verstanden + steps: + - intent: nlu_fallback + - action: utter_default + +- rule: Empfehle Filme nach Genre + steps: + - intent: frag_nach_genre_film + - slot_was_set: + - genre: "Komödie" + - action: action_empfehlung_nach_genre \ No newline at end of file diff --git a/data/stories.yml b/data/stories.yml index d36ed9b42636fb53d950746f328043f451401548..5104441d065537914c5992cce684d335aeba2798 100644 --- a/data/stories.yml +++ b/data/stories.yml @@ -2,6 +2,27 @@ version: "3.1" stories: +#Basics +- story: Lob annehmen + steps: + - intent: lob + - action: utter_lob + +- story: Kritik annehmen + steps: + - intent: kritik + - action: utter_kritik + +- story: Zustimmung + steps: + - intent: zustimmung + - action: utter_zustimmung + +- story: Ablehnung + steps: + - intent: ablehnung + - action: utter_ablehnung + - story: Frage nach Fähigkeiten steps: - intent: frag_nach_fähigkeiten @@ -33,24 +54,51 @@ stories: - intent: gute_stimmung - action: utter_gute_stimmung +- story: Schlechte Stimmung + steps: + - intent: begrüßung + - action: utter_begrüßung + - intent: schlechte_stimmung + - action: utter_schlechte_stimmung + - action: utter_erzähle_einen_witz + - story: Dynamische Filmempfehlung steps: - intent: film_empfehlen - action: action_film_empfehlen + - story: Filmempfehlung nach Genre steps: - - intent: frag_nach_genre + - intent: frag_nach_genre_film + entities: + - genre: "Komödie" + - slot_was_set: + - genre: "Komödie" - action: action_empfehlung_nach_genre - - intent: film_empfehlen - - action: action_film_empfehlen -- story: Filmempfehlung basierend auf Beliebtheit + +- story: Empfehlungen nach Genre für Serie + steps: + - intent: frag_nach_genre_serie + - slot_was_set: + - content_type: tv + - action: action_empfehlung_nach_genre + + +- story: Beliebte Inhalte anzeigen steps: - intent: was_ist_beliebt + - slot_was_set: + - content_type: movie + - action: action_was_ist_beliebt + +- story: Beliebte Serien anzeigen + steps: + - intent: was_ist_beliebt + - slot_was_set: + - content_type: tv - action: action_was_ist_beliebt - - intent: film_empfehlen - - action: action_film_empfehlen - story: Filmklassiker empfehlen steps: @@ -82,38 +130,81 @@ stories: - intent: serie_empfehlen - action: action_serie_empfehlen -- story: Serienempfehlung nach Genre - steps: - - intent: frag_nach_genre - - action: action_empfehlung_nach_genre - -- story: Serienempfehlung nach Stimmung - steps: - - intent: empfehlung_für_stimmung - - action: utter_empfehlung_für_stimmung - - intent: serie_empfehlen - - action: utter_serie_empfehlen - - story: Seriendetails anzeigen steps: - intent: frag_nach_serie_details - action: action_serie_details -- story: Vorschläge bewerten und weitere anzeigen - steps: - - intent: vorschläge_bewerten - - action: utter_vorschläge_bewerten - - intent: frag_nach_mehr - - action: utter_frag_nach_mehr - - story: Bewertung hinterlassen steps: - intent: bewertung_hinterlassen - action: utter_bewertung_hinterlassen -- story: Problem mit Vorschlägen +- story: FAQ + steps: + - intent: faq + - action: utter_faq + +- story: Fehler melden + steps: + - intent: fehler_melden + - action: utter_fehler_melden + +- story: Was bist du? + steps: + - intent: was_bist_du + - action: utter_was_bist_du + +- story: Wie geht es dir? 1 + steps: + - intent: frag_nach_stimmung + - action: utter_frag_nach_stimmung + - intent: gute_stimmung + - action: utter_gute_stimmung + +- story: Wie geht es dir? 2 + steps: + - intent: frag_nach_stimmung + - action: utter_frag_nach_stimmung + - intent: schlechte_stimmung + - action: utter_schlechte_stimmung + - intent: erzähle_einen_witz + - action: utter_erzähle_einen_witz + +- story: Witz erzählen + steps: + - intent: erzähle_einen_witz + - action: utter_erzähle_einen_witz + +- story: Nach Hilfe fragen + steps: + - intent: frag_nach_hilfe + - action: utter_frag_nach_hilfe + +- story: Feedback hinterlassen wollen + steps: + - intent: feedback + - action: utter_feedback + +- story: Empfehlungen geben + steps: + - intent: frag_nach_empfehlungen + - action: utter_frag_nach_empfehlungen + - intent: frag_nach_genre_film + - intent: frag_nach_genre_serie + - action: action_empfehlung_nach_genre + +- story: Was kannst du noch? + steps: + - intent: was_kannst_du_noch + - action: utter_was_kannst_du_noch + +- story: Themengebiet abfragen + steps: + - intent: frag_nach_themengebiet + - action: utter_frag_nach_themengebiet + +- story: Danke und Bitte sagen steps: - - intent: problem_mit_vorschlägen - - action: utter_problem_mit_vorschlägen - - intent: frag_nach_mehr - - action: utter_frag_nach_mehr + - intent: dankeschön + - action: utter_bitte \ No newline at end of file diff --git a/domain.yml b/domain.yml index a3d2b214807f449d41e820bb93c40cf91cc373d6..efd8138ae0003133dfbc10ebd0e6051018e6f10d 100644 --- a/domain.yml +++ b/domain.yml @@ -4,7 +4,7 @@ intents: - begrüßung - verabschiedung - zustimmung - - ablehung + - ablehnung - gute_stimmung - schlechte_stimmung - lob @@ -27,30 +27,21 @@ intents: - frag_nach_empfehlungen - was_kannst_du_noch - frag_nach_themengebiet + - dankeschön - film_empfehlen - serie_empfehlen - - frag_nach_genre + - frag_nach_genre_film + - frag_nach_genre_serie - frag_nach_streamingdienst - frag_nach_film_details - frag_nach_serie_details - was_ist_beliebt - - empfehlung_basierend_auf_favoriten - - empfehlung_für_stimmung - - empfehlung_für_alter - - empfehlung_für_anlass - bewertung_hinterlassen - - vorschläge_bewerten - - frag_nach_mehr - - frag_nach_bewertungen - - frag_nach_trailern - - frag_nach_dauer - - frag_nach_verfügbarkeit - - problem_mit_vorschlägen - filmklassiker_empfehlen - neuveröffentlichungen_empfehlen - frag_nach_aktuellen_kinohits - - frag_nach_award_gewinnern - empfehlung_für_mehrsprachige_inhalte + - nlu_fallback responses: utter_begrüßung: @@ -74,14 +65,14 @@ responses: - text: "Alles klar, ich bin hier, um dir zu helfen." utter_gute_stimmung: - - text: "Danke für die Nachfrage, mir geht es super!" - - text: "Alles bestens bei mir, ich hoffe bei dir auch!" - - text: "Ich bin in toller Stimmung und bereit zu helfen." + - text: "Es freut mich, dass es dir gut geht!" + - text: "Das ist toll, dass alles so klappt im Leben!" + - text: "Das ist super! Weiter so!" utter_schlechte_stimmung: - - text: "Danke, dass du fragst. Ich gebe mein Bestes!" - - text: "Es läuft nicht perfekt, aber ich bin hier, um dir zu helfen." - - text: "Ich könnte etwas besser drauf sein, aber lass uns loslegen!" + - text: "Es tut mir so Leid für dich!" + - text: "Das tut mir so Leid! Ich wünsche dir nur das Beste!" + - text: "Oh nein! Ich möchte, dass du glücklich bist!" utter_lob: - text: "Vielen Dank! Ich gebe mein Bestes." @@ -104,7 +95,7 @@ responses: - text: "Nenn mich einfach MovieBot!" utter_frag_nach_support: - - text: "Für Support kannst du [support@example.com](mailto:support@example.com) kontaktieren." + - text: "Für Support kannst du support@example.com kontaktieren." - text: "Bitte kontaktiere unser Team unter support@example.com." - text: "Falls du Hilfe brauchst, erreichst du uns hier: support@example.com." @@ -140,8 +131,8 @@ responses: utter_frag_nach_stimmung: - text: "Mir geht es super, danke! Und dir?" - - text: "Alles gut bei mir, wie kann ich dir helfen?" - - text: "Ich bin bereit für deine Fragen!" + - text: "Alles gut bei mir. Und bei dir?" + - text: "Mir geht es super. Und wie geht es dir? Ich bin bereit für deine Fragen!" utter_erzähle_einen_witz: - text: "Warum sind Geister so schlechte Lügner? Weil man durch sie hindurchsehen kann!" @@ -162,6 +153,7 @@ responses: - text: "Danke, dass du den Fehler gemeldet hast. Ich kümmere mich darum." - text: "Tut mir leid, das sollte nicht passieren. Ich werde das Problem prüfen." - text: "Ich leite das an das Entwicklerteam weiter. Vielen Dank!" + - text: "Ich werde das Problem identifizieren und dem Entwicklerteam Bescheid geben." utter_feedback: - text: "Ich freue mich über dein Feedback!" @@ -193,11 +185,6 @@ responses: - text: "Ich empfehle 'Stranger Things'. Mystery und 80er-Nostalgie in einem." - text: "Probier 'The Crown', wenn du Dramen und historische Geschichten magst." - utter_frag_nach_genre: - - text: "Für Horror empfehle ich dir 'The Conjuring' oder 'Hereditary'." - - text: "Actionfilme wie 'Mad Max: Fury Road' sind sehr spannend." - - text: "Für Romantik probiere 'P.S. Ich liebe dich'." - utter_frag_nach_streamingdienst: - text: "Dieser Film ist auf Netflix verfügbar." - text: "Die Serie findest du auf Prime Video." @@ -218,65 +205,10 @@ responses: - text: "Die Leute lieben gerade 'The Last of Us'." - text: "Beliebt ist aktuell der Film 'Avatar: The Way of Water'." - utter_empfehlung_basierend_auf_favoriten: - - text: "Wenn du 'Breaking Bad' magst, schau dir 'Better Call Saul' an." - - text: "Liebst du 'Inception'? Dann gefällt dir sicher auch 'Interstellar'." - - text: "Für Fans von 'Game of Thrones' ist 'House of the Dragon' perfekt." - - utter_empfehlung_für_stimmung: - - text: "Wenn du etwas Lustiges willst, schau dir 'Superbad' an." - - text: "Für eine traurige Stimmung empfehle ich 'The Pursuit of Happyness'." - - text: "Willst du Spannung? Dann ist 'Gone Girl' genau das Richtige." - - utter_empfehlung_für_alter: - - text: "Für Kinder empfehle ich 'Findet Nemo' und 'Toy Story'." - - text: "Teenager könnten 'The Hunger Games' oder 'Twilight' mögen." - - text: "Für Erwachsene passt 'The Wolf of Wall Street'." - - utter_empfehlung_für_anlass: - - text: "Für einen Familienabend ist 'Shrek' perfekt." - - text: "Ein Film für ein Date? Probier 'La La Land'." - - text: "Für einen Filmabend mit Freunden empfehle ich 'The Hangover'." - utter_bewertung_hinterlassen: - - text: "Wie hat dir der Film gefallen? War er gut?" - - text: "Hinterlass mir gerne dein Feedback zu meinem Vorschlag." - - text: "Hat dir die Serie gefallen? Was denkst du?" - - utter_vorschläge_bewerten: - - text: "Welcher Vorschlag gefällt dir am besten?" - - text: "Kann ich die Empfehlungen anpassen?" - - text: "Sag mir, ob etwas davon passt." - - utter_frag_nach_mehr: - - text: "Willst du weitere Vorschläge?" - - text: "Ich habe noch mehr Filme und Serien. Möchtest du sie sehen?" - - text: "Soll ich dir mehr Optionen zeigen?" - - utter_frag_nach_bewertungen: - - text: "Der Film hat eine IMDb-Bewertung von 8,5." - - text: "Diese Serie hat 95 % bei Rotten Tomatoes." - - text: "Die Kritiken zu diesem Film sind großartig." - - utter_frag_nach_trailern: - - text: "Hier ist der Trailer zu 'Inception': [Link]" - - text: "Den Trailer zu 'Stranger Things' findest du hier: [Link]" - - text: "Schau dir die Vorschau zu 'Dune' an: [Link]" - - utter_frag_nach_dauer: - - text: "Der Film dauert 2 Stunden und 28 Minuten." - - text: "Eine Episode dieser Serie dauert etwa 45 Minuten." - - text: "Die Serie hat insgesamt 10 Stunden Spielzeit." - - utter_frag_nach_verfügbarkeit: - - text: "Dieser Film ist auf Netflix verfügbar." - - text: "Die Serie findest du auf Prime Video." - - text: "Du kannst den Film auf Disney+ ansehen." - - utter_problem_mit_vorschlägen: - - text: "Tut mir leid, das passt nicht. Soll ich etwas anderes zeigen?" - - text: "Danke für dein Feedback. Ich passe die Empfehlungen an." - - text: "Was genau möchtest du sehen? Ich finde etwas für dich." + - text: "Ich danke dir für deine Bewertung! Ich werde sie in meinen nächsten Vorschlägen berücksichtigen." + - text: "Danke für das Feedback." + - text: "Das sehe ich genauso wie du!" utter_filmklassiker_empfehlen: - text: "Ein Klassiker, den du sehen solltest, ist 'Casablanca'." @@ -293,11 +225,6 @@ responses: - text: "Ein großer Erfolg ist derzeit 'Oppenheimer'." - text: "Im Kino kannst du 'Avatar: The Way of Water' anschauen." - utter_frag_nach_award_gewinnern: - - text: "Der Oscar-Gewinner 'Everything Everywhere All At Once' ist sehenswert." - - text: "Ein preisgekrönter Film ist 'Parasite'." - - text: "Wie wäre es mit 'The Shape of Water'? Ein außergewöhnlicher Film." - utter_empfehlung_für_mehrsprachige_inhalte: - text: "Ein großartiger spanischer Film ist 'El Laberinto del Fauno'." - text: "Für französische Filme empfehle ich 'Amélie'." @@ -308,59 +235,68 @@ responses: - text: "Kein Problem, immer gerne! ðŸ‘" - text: "Freut mich, dass ich helfen konnte!" + utter_default: + - text: "Entschuldigung, das habe ich nicht verstanden. Kannst du das anders formulieren?" + - text: "Hmm, das ist mir unklar. Vielleicht kannst du deine Anfrage konkretisieren?" + - text: "Tut mir leid, ich bin mir nicht sicher, wie ich darauf antworten soll." + slots: - film_genre: + genre: type: text influence_conversation: true mappings: - - type: from_text # Der Wert wird direkt aus der Benutzereingabe übernommen - serie_genre: - type: text - influence_conversation: true - mappings: - - type: from_text - film_name: - type: text - influence_conversation: true - mappings: - - type: from_text - serie_name: + - type: from_entity + entity: genre + content_type: type: text influence_conversation: true mappings: - - type: from_text - favorit_film: - type: text - influence_conversation: true - mappings: - - type: from_text - favorit_serie: + - type: from_intent + value: movie + intent: frag_nach_genre_film + - type: from_intent + value: tv + intent: frag_nach_genre_serie + streamingdienst: type: text influence_conversation: true mappings: - - type: from_text - sprache: + - type: from_entity + entity: streamingdienst + film_name: type: text influence_conversation: true mappings: - - type: from_text - streamingdienst: + - type: from_entity + entity: film_name + serie_name: type: text influence_conversation: true mappings: - - type: from_text - + - type: from_entity + entity: serie_name + actions: - action_film_empfehlen - action_serie_empfehlen - action_empfehlung_nach_genre - - action_empfehlung_nach_streamingdienst - - action_film_details - action_was_ist_beliebt + - action_film_details + - action_serie_details - action_filmklassiker_empfehlen - action_aktuelle_kinohits - - action_serie_details + - action_empfehlung_nach_streamingdienst + + + +entities: + - genre + - content_type + - streamingdienst + - film_name + - serie_name + session_config: diff --git a/models/20241213-192303-frayed-circle.tar.gz b/models/20241213-192303-frayed-circle.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..6a8f22c3cbaccbc4e4300879865cfc6313538770 Binary files /dev/null and b/models/20241213-192303-frayed-circle.tar.gz differ diff --git a/models/20241213-205851-legato-number.tar.gz b/models/20241213-205851-legato-number.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..9424fca299a28e26341499c8dc8101e957c55442 Binary files /dev/null and b/models/20241213-205851-legato-number.tar.gz differ diff --git a/models/20241213-212912-miniature-offset.tar.gz b/models/20241213-212912-miniature-offset.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..d44e364cc32d61924e3a00261635a133b75b53c5 Binary files /dev/null and b/models/20241213-212912-miniature-offset.tar.gz differ diff --git a/models/20241213-215709-narrow-rate.tar.gz b/models/20241213-215709-narrow-rate.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..66b465484b8ea356cf5b8108f4135ba6bb408d8c Binary files /dev/null and b/models/20241213-215709-narrow-rate.tar.gz differ diff --git a/models/20241215-184125-novel-keel.tar.gz b/models/20241215-184125-novel-keel.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..64a62bafa43e5922ffbe527280b7ab9511a6ad0e Binary files /dev/null and b/models/20241215-184125-novel-keel.tar.gz differ diff --git a/models/20241215-210714-khaki-veranda.tar.gz b/models/20241215-210714-khaki-veranda.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..f2f763667e43f54bf87e59882804bed702b0441e Binary files /dev/null and b/models/20241215-210714-khaki-veranda.tar.gz differ diff --git a/models/20241215-213827-paper-transmitter.tar.gz b/models/20241215-213827-paper-transmitter.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..0920a0c76649acce80847bdcb463ddd0bc86f128 Binary files /dev/null and b/models/20241215-213827-paper-transmitter.tar.gz differ