Luis Vizcaya commited on
Commit
7cfb6fe
·
1 Parent(s): 87c82dc

Complete refactor of app.py state to dictionary

Browse files
Files changed (1) hide show
  1. app.py +38 -58
app.py CHANGED
@@ -40,35 +40,20 @@ theme = gr.themes.Soft(
40
  secondary_hue="slate",
41
  neutral_hue="slate",
42
  font=[gr.themes.GoogleFont('Inter'), 'sans-serif'],
43
- ).set(
44
- button_primary_background_fill='linear-gradient(90deg, #4f46e5 0%, #3b82f6 100%)',
45
- button_primary_background_fill_hover='linear-gradient(90deg, #4338ca 0%, #2563eb 100%)',
46
  )
47
 
48
- class ResearchState:
49
- def __init__(self):
50
- self.initial_topic = ""
51
- self.suggestions = []
52
- self.final_topic = ""
53
- self.research_plan = ""
54
- self.subtasks = []
55
- self.final_report = ""
56
- self.pdf_data = None
57
- self.pdf_path = ""
58
-
59
  def start_clarification(topic, hf_key, state):
60
  if not topic:
61
  return gr.update(), "Please enter a topic.", state, gr.update()
62
  if not hf_key:
63
  return gr.update(), "Please provide an HF Token.", state, gr.update()
64
 
65
- state.initial_topic = topic
66
  clarifier = Clarifier(model_name=CLARIFIER_MODEL, hf_key=hf_key)
67
  try:
68
  suggestions = clarifier.get_suggestions(topic)
69
- state.suggestions = suggestions
70
 
71
- # Format suggestions for the UI
72
  suggestion_md = "### Refine Your Topic\n\nChoose one of the suggested directions or enter a custom one below:\n\n"
73
  for i, s in enumerate(suggestions):
74
  suggestion_md += f"**Option {i+1}: {s['title']}**\n{s['description']}\n\n"
@@ -78,21 +63,21 @@ def start_clarification(topic, hf_key, state):
78
  return gr.update(), f"Error: {e}", state, gr.update()
79
 
80
  def select_suggestion(index, custom_topic, state):
81
- if custom_topic.strip():
82
- state.final_topic = custom_topic
83
- elif index is not None and 0 <= int(index)-1 < len(state.suggestions):
84
- sug = state.suggestions[int(index)-1]
85
- state.final_topic = f"{sug['title']}: {sug['description']}"
86
  else:
87
- return gr.update(), "Please select an option or enter a custom topic.", state
88
 
89
- return gr.update(visible=True), f"Targeting: **{state.final_topic}**", state, gr.update(visible=False)
90
 
91
  def generate_strategy(hf_key, state):
92
  planner = Planner(model_name=PLANNER_MODEL, hf_key=hf_key)
93
  try:
94
- plan = planner.plan(state.final_topic)
95
- state.research_plan = plan
96
  return gr.update(visible=True), plan, state, gr.update(visible=False)
97
  except Exception as e:
98
  return gr.update(), f"Error: {e}", state, gr.update()
@@ -100,8 +85,8 @@ def generate_strategy(hf_key, state):
100
  def decompose_tasks(hf_key, state):
101
  splitter = Splitter(model_name=SPLITTER_MODEL, hf_key=hf_key)
102
  try:
103
- subtasks = splitter.split(state.research_plan)
104
- state.subtasks = subtasks
105
 
106
  tasks_md = "### 📋 Generated Subtasks\n\n"
107
  for task in subtasks:
@@ -144,7 +129,7 @@ def run_research(hf_key, tavily_key, state):
144
  current_findings = []
145
  log_content = "### 🔍 Agentic Research Progress\n\n"
146
 
147
- for i, task in enumerate(state.subtasks):
148
  t_id = task['id']
149
  t_title = task['title']
150
  t_desc = task['description']
@@ -159,8 +144,8 @@ def run_research(hf_key, tavily_key, state):
159
  max_steps=2
160
  )
