File size: 9,258 Bytes
98ffa93
 
d8a9363
98ffa93
 
a98e519
 
 
99e79f0
 
 
 
a98e519
99e79f0
a98e519
 
 
 
 
99e79f0
 
 
 
 
 
 
 
 
 
a98e519
 
 
 
99e79f0
 
 
 
 
 
 
 
a98e519
99e79f0
 
 
 
 
a98e519
 
 
99e79f0
a98e519
99e79f0
 
 
 
98ffa93
 
99e79f0
 
 
 
d8a9363
98ffa93
 
 
 
 
99e79f0
a98e519
d8a9363
99e79f0
98ffa93
 
d8a9363
 
 
 
98ffa93
 
 
 
99e79f0
98ffa93
 
d8a9363
99e79f0
d8a9363
98ffa93
d8a9363
99e79f0
 
 
 
d8a9363
 
 
a98e519
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d8a9363
a98e519
 
 
 
 
 
98ffa93
d8a9363
99e79f0
 
 
 
d8a9363
 
 
 
 
 
fd1209e
d8a9363
 
98ffa93
d8a9363
 
 
a98e519
 
 
d8a9363
98ffa93
a98e519
d8a9363
a98e519
d8a9363
a98e519
d8a9363
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
98ffa93
 
d8a9363
 
 
 
 
99e79f0
 
 
 
a98e519
 
 
 
d8a9363
 
99e79f0
 
 
 
a98e519
 
 
 
 
 
99e79f0
 
 
a98e519
 
 
 
 
 
 
 
 
 
 
99e79f0
 
a98e519
d8a9363
 
 
 
 
 
 
 
 
 
 
 
a98e519
d8a9363
 
 
 
 
 
 
 
a98e519
 
d8a9363
 
98ffa93
d8a9363
 
 
 
 
 
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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
import streamlit as st
import pandas as pd
from typing import Union, List, Dict
from groq import Groq
import os
from duckduckgo_search import DDGS

class DuckDuckGoSearch:
    """
    Custom DuckDuckGo search implementation with robust error handling and result processing.
    Uses the duckduckgo_search library to fetch and format news results.
    """
    def __init__(self):
        # Initialize the DuckDuckGo search session
        self.ddgs = DDGS()
    
    def __call__(self, query: str, max_results: int = 5) -> str:
        try:
            # Perform the search and get results
            # The news method is more appropriate for recent news analysis
            search_results = list(self.ddgs.news(
                query,
                max_results=max_results,
                region='wt-wt',  # Worldwide results
                safesearch='on'
            ))
            
            if not search_results:
                return "No results found. Try modifying your search query."
            
            # Format the results into a readable string
            formatted_results = []
            for idx, result in enumerate(search_results, 1):
                # Extract available fields with fallbacks for missing data
                title = result.get('title', 'No title available')
                snippet = result.get('body', result.get('snippet', 'No description available'))
                source = result.get('source', 'Unknown source')
                url = result.get('url', result.get('link', 'No link available'))
                date = result.get('date', 'Date not available')
                
                # Format each result with available information
                formatted_results.append(
                    f"{idx}. Title: {title}\n"
                    f"   Date: {date}\n"
                    f"   Source: {source}\n"
                    f"   Summary: {snippet}\n"
                    f"   URL: {url}\n"
                )
            
            return "\n".join(formatted_results)
        
        except Exception as e:
            # Provide detailed error information for debugging
            error_msg = f"Search error: {str(e)}\nTry again with a different search term or check your internet connection."
            print(f"DuckDuckGo search error: {str(e)}")  # For logging
            return error_msg

class GroqLLM:
    """
    LLM interface using Groq's LLama model.
    Handles API communication and response processing.
    """
    def __init__(self, model_name="llama-3.1-8B-Instant"):
        self.client = Groq(api_key=os.environ.get("GROQ_API_KEY"))
        self.model_name = model_name
    
    def __call__(self, prompt: Union[str, dict, List[Dict]]) -> str:
        try:
            # Convert prompt to string if it's a complex structure
            prompt_str = str(prompt) if isinstance(prompt, (dict, list)) else prompt
            
            # Make API call to Groq
            completion = self.client.chat.completions.create(
                model=self.model_name,
                messages=[{
                    "role": "user",
                    "content": prompt_str
                }],
                temperature=0.7,
                max_tokens=1024,
                stream=False
            )
            
            return completion.choices[0].message.content if completion.choices else "Error: No response generated"
        except Exception as e:
            error_msg = f"Error generating response: {str(e)}"
            print(error_msg)  # For logging
            return error_msg

