Spaces:
Sleeping
Sleeping
Luis Vizcaya commited on
Commit ·
7cfb6fe
1
Parent(s): 87c82dc
Complete refactor of app.py state to dictionary
Browse files
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
|
| 66 |
clarifier = Clarifier(model_name=CLARIFIER_MODEL, hf_key=hf_key)
|
| 67 |
try:
|
| 68 |
suggestions = clarifier.get_suggestions(topic)
|
| 69 |
-
state
|
| 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
|
| 83 |
-
elif index is not None and 0 <= int(index)-1 < len(state.suggestions):
|
| 84 |
-
sug = state
|
| 85 |
-
state
|
| 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
|
| 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
|
| 95 |
-
state
|
| 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
|
| 104 |
-
state
|
| 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
|
| 163 |
-
research_plan=state
|
| 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
|
| 183 |
-
research_plan=state
|
| 184 |
-
subtasks_json=json.dumps(state
|
| 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
|
| 206 |
|
| 207 |
os.makedirs("temp_outputs", exist_ok=True)
|
| 208 |
-
|
|
|
|
| 209 |
if reviewer.generate_pdf(polished_report, pdf_path):
|
| 210 |
-
state
|
| 211 |
|
| 212 |
-
|
|
|
|
| 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),
|
| 223 |
-
gr.update(visible=False),
|
| 224 |
-
gr.update(visible=False),
|
| 225 |
-
gr.update(visible=False),
|
| 226 |
-
gr.update(visible=False),
|
| 227 |
-
|
| 228 |
-
"",
|
| 229 |
-
""
|
| 230 |
)
|
| 231 |
|
| 232 |
with gr.Blocks(theme=theme, title="Deep Research Agent") as demo:
|
| 233 |
-
state = gr.State(
|
| 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:
|
| 328 |
inputs=[state],
|
| 329 |
-
outputs=[
|
| 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()
|