161
  prompt = SUBAGENT_DIRECTION.format(
162
- user_query=state.final_topic,
163
- research_plan=state.research_plan,
164
  subtask_id=t_id,
165
  subtask_title=t_title,
166
  subtask_description=t_desc
@@ -179,9 +164,9 @@ def run_research(hf_key, tavily_key, state):
179
  yield log_content, state, gr.update(), gr.update()
180
 
181
  sys_prompt = COORDINATOR_DIRECTION.format(
182
- user_query=state.final_topic,
183
- research_plan=state.research_plan,
184
- subtasks_json=json.dumps(state.subtasks, indent=2)
185
  )
186
  user_prompt = f"Synthesize these findings:\n\n" + "\n\n".join(current_findings)
187
 
@@ -202,16 +187,19 @@ def run_research(hf_key, tavily_key, state):
202
 
203
  reviewer = Reviewer(model_name=REVIEWER_MODEL, hf_key=hf_key)
204
  polished_report = reviewer.review(final_report)
205
- state.final_report = polished_report
206
 
207
  os.makedirs("temp_outputs", exist_ok=True)
208
- pdf_path = f"temp_outputs/research_{int(time.time())}.pdf"
 
209
  if reviewer.generate_pdf(polished_report, pdf_path):
210
- state.pdf_path = pdf_path
211
 
212
- md_path = f"temp_outputs/research_{int(time.time())}.md"
 
213
  with open(md_path, "w", encoding="utf-8") as f:
214
  f.write(polished_report)
 
215
 
216
  yield log_content + "✅ Research mission accomplished!", state, gr.update(visible=True), polished_report
217
  except Exception as e:
@@ -219,18 +207,18 @@ def run_research(hf_key, tavily_key, state):
219
 
220
  def reset_all():
221
  return (
222
- gr.update(value="", visible=True), # topic_input
223
- gr.update(visible=False), # step2_col
224
- gr.update(visible=False), # step3_col
225
- gr.update(visible=False), # step4_col
226
- gr.update(visible=False), # step5_col
227
- ResearchState(), # state
228
- "", # log_output
229
- "" # final_md_display
230
  )
231
 
232
  with gr.Blocks(theme=theme, title="Deep Research Agent") as demo:
233
- state = gr.State(ResearchState())
234
 
235
  gr.Markdown("# 🧬 Deep Research Agent")
236
  gr.Markdown("### The ultimate AI research pipeline that browses the web for you.")
@@ -246,14 +234,11 @@ with gr.Blocks(theme=theme, title="Deep Research Agent") as demo:
246
  log_output = gr.Markdown("Ready to research.")
247
 
248
  with gr.Column(scale=4):
249
- # --- STEP 1 ---
250
  with gr.Column(visible=True) as step1_col:
251
  gr.Markdown("## 1️⃣ What are you researching?")
252
  topic_input = gr.Textbox(label="Enter a broad topic or research question:", placeholder="e.g., The impact of AI on specialized legal services")
253
  start_btn = gr.Button("Start Clarification", variant="primary")
254
- step1_msg = gr.Markdown()
255
 
256
- # --- STEP 2 ---
257
  with gr.Column(visible=False) as step2_col:
258
  gr.Markdown("## 2️⃣ Refine Your Topic")
259
  suggestion_display = gr.Markdown()
@@ -261,9 +246,7 @@ with gr.Blocks(theme=theme, title="Deep Research Agent") as demo:
261
  opt_index = gr.Dropdown(choices=["1", "2", "3"], label="Select Option")
262
  custom_topic_input = gr.Textbox(label="Or type your own refined topic:")
263
  refine_btn = gr.Button("Use Selected/Custom Topic", variant="primary")
264
- step2_msg = gr.Markdown()
265
 
266
- # --- STEP 3 ---
267
  with gr.Column(visible=False) as step3_col:
268
  gr.Markdown("## 3️⃣ Strategy & Task Splitting")
269
  target_display = gr.Markdown()
@@ -273,13 +256,10 @@ with gr.Blocks(theme=theme, title="Deep Research Agent") as demo:
273
  tasks_display = gr.Markdown(visible=False)
274
  execute_btn = gr.Button("🚀 Execute Research Agents", variant="primary", visible=False)
275
 
276
- # --- STEP 4 ---
277
  with gr.Column(visible=False) as step4_col:
278
  gr.Markdown("## 4️⃣ Agentic Research in Progress")
279
- # Removed log_output from here since it's move to the sidebar
280
  gr.Markdown("Agents are browsing the web... check the status panel!")
281
 
282
- # --- STEP 5 ---
283
  with gr.Column(visible=False) as step5_col:
284
  gr.Markdown("## 🏁 Final Research Report")
285
  final_md_display = gr.Markdown()
@@ -288,7 +268,6 @@ with gr.Blocks(theme=theme, title="Deep Research Agent") as demo:
288
  download_pdf = gr.File(label="Download PDF")
289
  new_research_btn = gr.Button("Start New Research", variant="primary")
290
 
291
- # --- CALLBACKS ---
292
  start_btn.click(
293
  start_clarification,
294
  inputs=[topic_input, hf_key_input, state],
@@ -324,9 +303,9 @@ with gr.Blocks(theme=theme, title="Deep Research Agent") as demo:
324
  inputs=[hf_key_input, tavily_key_input, state],
325
  outputs=[log_output, state, step5_col, final_md_display]
326
  ).then(
327
- lambda s: [s.pdf_path, s.pdf_path.replace(".pdf", ".md") if s.pdf_path else None],
328
  inputs=[state],
329
- outputs=[download_pdf, download_md]
330
  )
331
 
332
  reset_btn.click(
@@ -340,4 +319,5 @@ with gr.Blocks(theme=theme, title="Deep Research Agent") as demo:
340
  )
341
 
342
  if __name__ == "__main__":
 
343
  demo.launch()
 
40
  secondary_hue="slate",
41
  neutral_hue="slate",
42
  font=[gr.themes.GoogleFont('Inter'), 'sans-serif'],
 
 
 
43
  )
