File size: 5,271 Bytes
1190b8e
 
 
 
 
6133cad
1190b8e
 
5db8377
1190b8e
 
 
 
 
5db8377
 
1190b8e
 
 
 
5db8377
6133cad
5db8377
1190b8e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5db8377
 
 
1190b8e
5db8377
 
 
1190b8e
 
6133cad
 
1190b8e
 
 
 
6133cad
1190b8e
 
 
 
 
 
 
 
 
 
6133cad
1190b8e
 
 
6133cad
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1190b8e
 
 
 
 
 
 
6133cad
 
d294409
 
 
 
 
 
6133cad
1190b8e
6133cad
 
 
 
 
1190b8e
 
 
6133cad
 
1190b8e
 
 
 
 
 
6133cad
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
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()