sagar007 commited on
Commit
ed0c3c5
·
verified ·
1 Parent(s): 60c475d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +62 -110
app.py CHANGED
@@ -1,26 +1,23 @@
1
  import gradio as gr
 
2
  from transformers import pipeline
3
  from duckduckgo_search import DDGS
4
  from datetime import datetime
5
- import asyncio
6
 
7
- # Initialize a lightweight text generation model (distilgpt2 for speed)
8
- generator = pipeline("text-generation", model="distilgpt2", device=0 if gr.cuda.is_available() else -1)
9
 
10
- # Web search function using DuckDuckGo
11
- async def get_web_results(query: str, max_results: int = 5) -> list:
12
- """Fetch web results asynchronously for deep research."""
13
  try:
14
  with DDGS() as ddgs:
15
- results = await asyncio.to_thread(lambda: list(ddgs.text(query, max_results=max_results)))
16
- return [
17
- {"title": r.get("title", "No Title"), "snippet": r["body"], "url": r["href"]}
18
- for r in results
19
- ]
20
  except Exception as e:
21
  return [{"title": "Error", "snippet": f"Failed to fetch results: {str(e)}", "url": "#"}]
22
 
23
- # Format prompt for the AI model
24
  def format_prompt(query: str, web_results: list) -> str:
25
  """Create a concise prompt with web context."""
26
  current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
@@ -29,70 +26,50 @@ def format_prompt(query: str, web_results: list) -> str:
29
  Query: {query}
30
  Web Context:
31
  {context}
32
- Provide a detailed, well-structured answer in markdown format with citations [1], [2], etc."""
33
 
34
- # Generate answer using the AI model
 
35
  def generate_answer(prompt: str) -> str:
36
- """Generate a detailed research answer."""
37
- response = generator(prompt, max_length=300, num_return_sequences=1, truncation=True)[0]["generated_text"]
38
- # Extract the answer after the prompt
39
- answer_start = response.find("Provide a detailed") + len("Provide a detailed, well-structured answer in markdown format with citations [1], [2], etc.")
40
- return response[answer_start:].strip()
41
 
42
- # Format sources for display
43
  def format_sources(web_results: list) -> str:
44
- """Create an HTML list of sources."""
45
  if not web_results:
46
  return "<div>No sources available</div>"
47
-
48
  sources_html = "<div class='sources-list'>"
49
  for i, res in enumerate(web_results, 1):
50
  sources_html += f"""
51
  <div class='source-item'>
52
  <span class='source-number'>[{i}]</span>
53
- <a href='{res['url']}' target='_blank'>{res['title']}</a>: {res['snippet'][:150]}...
54
  </div>
55
  """
56
  sources_html += "</div>"
57
  return sources_html
58
 
59
  # Main processing function
60
- async def process_deep_research(query: str, history: list):
61
- """Handle the deep research process with progressive updates."""
62
  if not history:
63
  history = []
64
 
65
- # Step 1: Initial loading state
66
- yield {
67
- "answer": "*Searching the web...*",
68
- "sources": "<div>Fetching sources...</div>",
69
- "history": history + [[query, "*Searching...*"]]
70
- }
71
-
72
- # Step 2: Fetch web results
73
- web_results = await get_web_results(query)
74
  sources_html = format_sources(web_results)
75
 
76
- # Step 3: Update with web search completed
77
- yield {
78
- "answer": "*Analyzing results...*",
79
- "sources": sources_html,
80
- "history": history + [[query, "*Analyzing...*"]]
81
- }
82
-
83
- # Step 4: Generate detailed answer
84
  prompt = format_prompt(query, web_results)
85
  answer = generate_answer(prompt)
86
  final_history = history + [[query, answer]]
87
 
88
- # Step 5: Final result
89
- yield {
90
- "answer": answer,
91
- "sources": sources_html,
92
- "history": final_history
93
- }
94
 
95
- # Custom CSS for a cool, modern UI
96
  css = """