44
 
 
 
 
 
 
 
 
 
 
 
 
45
  def start_clarification(topic, hf_key, state):
46
  if not topic:
47
  return gr.update(), "Please enter a topic.", state, gr.update()
48
  if not hf_key:
49
  return gr.update(), "Please provide an HF Token.", state, gr.update()
50
 
51
+ state["initial_topic"] = topic
52
  clarifier = Clarifier(model_name=CLARIFIER_MODEL, hf_key=hf_key)
53
  try:
54
  suggestions = clarifier.get_suggestions(topic)
55
+ state["suggestions"] = suggestions
56
 
 
57
  suggestion_md = "### Refine Your Topic\n\nChoose one of the suggested directions or enter a custom one below:\n\n"
58
  for i, s in enumerate(suggestions):
59
  suggestion_md += f"**Option {i+1}: {s['title']}**\n{s['description']}\n\n"
 
63
  return gr.update(), f"Error: {e}", state, gr.update()
64
 
65
  def select_suggestion(index, custom_topic, state):
66
+ if custom_topic and custom_topic.strip():
67
+ state["final_topic"] = custom_topic
68
+ elif index is not None and 0 <= int(index)-1 < len(state.get("suggestions", [])):
69
+ sug = state["suggestions"][int(index)-1]
70
+ state["final_topic"] = f"{sug['title']}: {sug['description']}"
71
  else:
72
+ return gr.update(), "Please select an option or enter a custom topic.", state, gr.update()
73
 
74
+ return gr.update(visible=True), f"Targeting: **{state['final_topic']}**", state, gr.update(visible=False)
75
 
76
  def generate_strategy(hf_key, state):
77
  planner = Planner(model_name=PLANNER_MODEL, hf_key=hf_key)
78
  try:
79
+ plan = planner.plan(state["final_topic"])
80
+ state["research_plan"] = plan
81
  return gr.update(visible=True), plan, state, gr.update(visible=False)
82
  except Exception as e:
83
  return gr.update(), f"Error: {e}", state, gr.update()
 
85
  def decompose_tasks(hf_key, state):
86
  splitter = Splitter(model_name=SPLITTER_MODEL, hf_key=hf_key)
87
  try:
88
+ subtasks = splitter.split(state["research_plan"])
89
+ state["subtasks"] = subtasks
90
 
91
  tasks_md = "### 📋 Generated Subtasks\n\n"
92
  for task in subtasks:
 
129
  current_findings = []
130
  log_content = "### 🔍 Agentic Research Progress\n\n"
131
 
132
+ for i, task in enumerate(state.get("subtasks", [])):
133
  t_id = task['id']
134
  t_title = task['title']
135
  t_desc = task['description']
 
144
  max_steps=2
145
  )
