siyah1 commited on
Commit
b96067c
Β·
verified Β·
1 Parent(s): 1eba7f7

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +325 -72
app.py CHANGED
@@ -5,6 +5,167 @@ from groq import Groq
5
  import os
6
  from duckduckgo_search import DDGS
7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
  class DuckDuckGoSearch:
9
  """
10
  Custom DuckDuckGo search implementation with robust error handling and result processing.
@@ -125,22 +286,36 @@ def log_agent_activity(prompt: str, result: str, agent_name: str):
125
  Creates an expandable log of agent activities in the Streamlit interface
126
  for transparency and debugging purposes.
127
  """
128
- with st.expander("View Agent Activity Log"):
129
  st.write(f"### Agent Activity ({agent_name}):")
130
  st.write("**Input Prompt:**")
131
  st.code(prompt, language="text")
132
  st.write("**Analysis Output:**")
133
  st.code(result, language="text")
134
 
135
- # Initialize Streamlit app
136
- st.set_page_config(page_title="News Analysis Tool", layout="wide")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
137
 
138
- # Title and description
139
- st.title("Z-AgentπŸ” AI News Analysis Tool")
140
- st.write("""
141
- This tool combines the power of Ai Agent. Get comprehensive insights and multiple
142
- perspectives on any news topic.
143
- """)
144
 
145
  # Initialize the components
146
  try:
@@ -148,83 +323,153 @@ try:
148
  llm = GroqLLM()
149
  search_tool = DuckDuckGoSearch()
150
 
151
- # Input section
152
  news_topic = st.text_input(
153
- "Enter News Topic or Query:",
154
- placeholder="E.g., Recent developments in renewable energy"
155
  )
156
 
157
- # Analysis options
158
- col1, col2 = st.columns(2)
 
159
  with col1:
160
  search_depth = st.slider(
161
- "Search Depth (number of results)",
162
  min_value=3,
163
  max_value=10,
164
- value=5
 
165
  )
 
166
  with col2:
167
  analysis_type = st.selectbox(
168
  "Analysis Type",
169
- ["Comprehensive", "Quick Summary", "Technical", "Simplified"]
 
 
 
 
 
 
 
 
170
  )
171
 
172
  # Generate analysis button
173
- if st.button("Analyze News"):
174
- if news_topic:
175
- with st.spinner("Gathering information and analyzing..."):
176
- try:
177
- # Show search progress
178
- search_placeholder = st.empty()
179
- search_placeholder.info("Searching for recent news...")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
180
 
181
- # Perform search
182
- search_results = search_tool(
183
- f"Latest news about {news_topic} last 7 days",
184
- max_results=search_depth
185
- )
 
 
 
186
 
187
- if not search_results.startswith(("Search error", "No results")):
188
- # Update progress
189
- search_placeholder.info("Analyzing search results...")
190
-
191
- # Create analysis prompt
192
- analysis_prompt = create_analysis_prompt(news_topic, search_results)
193
-
194
- # Get analysis from LLM
195
- analysis_result = llm(analysis_prompt)
196
-
197
- # Clear progress messages
198
- search_placeholder.empty()
199
-
200
- # Display results
201
- st.subheader("πŸ“Š Analysis Results")
202
  st.markdown(analysis_result)