def create_analysis_prompt(topic: str, search_results: str) -> str:
    """
    Creates a detailed prompt for news analysis, structuring the request
    to get comprehensive and well-organized results from the LLM.
    """
    return f"""Analyze the following news information about {topic}. 
    Search Results: {search_results}
    
    Please provide a comprehensive analysis including:
    1. Key Points Summary:
       - Main events and developments
       - Critical updates and changes
    
    2. Stakeholder Analysis:
       - Primary parties involved
       - Their roles and positions
    
    3. Impact Assessment:
       - Immediate implications
       - Potential long-term effects
       - Broader context and significance
    
    4. Multiple Perspectives:
       - Different viewpoints on the issue
       - Areas of agreement and contention
    
    5. Fact Check & Reliability:
       - Verification of major claims
       - Consistency across sources
       - Source credibility assessment
    
    Please format the analysis in a clear, journalistic style with section headers."""

def log_agent_activity(prompt: str, result: str, agent_name: str):
    """
    Creates an expandable log of agent activities in the Streamlit interface
    for transparency and debugging purposes.
    """
    with st.expander("View Agent Activity Log"):
        st.write(f"### Agent Activity ({agent_name}):")
        st.write("**Input Prompt:**")
        st.code(prompt, language="text")
        st.write("**Analysis Output:**")
        st.code(result, language="text")

# Initialize Streamlit app
st.set_page_config(page_title="News Analysis Tool", layout="wide")

# Title and description
st.title("πŸ” AI News Analysis Tool")
st.write("""
This tool combines the power of Groq's LLama 3.1 8B Instant model with DuckDuckGo 
search to provide in-depth news analysis. Get comprehensive insights and multiple 
perspectives on any news topic.
""")

# Initialize the components
try:
    # Initialize LLM and search tool
    llm = GroqLLM()
    search_tool = DuckDuckGoSearch()
    
    # Input section
    news_topic = st.text_input(
        "Enter News Topic or Query:",
        placeholder="E.g., Recent developments in renewable energy"
    )
    
    # Analysis options
    col1, col2 = st.columns(2)
    with col1:
        search_depth = st.slider(
            "Search Depth (number of results)",
            min_value=3,
            max_value=10,
            value=5
        )
    with col2:
        analysis_type = st.selectbox(
            "Analysis Type",
            ["Comprehensive", "Quick Summary", "Technical", "Simplified"]
        )
    
    # Generate analysis button
    if st.button("Analyze News"):
        if news_topic:
            with st.spinner("Gathering information and analyzing..."):
                try:
                    # Show search progress
                    search_placeholder = st.empty()
                    search_placeholder.info("Searching for recent news...")
                    
                    # Perform search
                    search_results = search_tool(
                        f"Latest news about {news_topic} last 7 days",
                        max_results=search_depth
                    )
                    
                    if not search_results.startswith(("Search error", "No results")):
                        # Update progress
                        search_placeholder.info("Analyzing search results...")
                        
                        # Create analysis prompt
                        analysis_prompt = create_analysis_prompt(news_topic, search_results)
                        
                        # Get analysis from LLM
                        analysis_result = llm(analysis_prompt)
                        
                        # Clear progress messages
                        search_placeholder.empty()
                        
                        # Display results
                        st.subheader("πŸ“Š Analysis Results")
                        st.markdown(analysis_result)
                        
                        # Log the activity
                        log_agent_activity(
                            analysis_prompt,
                            analysis_result,
                            "News Analysis Agent"
                        )
                    else:
                        search_placeholder.empty()
                        st.error(search_results)
                        
                except Exception as e:
                    st.error(f"An error occurred during analysis: {str(e)}")
        else:
            st.warning("Please enter a news topic to analyze.")

    # Add helpful tips
    with st.expander("πŸ’‘ Tips for Better Results"):
        st.write("""
        - Be specific with your topic for more focused analysis
        - Use keywords related to recent events for timely information
        - Consider including timeframes in your query
        - Try different analysis types for various perspectives
        - For complex topics, start with a broader search and then narrow down
        """)

except Exception as e:
    st.error(f"""
    Failed to initialize the application: {str(e)}
    
    Please ensure:
    1. Your GROQ_API_KEY is properly set in environment variables
    2. All required packages are installed:
       - pip install streamlit groq duckduckgo-search
    3. You have internet connectivity for DuckDuckGo searches
    """)

# Footer
st.markdown("---")
st.caption(
    "Powered by Groq LLama 3.1 8B Instant, DuckDuckGo, and Streamlit | "
    "Created for news analysis and research purposes"
)