146
  prompt = SUBAGENT_DIRECTION.format(
147
+ user_query=state["final_topic"],
148
+ research_plan=state["research_plan"],
149
  subtask_id=t_id,
150
  subtask_title=t_title,
151
  subtask_description=t_desc
 
164
  yield log_content, state, gr.update(), gr.update()
165
 
166
  sys_prompt = COORDINATOR_DIRECTION.format(
167
+ user_query=state["final_topic"],
168
+ research_plan=state["research_plan"],
169
+ subtasks_json=json.dumps(state["subtasks"], indent=2)
170
  )
171
  user_prompt = f"Synthesize these findings:\n\n" + "\n\n".join(current_findings)
172
 
 
187
 
188
  reviewer = Reviewer(model_name=REVIEWER_MODEL, hf_key=hf_key)
189
  polished_report = reviewer.review(final_report)
190
+ state["final_report"] = polished_report
191
 
192
  os.makedirs("temp_outputs", exist_ok=True)
193
+ pdf_name = f"research_{int(time.time())}.pdf"
194
+ pdf_path = os.path.join("temp_outputs", pdf_name)
195
  if reviewer.generate_pdf(polished_report, pdf_path):
196
+ state["pdf_path"] = pdf_path
197
 
198
+ md_name = f"research_{int(time.time())}.md"
199
+ md_path = os.path.join("temp_outputs", md_name)
200
  with open(md_path, "w", encoding="utf-8") as f:
201
  f.write(polished_report)
202
+ state["md_path"] = md_path
203
 
204
  yield log_content + "✅ Research mission accomplished!", state, gr.update(visible=True), polished_report
205
  except Exception as e:
 
207
 
208
  def reset_all():
209
  return (
210
+ gr.update(value="", visible=True),
211
+ gr.update(visible=False),
212
+ gr.update(visible=False),
213
+ gr.update(visible=False),
214
+ gr.update(visible=False),
215
+ {},
216
+ "Ready to research.",
217
+ ""
218
  )
219
 
220
  with gr.Blocks(theme=theme, title="Deep Research Agent") as demo:
221
+ state = gr.State({})
222
 
223
  gr.Markdown("# 🧬 Deep Research Agent")
224
  gr.Markdown("### The ultimate AI research pipeline that browses the web for you.")
 
234
  log_output = gr.Markdown("Ready to research.")
235
 
236
  with gr.Column(scale=4):
 
237
  with gr.Column(visible=True) as step1_col:
238
  gr.Markdown("## 1️⃣ What are you researching?")
239
  topic_input = gr.Textbox(label="Enter a broad topic or research question:", placeholder="e.g., The impact of AI on specialized legal services")
240
  start_btn = gr.Button("Start Clarification", variant="primary")
 
241
 
 
242
  with gr.Column(visible=False) as step2_col:
243
  gr.Markdown("## 2️⃣ Refine Your Topic")
244
  suggestion_display = gr.Markdown()
 
246
  opt_index = gr.Dropdown(choices=["1", "2", "3"], label="Select Option")
247
  custom_topic_input = gr.Textbox(label="Or type your own refined topic:")
248
  refine_btn = gr.Button("Use Selected/Custom Topic", variant="primary")
 
249
 
 
250
  with gr.Column(visible=False) as step3_col:
251
  gr.Markdown("## 3️⃣ Strategy & Task Splitting")
252
  target_display = gr.Markdown()
 
256
  tasks_display = gr.Markdown(visible=False)
257
  execute_btn = gr.Button("🚀 Execute Research Agents", variant="primary", visible=False)
258
 
 
259
  with gr.Column(visible=False) as step4_col:
260
  gr.Markdown("## 4️⃣ Agentic Research in Progress")
 
261
  gr.Markdown("Agents are browsing the web... check the status panel!")
262
 
 
263
  with gr.Column(visible=False) as step5_col:
264
  gr.Markdown("## 🏁 Final Research Report")
265
  final_md_display = gr.Markdown()
 
268
  download_pdf = gr.File(label="Download PDF")
269
  new_research_btn = gr.Button("Start New Research", variant="primary")
270
 
 
271
  start_btn.click(
272
  start_clarification,
273
  inputs=[topic_input, hf_key_input, state],
 
303
  inputs=[hf_key_input, tavily_key_input, state],
304
  outputs=[log_output, state, step5_col, final_md_display]
305
  ).then(
306
+ lambda s: (s.get("md_path"), s.get("pdf_path")),
307
  inputs=[state],
308
+ outputs=[download_md, download_pdf]
309
  )
310
 
311
  reset_btn.click(
 
319
  )
320
 
321
  if __name__ == "__main__":
322
+ demo.queue()
323
  demo.launch()