import gradio as gr from newspaper import Article from modules.online_search import search_online from modules.validation import calculate_truthfulness_score from modules.knowledge_graph import search_kg from modules.generate_explanation import generate_explanation # Import the explanation generator from dotenv import load_dotenv import os from concurrent.futures import ThreadPoolExecutor # Load environment variables from .env file load_dotenv() # Constants KG_INDEX_PATH = "KG/news_category_index.faiss" KG_DATASET_PATH = "KG/News_Category_Dataset_v3.json" SEARCH_API_KEY = os.getenv("SEARCH_API_KEY") SEARCH_BASE_URL = os.getenv("SEARCH_BASE_URL") SEARCH_MODEL = os.getenv("SEARCH_MODEL") # Initialize ThreadPoolExecutor executor = ThreadPoolExecutor(max_workers=3) # Increased workers to accommodate explanation task # Function to process input and evaluate truthfulness def evaluate_news(news_input): # Display loading message yield "**Processing... Please wait while we analyze the information.** ⏳" # Handle URL input if news_input.startswith("http"): try: article = Article(news_input) article.download() article.parse() news_text = article.title + ". " + article.text except Exception as e: yield f"**Error processing the URL:** {str(e)}" return else: # Direct text input news_text = news_input try: # Run both search functions concurrently using ThreadPoolExecutor future_kg = executor.submit(search_kg, news_text, KG_INDEX_PATH, KG_DATASET_PATH) future_online = executor.submit(search_online, news_text, SEARCH_API_KEY, SEARCH_BASE_URL, SEARCH_MODEL) # Wait for the results of both tasks kg_content = future_kg.result() online_search_results = future_online.result() # Combine context from KG and online search context = online_search_results['message_content'] + '\n' + kg_content + '\n' + 'Device set to use cpu' # print(context) # Debug log # Calculate truth score truth_score = calculate_truthfulness_score(info=news_text, context=context) # Determine truthfulness status and recommendation if truth_score > 0.7: status = "likely true" recommendation = "You can reasonably trust this information, but further verification is always recommended for critical decisions." elif truth_score > 0.4: status = "uncertain" recommendation = "This information might be partially true, but additional investigation is required before accepting it as fact." else: status = "unlikely to be true" recommendation = "It is recommended to verify this information through multiple reliable sources before trusting it." # Display initial result with score result = f"**News**: \"{news_text[:300]}...\"\n\n" result += f"**Truthfulness Score**: {truth_score:.2f} (**{status.capitalize()}**)\n\n" result += f"**Analysis**: {recommendation}\n\n" yield result # Immediately display score and recommendation # Generate explanation asynchronously future_explanation = executor.submit(generate_explanation, news_text, context, truth_score) # Add explanation and sources once available explanation = future_explanation.result() # Wait for explanation result if explanation: result += f"**Explanation**: {explanation}\n\n" # Append explanation # Add sources from the online search results (top 5 sources) sources = online_search_results.get('sources', []) if sources: result += "\n**Sources**:\n" # Ensure we only show up to 5 sources for i, source in enumerate(sources[:5]): result += f"{i + 1}. {source}\n" result += "\n*Please make sure to do your own research for more confirmation and to cross-check the information.*" yield result # Update UI with explanation and sources except Exception as e: yield f"**Error occurred while processing the input:** {str(e)}" # Gradio Interface with gr.Blocks() as demo: gr.Markdown("# 📰 EchoTruth: Verify News Authenticity in Real-Time") gr.Markdown(""" **How to use:** 1. Enter a news article or URL in the box below. 2. Click on **Check Truthfulness**. 3. Receive a **truthfulness score** along with **explanations and sources** to help you assess the authenticity of the content. """) with gr.Row(): input_box = gr.Textbox( placeholder="Enter news text or URL here... (e.g., https://example.com)", label="Input News or URL", lines=5 ) submit_btn = gr.Button("Check Truthfulness") output_box = gr.Markdown() submit_btn.click( fn=evaluate_news, inputs=[input_box], outputs=[output_box] ) gr.Markdown("### **About EchoTruth**") gr.Markdown("EchoTruth uses AI to help users verify news authenticity in real-time. We recommend checking multiple sources before making decisions based on news.") demo.launch()