97
  body {
98
  font-family: 'Arial', sans-serif;
@@ -100,31 +77,24 @@ body {
100
  color: #ffffff;
101
  }
102
  .gradio-container {
103
- max-width: 1000px;
104
  margin: 0 auto;
105
- padding: 20px;
106
  }
107
  .header {
108
  text-align: center;
109
- padding: 20px;
110
  background: linear-gradient(135deg, #2c3e50, #3498db);
111
- border-radius: 10px;
112
- margin-bottom: 20px;
113
- }
114
- .header h1 {
115
- font-size: 2.5em;
116
- margin: 0;
117
- color: #ffffff;
118
- }
119
- .header p {
120
- color: #bdc3c7;
121
- font-size: 1.1em;
122
  }
 
 
123
  .search-box {
124
  background: #2c2c2c;
125
- padding: 15px;
126
- border-radius: 10px;
127
- box-shadow: 0 4px 10px rgba(0, 0, 0, 0.3);
128
  }
129
  .search-box input {
130
  background: #3a3a3a !important;
@@ -136,68 +106,50 @@ body {
136
  background: #3498db !important;
137
  border: none !important;
138
  border-radius: 5px !important;
139
- transition: background 0.3s;
140
- }
141
- .search-box button:hover {
142
- background: #2980b9 !important;
143
  }
144
  .results-container {
145
- margin-top: 20px;
146
  display: flex;
147
- gap: 20px;
148
  }
149
  .answer-box {
150
  flex: 2;
151
  background: #2c2c2c;
152
- padding: 20px;
153
- border-radius: 10px;
154
- box-shadow: 0 4px 10px rgba(0, 0, 0, 0.3);
155
- }
156
- .answer-box .markdown {
157
- color: #ecf0f1;
158
- line-height: 1.6;
159
  }
 
160
  .sources-list {
161
  flex: 1;
162
  background: #2c2c2c;
163
- padding: 15px;
164
- border-radius: 10px;
165
- box-shadow: 0 4px 10px rgba(0, 0, 0, 0.3);
166
- }
167
- .source-item {
168
- margin-bottom: 10px;
169
- }
170
- .source-number {
171
- color: #3498db;
172
- font-weight: bold;
173
- margin-right: 5px;
174
- }
175
- .source-item a {
176
- color: #3498db;
177
- text-decoration: none;
178
- }
179
- .source-item a:hover {
180
- text-decoration: underline;
181
- }
182
  .history-box {
183
- margin-top: 20px;
184
  background: #2c2c2c;
185
- padding: 15px;
186
- border-radius: 10px;
187
- max-height: 300px;
188
  overflow-y: auto;
189
- box-shadow: 0 4px 10px rgba(0, 0, 0, 0.3);
190
  }
191
  """
192
 
193
- # Gradio app setup with Blocks for better control
194
- with gr.Blocks(title="Deep Research Engine", css=css) as demo:
195
  history_state = gr.State([])
196
 
197
  # Header
198
  with gr.Column(elem_classes="header"):
199
  gr.Markdown("# Deep Research Engine")
200
- gr.Markdown("Your gateway to in-depth answers with real-time web insights.")
201
 
202
  # Search input and button
203
  with gr.Row(elem_classes="search-box"):
@@ -216,15 +168,15 @@ with gr.Blocks(title="Deep Research Engine", css=css) as demo:
216
  history_display = gr.Chatbot(label="History", elem_classes="history-box")
217
 
218
  # Event handling
219
- async def handle_search(query, history):
220
- async for step in process_deep_research(query, history):
221
- yield step["answer"], step["sources"], step["history"]
222
 
223
  search_btn.click(
224
  fn=handle_search,
225
  inputs=[search_input, history_state],
226
  outputs=[answer_output, sources_output, history_display],
227
- _js="() => [document.querySelector('.search-box input').value, null]" # Ensure history is managed
228
  ).then(
229
  fn=lambda x: x,
230
  inputs=[history_display],
 
1
  import gradio as gr
2
+ import spaces # Required for ZeroGPU
3
  from transformers import pipeline
4
  from duckduckgo_search import DDGS
5
  from datetime import datetime
 
6
 
7
+ # Initialize a lightweight text generation model on CPU (moves to GPU when decorated)
8
+ generator = pipeline("text-generation", model="distilgpt2", device=-1) # -1 ensures CPU by default
9
 
10
+ # Web search function (CPU-based)
11
+ def get_web_results(query: str, max_results: int = 3) -> list:
12
+ """Fetch web results synchronously for Zero GPU compatibility."""
13
  try:
14
  with DDGS() as ddgs:
15
+ results = list(ddgs.text(query, max_results=max_results))
16
+ return [{"title": r.get("title", "No Title"), "snippet": r["body"], "url": r["href"]} for r in results]
 
 
 
17
  except Exception as e:
18
  return [{"title": "Error", "snippet": f"Failed to fetch results: {str(e)}", "url": "#"}]
19
 
20
+ # Format prompt for the AI model (CPU-based)
21
  def format_prompt(query: str, web_results: list) -> str:
22
  """Create a concise prompt with web context."""
23
  current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
 
26
  Query: {query}
27
  Web Context:
28
  {context}
29
+ Provide a concise answer in markdown format with citations [1], [2], etc."""
30
 
31
+ # GPU-decorated answer generation
32
+ @spaces.GPU(duration=120) # Allow up to 120 seconds of GPU time
33
  def generate_answer(prompt: str) -> str:
34
+ """Generate a concise research answer using GPU."""
35
+ response = generator(prompt, max_length=200, num_return_sequences=1, truncation=True)[0]["generated_text"]
36
+ answer_start = response.find("Provide a concise") + len("Provide a concise answer in markdown format with citations [1], [2], etc.")
37
+ return response[answer_start:].strip() if answer_start > -1 else "No detailed answer generated."
 
38
 
39
+ # Format sources for display (CPU-based)
40
  def format_sources(web_results: list) -> str:
41
+ """Create a simple HTML list of sources."""
42
  if not web_results:
43
  return "<div>No sources available</div>"
 
44
  sources_html = "<div class='sources-list'>"
45
  for i, res in enumerate(web_results, 1):
46
  sources_html += f"""
47
  <div class='source-item'>
48
  <span class='source-number'>[{i}]</span>
49
+ <a href='{res['url']}' target='_blank'>{res['title']}</a>: {res['snippet'][:100]}...
50
  </div>
51
  """
52
  sources_html += "</div>"
53
  return sources_html
54
 
55
  # Main processing function
56
+ def process_deep_research(query: str, history: list):
57
+ """Handle the deep research process."""
58
  if not history:
59
  history = []
60
 
61
+ # Fetch web results (CPU)
62
+ web_results = get_web_results(query)
 
 
 
 
 
 
 
63
  sources_html = format_sources(web_results)
64
 
65
+ # Generate answer (GPU via @spaces.GPU)
 
 
 
 
 
 
 
66
  prompt = format_prompt(query, web_results)
67
  answer = generate_answer(prompt)
68
  final_history = history + [[query, answer]]
69
 
70
+ return answer, sources_html, final_history
 
 
 
 
 
71
 
72
+ # Custom CSS for a cool, lightweight UI
73
  css = """
74
  body {
75
  font-family: 'Arial', sans-serif;
 
77
  color: #ffffff;
78
  }
79
  .gradio-container {
80
+ max-width: 900px;
81
  margin: 0 auto;
82
+ padding: 15px;
83
  }
84
  .header {
85
  text-align: center;
86
+ padding: 15px;
87
  background: linear-gradient(135deg, #2c3e50, #3498db);
88
+ border-radius: 8px;
89
+ margin-bottom: 15px;
 
 
 
 
 
 
 
 
 
90
  }
91
+ .header h1 { font-size: 2em; margin: 0; color: #ffffff; }
92
+ .header p { color: #bdc3c7; font-size: 1em; }
93
  .search-box {
94
  background: #2c2c2c;
95
+ padding: 10px;
96
+ border-radius: 8px;
97
+ box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
98
  }
99
  .search-box input {
100
  background: #3a3a3a !important;
 
106
  background: #3498db !important;
107
  border: none !important;
108
  border-radius: 5px !important;
 
 
 
 
109
  }
110
  .results-container {
111
+ margin-top: 15px;
112
  display: flex;
113
+ gap: 15px;
114
  }
115
  .answer-box {
116
  flex: 2;
117
  background: #2c2c2c;
118
+ padding: 15px;
119
+ border-radius: 8px;
120
+ box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
 
 
 
 
121
  }
122
+ .answer-box .markdown { color: #ecf0f1; line-height: 1.5; }
123
  .sources-list {
124
  flex: 1;
125
  background: #2c2c2c;
126
+ padding: 10px;
127
+ border-radius: 8px;
128
+ box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
129
+ }
130
+ .source-item { margin-bottom: 8px; }
131
+ .source-number { color: #3498db; font-weight: bold; margin-right: 5px; }
132
+ .source-item a { color: #3498db; text-decoration: none; }
133
+ .source-item a:hover { text-decoration: underline; }
 
 
 
 
 
 
 
 
 
 
 
134
  .history-box {
135
+ margin-top: 15px;
136
  background: #2c2c2c;
137
+ padding: 10px;
138
+ border-radius: 8px;
139
+ max-height: 250px;
140
  overflow-y: auto;
141
+ box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
142
  }
143
  """
144
 
145
+ # Gradio app setup with Blocks
146
+ with gr.Blocks(title="Deep Research Engine - ZeroGPU", css=css) as demo:
147
  history_state = gr.State([])
148
 
149
  # Header
150
  with gr.Column(elem_classes="header"):
151
  gr.Markdown("# Deep Research Engine")
152
+ gr.Markdown("Fast, in-depth answers powered by web insights (ZeroGPU).")
153
 
154
  # Search input and button
155
  with gr.Row(elem_classes="search-box"):
 
168
  history_display = gr.Chatbot(label="History", elem_classes="history-box")
169
 
170
  # Event handling
171
+ def handle_search(query, history):
172
+ answer, sources, new_history = process_deep_research(query, history)
173
+ return answer, sources, new_history
174
 
175
  search_btn.click(
176
  fn=handle_search,
177
  inputs=[search_input, history_state],
178
  outputs=[answer_output, sources_output, history_display],
179
+ _js="() => [document.querySelector('.search-box input').value, null]"
180
  ).then(
181
  fn=lambda x: x,
182
  inputs=[history_display],