diff --git a/src/Ai/llm.py b/src/Ai/llm.py index 0b44cfb..7f3a4ec 100644 --- a/src/Ai/llm.py +++ b/src/Ai/llm.py @@ -12,7 +12,7 @@ class ArticleRater: "model": "mistral-nemo:12b-instruct-2407-q8_0", "headers": self.headers, "system": """Ein Mashine Learning Model hat einen Text bewertet, ob es sich um FakeNews handelt oder um Reale News. - Erkläre in 1-3 Sätzen warum dieses Modell zu dieser Entscheidung. Beginne die Antwort IMMER mit den Resultaten und Konfidenzen des Models. + Erkläre in 1-2 Sätzen warum dieses Modell zu dieser Entscheidung. DU SOLLST KEINE ÜBERSCHRIFTEN oder ähnliches ERKLÄREN. Du erhählst einen TEXT und sollst erklären wie das RESULTAT zustande kam""" } diff --git a/src/controller/mainFrameController.py b/src/controller/mainFrameController.py index 7406d0a..9c233cc 100644 --- a/src/controller/mainFrameController.py +++ b/src/controller/mainFrameController.py @@ -7,12 +7,7 @@ from utils.database.database import FakeNewsChecker from models.provider import Provider from collections import Counter from Ai.llm import ArticleRater - -BAD_WORDS = ["FAKE", "SATIRE", "Fake", "fake", "fake news", "Fake News", "FakeNews"] -GOOD_WORDS = ["REAL", "real ", "Real", "Reale News", "reale", "reale News", "realen", "Real News"] -BAD_COLOR = "#ff8080" -GOOD_COLOR = "#80ff8f" -WORDS = BAD_WORDS + GOOD_WORDS +from Ai.Token import get_token class MainFrameController: @@ -47,63 +42,36 @@ class MainFrameController: return text_data def press_check_button(self): + self.frame.result_label.configure(text="", fg_color="#333333") + self.frame.confidence_label.configure(text="", fg_color="#333333") text_data = self.get_text_data() + if not text_data.text.strip(): + return + text_data = self._predict(text_data) self._add_to_db(text_data) + self.frame.output_textbox.configure(state="normal") self.frame.output_textbox.delete("0.0", "end") - response_stream = self.rater.get_response(text_data.text, text_data.result, float(f"{text_data.confidence * 100:.2f}")) + confidence = text_data.confidence * 100 + self.frame.confidence_label.configure(text=f"{confidence:.2f}%") - highlight_buffer = deque(maxlen=5) + result_color = "green" if text_data.result == "REAL" else "red" + self.frame.result_label.configure(text=text_data.result, fg_color=result_color) - for chunk in response_stream: - # Display the chunk immediately - self.frame.output_textbox.insert("end", chunk) - self.frame.output_textbox.see("end") - self.frame.update_idletasks() + confidence_color = "green" if confidence > 80 else ("orange" if confidence > 50 else "red") + self.frame.confidence_label.configure(fg_color=confidence_color) + + if get_token().strip(): + response_stream = self.rater.get_response(text_data.text, text_data.result, confidence) - # Add to highlight buffer - highlight_buffer.append(chunk) + for chunk in response_stream: + self.frame.output_textbox.insert("end", chunk) + self.frame.output_textbox.see("end") + self.frame.update_idletasks() - # Process highlighting when buffer is full - if len(highlight_buffer) == 5: - self._process_highlighting(highlight_buffer) - - # Process any remaining chunks in the buffer - if highlight_buffer: - self._process_highlighting(highlight_buffer) - - self.frame.output_textbox.configure(state="disabled") - self.update_provider_list() - def _process_highlighting(self, highlight_buffer): - start_index = self.frame.output_textbox.index(f"end-{sum(len(c) for c in highlight_buffer)}c") - end_index = self.frame.output_textbox.index("end") - self._highlight_words(start_index, end_index) - - # Keep overlap of 2 chunks - highlight_buffer = deque(list(highlight_buffer)[-3:], maxlen=5) - - def _highlight_words(self, start_index, end_index): - content = self.frame.output_textbox.get(start_index, end_index) - - for word in WORDS: - start = 0 - while True: - pos = content.find(word, start) - if pos == -1: - break - word_start = f"{start_index}+{pos}c" - word_end = f"{word_start}+{len(word)}c" - tag_name = f"{word.lower()}_color" - self.frame.output_textbox.tag_add(tag_name, word_start, word_end) - if word in BAD_WORDS: - self.frame.output_textbox.tag_config(tag_name, foreground=BAD_COLOR) - elif word in GOOD_WORDS: - self.frame.output_textbox.tag_config(tag_name, foreground=GOOD_COLOR) - start = pos + len(word) - def _predict(self, text_data: TextData) -> TextData: """ Make a prediction using the VeraMind model. diff --git a/src/views/mainScreen.py b/src/views/mainScreen.py index 51fa03e..f22a8f0 100644 --- a/src/views/mainScreen.py +++ b/src/views/mainScreen.py @@ -1,44 +1,64 @@ from typing import Any import customtkinter as ctk -class MainFrame(ctk.CTkFrame): - + + +class MainFrame(ctk.CTkFrame): def __init__(self, master: Any, **kwargs): super().__init__(master, **kwargs) self.controller = None - # Konfiguriere das Hauptframe, um sich zu dehnen + # Configure the main frame to stretch self.grid_rowconfigure(0, weight=1) - self.grid_columnconfigure(0, weight=1) # Linke Spalte soll sich dehnen - self.grid_columnconfigure(1, weight=0) # Mittlere Spalte (Button) soll sich nicht dehnen - self.grid_columnconfigure(2, weight=1) # Rechte Spalte soll sich dehnen + self.grid_columnconfigure(0, weight=1) # Left column should stretch + self.grid_columnconfigure(1, weight=0) # Middle column (button) should not stretch + self.grid_columnconfigure(2, weight=1) # Right column should stretch - # Linkes Frame + # Left frame self.frame1 = ctk.CTkFrame(self) self.frame1.grid(row=0, column=0, sticky="nsew", padx=10, pady=10) - self.frame1.grid_rowconfigure(2, weight=1) # Lasse die Output-Textbox wachsen - self.frame1.grid_columnconfigure(0, weight=1) # Lasse frame1 horizontal wachsen + self.frame1.grid_rowconfigure(3, weight=1) + self.frame1.grid_columnconfigure(0, weight=1) self.entry_url = ctk.CTkEntry(self.frame1, placeholder_text='Enter the article link', height=50) - self.entry_url.grid(row=0, column=0, padx=10, pady=10, sticky="ew") + self.entry_url.grid(row=0, column=0,columnspan=2, padx=10, pady=10, sticky="ew") - self.input_textbox = ctk.CTkTextbox(self.frame1, height=150) - self.input_textbox.grid(row=1, column=0, columnspan=2, padx=10, pady=10, sticky="nsew") - - self.output_textbox = ctk.CTkTextbox(self.frame1, height=200, state="disabled") - self.output_textbox.grid(row=2, column=0, columnspan=2, padx=10, pady=10, sticky="nsew") - - # Mittlerer Button + # Middle button self.check_button = ctk.CTkButton(self.frame1, text="Check", width=60, height=50, command=self.check_button_event) - self.check_button.grid(row=0, column=1, padx=10, pady=10, sticky="w") + self.check_button.grid(row=0, column=2,columnspan=1, padx=10, pady=10, sticky="e") - # Rechte scrollbare Ansicht + # Input Checkbox + self.input_textbox = ctk.CTkTextbox(self.frame1, height=125) + self.input_textbox.grid(row=1, column=0,columnspan=3, padx=10, pady=10, sticky="nsew") + + # Frame for Result and Confidence labels + self.label_frame = ctk.CTkFrame(self.frame1, fg_color="#333333") + self.label_frame.grid(row=2, column=0, columnspan=3, padx=10, pady=10, sticky="ew") + self.label_frame.grid_columnconfigure(0, weight=1) + self.label_frame.grid_columnconfigure(1, weight=1) + + # Result label + self.result_label = ctk.CTkLabel(self.label_frame, text="", height=50, fg_color="#333333", corner_radius=5) + self.result_label.grid(row=0, column=0, padx=(0, 5), pady=0, sticky="ew") + + # Confidence label + self.confidence_label = ctk.CTkLabel(self.label_frame, text="", height=50, fg_color="#333333", corner_radius=5) + self.confidence_label.grid(row=0, column=1, padx=(5, 0), pady=0, sticky="ew") + + # Ensure equal width for both labels + self.label_frame.grid_columnconfigure(0, weight=1, minsize=200) + self.label_frame.grid_columnconfigure(1, weight=1, minsize=200) + + self.output_textbox = ctk.CTkTextbox(self.frame1, height=175, state="disabled") + self.output_textbox.grid(row=3, column=0, columnspan=3, padx=10, pady=10, sticky="nsew") + + # Right scrollable view self.scrollview = ctk.CTkScrollableFrame(self) self.scrollview.grid(row=0, column=2, padx=10, pady=10, sticky="nsew") - # Überschrift hinzufügen + # Add header self.header = ctk.CTkLabel(self.scrollview, text="Leaderboard", font=("Arial", 24, "bold")) self.header.pack(pady=10, padx=10, anchor="w") - # Container für Provider-Einträge + # Container for provider entries self.provider_container = ctk.CTkFrame(self.scrollview) self.provider_container.pack(fill="both", expand=True)