203
-
204
- # Log the activity
205
- log_agent_activity(
206
- analysis_prompt,
207
- analysis_result,
208
- "News Analysis Agent"
209
- )
210
- else:
211
- search_placeholder.empty()
212
- st.error(search_results)
213
-
214
- except Exception as e:
215
- st.error(f"An error occurred during analysis: {str(e)}")
216
- else:
217
- st.warning("Please enter a news topic to analyze.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
218
 
219
- # Add helpful tips
220
- with st.expander("πŸ’‘ Tips for Better Results"):
221
- st.write("""
222
- - Be specific with your topic for more focused analysis
223
- - Use keywords related to recent events for timely information
224
- - Consider including timeframes in your query
225
- - Try different analysis types for various perspectives
226
- - For complex topics, start with a broader search and then narrow down
 
 
 
227
  """)
 
 
 
 
 
 
 
 
 
228
 
229
  except Exception as e:
230
  st.error(f"""
@@ -237,9 +482,17 @@ except Exception as e:
237
  3. You have internet connectivity for DuckDuckGo searches
238
  """)
239
 
240
- # Footer
241
  st.markdown("---")
242
- st.caption(
243
- " | "
244
- "Created for news analysis and research purposes"
245
- )
 
 
 
 
 
 
 
 
 
5
  import os
6
  from duckduckgo_search import DDGS
7
 
8
+ # Set page configuration with wider layout and custom theme
9
+ st.set_page_config(
10
+ page_title="Z-Agent News Analysis",
11
+ layout="wide",
12
+ initial_sidebar_state="collapsed",
13
+ page_icon="πŸ”"
14
+ )
15
+
16
+ # Custom CSS for Google DeepMind-inspired styling
17
+ st.markdown("""
18
+ <style>
19
+ /* Global font and color scheme */
20
+ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');
21
+
22
+ html, body, [class*="css"] {
23
+ font-family: 'Inter', sans-serif;
24
+ }
25
+
26
+ /* Header styling */
27
+ h1 {
28
+ color: #101010;
29
+ font-weight: 700 !important;
30
+ margin-bottom: 1rem !important;
31
+ letter-spacing: -0.5px;
32
+ }
33
+
34
+ h2, h3 {
35
+ font-weight: 600 !important;
36
+ color: #202020;
37
+ letter-spacing: -0.3px;
38
+ }
39
+
40
+ /* Container styling */
41
+ .main .block-container {
42
+ padding-top: 2rem;
43
+ padding-bottom: 2rem;
44
+ max-width: 1200px;
45
+ }
46
+
47
+ /* Card-like sections */
48
+ .card {
49
+ background-color: white;
50
+ border-radius: 12px;
51
+ padding: 1.5rem;
52
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
53
+ margin-bottom: 1.5rem;
54
+ }
55
+
56
+ /* Button styling */
57
+ .stButton > button {
58
+ background-color: #1a73e8;
59
+ color: white;
60
+ border: none;
61
+ border-radius: 6px;
62
+ padding: 0.6rem 1.2rem;
63
+ font-weight: 500;
64
+ transition: all 0.3s;
65
+ width: 100%;
66
+ }
67
+
68
+ .stButton > button:hover {
69
+ background-color: #1765cc;
70
+ box-shadow: 0 2px 10px rgba(26, 115, 232, 0.2);
71
+ }
72
+
73
+ /* Input field styling */
74
+ .stTextInput input, .stSelectbox div[data-baseweb="select"] div, .stSlider div[data-baseweb="slider"] {
75
+ border-radius: 6px;
76
+ border: 1px solid #E0E0E0;
77
+ }
78
+
79
+ .stTextInput input:focus, .stSelectbox div[data-baseweb="select"] div:focus {
80
+ border-color: #1a73e8;
81
+ box-shadow: 0 0 0 2px rgba(26, 115, 232, 0.2);
82
+ }
83
+
84
+ /* Analysis result styling */
85
+ .analysis-result {
86
+ background-color: #F8F9FA;
87
+ border-radius: 12px;
88
+ padding: 1.5rem;
89
+ border-left: 4px solid #1a73e8;
90
+ }
91
+
92
+ /* Expand/collapse sections */
93
+ .streamlit-expanderHeader {
94
+ font-weight: 500;
95
+ color: #5f6368;
96
+ }
97
+
98
+ /* Spinner/progress styling */
99
+ .stSpinner > div {
100
+ border-color: #1a73e8 transparent transparent !important;
101
+ }
102
+
103
+ /* Footer styling */
104
+ footer {
105
+ border-top: 1px solid #F0F0F0;
106
+ padding-top: 1rem;
107
+ color: #5f6368;
108
+ font-size: 0.8rem;
109
+ }
110
+
111
+ /* Logo and branding */
112
+ .logo-text {
113
+ font-weight: 600;
114
+ background: linear-gradient(90deg, #1a73e8, #8ab4f8);
115
+ -webkit-background-clip: text;
116
+ -webkit-text-fill-color: transparent;
117
+ font-size: 2.2rem;
118
+ letter-spacing: -1px;
119
+ }
120
+
121
+ /* Sections */
122
+ .section-header {
123
+ font-size: 1.2rem;
124
+ font-weight: 500;
125
+ margin-top: 1.5rem;
126
+ margin-bottom: 1rem;
127
+ color: #202124;
128
+ }
129
+
130
+ /* Source links */
131
+ a {
132
+ color: #1a73e8;
133
+ text-decoration: none;
134
+ }
135
+
136
+ a:hover {
137
+ text-decoration: underline;
138
+ }
139
+
140
+ /* Tabs for analysis results */
141
+ .stTabs [data-baseweb="tab-list"] {
142
+ gap: 2px;
143
+ }
144
+
145
+ .stTabs [data-baseweb="tab"] {
146
+ background-color: transparent;
147
+ border-radius: 4px 4px 0px 0px;
148
+ color: #5f6368;
149
+ padding: 10px 16px;
150
+ }
151
+
152
+ .stTabs [aria-selected="true"] {
153
+ background-color: white !important;
154
+ color: #1a73e8 !important;
155
+ border-bottom: 2px solid #1a73e8;
156
+ }
157
+
158
+ /* Info boxes */
159
+ .info-box {
160
+ background-color: #E8F0FE;
161
+ border-radius: 8px;
162
+ padding: 1rem;
163
+ border-left: 4px solid #1a73e8;
164
+ margin-bottom: 1rem;
165
+ }
166
+ </style>
167
+ """, unsafe_allow_html=True)
168
+
169
  class DuckDuckGoSearch:
170
  """
171
  Custom DuckDuckGo search implementation with robust error handling and result processing.
 
286
  Creates an expandable log of agent activities in the Streamlit interface
287
  for transparency and debugging purposes.
288
  """
289
+ with st.expander("πŸ” View Agent Activity Log"):
290
  st.write(f"### Agent Activity ({agent_name}):")
291
  st.write("**Input Prompt:**")
292
  st.code(prompt, language="text")
293
  st.write("**Analysis Output:**")
294
  st.code(result, language="text")
295
 
296
+ # Header with branded logo and description
297
+ col1, col2 = st.columns([1, 4])
298
+ with col1:
299
+ st.markdown("""
300
+ <div style="text-align: center; padding-top: 0.5rem;">
301
+ <svg width="50" height="50" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
302
+ <path d="M19.5 9.5l-7.5-7.5-7.5 7.5m15 0v8c0 1.1-.9 2-2 2h-11c-1.1 0-2-.9-2-2v-8" stroke="#1a73e8" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
303
+ <circle cx="12" cy="12" r="3" stroke="#1a73e8" stroke-width="2"/>
304
+ <path d="M12 15v3" stroke="#1a73e8" stroke-width="2" stroke-linecap="round"/>
305
+ </svg>
306
+ </div>
307
+ """, unsafe_allow_html=True)
308
+
309
+ with col2:
310
+ st.markdown('<span class="logo-text">Z-Agent News Analysis</span>', unsafe_allow_html=True)
311
+ st.markdown("""
312
+ <p style="color: #5f6368; font-size: 1rem; margin-top: -0.5rem;">
313
+ Intelligent news analysis powered by AI. Get comprehensive insights and multiple perspectives on any topic.
314
+ </p>
315
+ """, unsafe_allow_html=True)
316
 
317
+ # Main content area
318
+ st.markdown('<div class="card">', unsafe_allow_html=True)
 
 
 
 
319
 
320
  # Initialize the components
321
  try:
 
323
  llm = GroqLLM()
324
  search_tool = DuckDuckGoSearch()
325
 
326
+ # Input section with clear design
327
  news_topic = st.text_input(
328
+ "What news topic would you like to analyze?",
329
+ placeholder="E.g., Recent developments in renewable energy, Tech industry layoffs, Global climate agreements..."
330
  )
331
 
332
+ # Analysis options in a cleaner layout
333
+ col1, col2, col3 = st.columns([2, 2, 1])
334
+
335
  with col1:
336
  search_depth = st.slider(
337
+ "Search Depth",
338
  min_value=3,
339
  max_value=10,
340
+ value=5,
341
+ help="Number of news sources to analyze"
342
  )
343
+
344
  with col2:
345
  analysis_type = st.selectbox(
346
  "Analysis Type",
347
+ ["Comprehensive", "Quick Summary", "Technical", "Simplified"],
348
+ help="Choose the style and depth of analysis"
349
+ )
350
+
351
+ with col3:
352
+ time_period = st.selectbox(
353
+ "Time Period",
354
+ ["Last 7 days", "Last 30 days", "Last 24 hours"],
355
+ help="How recent should the news be"
356
  )
357
 
358
  # Generate analysis button
359
+ col1, col2 = st.columns([3, 1])
360
+ with col2:
361
+ analyze_button = st.button("Analyze News")
362
+
363
+ st.markdown('</div>', unsafe_allow_html=True)
364
+
365
+ # Results section
366
+ if analyze_button and news_topic:
367
+ with st.spinner(""):
368
+ try:
369
+ # Progress indicators with custom styling
370
+ progress_container = st.container()
371
+ progress_container.markdown('<div class="info-box">', unsafe_allow_html=True)
372
+ progress_placeholder = progress_container.empty()
373
+ progress_placeholder.markdown("πŸ”Ž **Searching for recent news sources...**", unsafe_allow_html=True)
374
+
375
+ # Determine time frame from selection
376
+ time_map = {
377
+ "Last 24 hours": "24h",
378
+ "Last 7 days": "7d",
379
+ "Last 30 days": "30d"
380
+ }
381
+ time_frame = time_map.get(time_period, "7d")
382
+
383
+ # Perform search
384
+ search_results = search_tool(
385
+ f"Latest news about {news_topic} {time_frame}",
386
+ max_results=search_depth
387
+ )
388
+
389
+ if not search_results.startswith(("Search error", "No results")):
390
+ # Update progress
391
+ progress_placeholder.markdown("🧠 **Analyzing search results and generating insights...**", unsafe_allow_html=True)
392
 
393
+ # Create analysis prompt
394
+ analysis_prompt = create_analysis_prompt(news_topic, search_results)
395
+
396
+ # Get analysis from LLM
397
+ analysis_result = llm(analysis_prompt)
398
+
399
+ # Clear progress messages
400
+ progress_container.empty()
401
 
402
+ # Display results in tabs for better organization
403
+ st.markdown('<div class="card">', unsafe_allow_html=True)
404
+ st.markdown(f'<h2>Analysis: {news_topic}</h2>', unsafe_allow_html=True)
405
+
406
+ tab1, tab2 = st.tabs(["πŸ“Š Analysis", "πŸ“° Sources"])
407
+
408
+ with tab1:
409
+ st.markdown('<div class="analysis-result">', unsafe_allow_html=True)
 
 
 
 
 
 
 
410
  st.markdown(analysis_result)
411
+ st.markdown('</div>', unsafe_allow_html=True)
412
+
413
+ with tab2:
414
+ st.markdown("### News Sources Used in Analysis")
415
+ # Parse and display sources in a more structured way
416
+ sources = search_results.split("\n\n")
417
+ for source in sources:
418
+ lines = source.strip().split("\n")
419
+ if len(lines) >= 5: # Ensure we have enough lines
420
+ title_line = lines[0].replace("1. Title: ", "").replace("2. Title: ", "").replace("3. Title: ", "").replace("4. Title: ", "").replace("5. Title: ", "")
421
+ date_line = lines[1].replace(" Date: ", "")
422
+ source_line = lines[2].replace(" Source: ", "")
423
+ url_line = lines[4].replace(" URL: ", "")
424
+
425
+ st.markdown(f"""
426
+ <div style="margin-bottom: 1rem; padding-bottom: 1rem; border-bottom: 1px solid #f0f0f0;">
427
+ <h4 style="margin-bottom: 0.2rem;">{title_line}</h4>
428
+ <p style="color: #5f6368; margin-bottom: 0.5rem; font-size: 0.9rem;">
429
+ {source_line} β€’ {date_line}
430
+ </p>
431
+ <a href="{url_line}" target="_blank">Read original article</a>
432
+ </div>
433
+ """, unsafe_allow_html=True)
434
+
435
+ st.markdown('</div>', unsafe_allow_html=True)
436
+
437
+ # Log the activity
438
+ log_agent_activity(
439
+ analysis_prompt,
440
+ analysis_result,
441
+ "News Analysis Agent"
442
+ )
443
+ else:
444
+ progress_container.empty()
445
+ st.error(f"πŸ˜• {search_results}")
446
+
447
+ except Exception as e:
448
+ st.error(f"An error occurred during analysis: {str(e)}")
449
+ elif analyze_button:
450
+ st.warning("Please enter a news topic to analyze.")
451
 
452
+ # Help section with visually appealing design
453
+ st.markdown('<div class="card">', unsafe_allow_html=True)
454
+ st.markdown('<h3>πŸ’‘ Tips for Better Results</h3>', unsafe_allow_html=True)
455
+
456
+ tips_col1, tips_col2 = st.columns(2)
457
+
458
+ with tips_col1:
459
+ st.markdown("""
460
+ - **Be specific** with your topic for more focused analysis
461
+ - Use **keywords** related to recent events for timely information
462
+ - Include **geographic locations** when relevant (e.g., "Climate policy in Europe")
463
  """)
464
+
465
+ with tips_col2:
466
+ st.markdown("""
467
+ - Try different **analysis types** for various perspectives
468
+ - For complex topics, start with a **broader search** then narrow down
469
+ - Adjust the **time period** to control recency of news sources
470
+ """)
471
+
472
+ st.markdown('</div>', unsafe_allow_html=True)
473
 
474
  except Exception as e:
475
  st.error(f"""
 
482
  3. You have internet connectivity for DuckDuckGo searches
483
  """)
484
 
485
+ # Footer with branding
486
  st.markdown("---")
487
+ st.markdown("""
488
+ <footer>
489
+ <div style="display: flex; justify-content: space-between; align-items: center;">
490
+ <div>
491
+ Z-Agent News Analysis Tool Β© 2025
492
+ </div>
493
+ <div>
494
+ Created for news analysis and research purposes
495
+ </div>
496
+ </div>
497
+ </footer>
498
+ """, unsafe_allow_html=True)