pratik33 commited on
Commit
25851c8
·
verified ·
1 Parent(s): 23c10dd

Upload folder using huggingface_hub

Browse files
README.md CHANGED
@@ -1,12 +1,6 @@
1
  ---
2
- title: 'Deep Reaserch '
3
- emoji: 🏃
4
- colorFrom: purple
5
- colorTo: yellow
6
  sdk: gradio
7
- sdk_version: 5.33.1
8
- app_file: app.py
9
- pinned: false
10
  ---
11
-
12
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: Deep_Reaserch_
3
+ app_file: deep_research.py
 
 
4
  sdk: gradio
5
+ sdk_version: 5.31.0
 
 
6
  ---
 
 
clarify_agent.py ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from agents import Agent
2
+
3
+ INSTRUCTIONS = (
4
+ "You are a clarification agent. You will be given a research query, your job is to generate a list of questions that user has to answer to clarify the query."
5
+ "The questions should narrow down the scope of the research to a more specific topic, by asking questions that explore the intention of the user that he or she forgot to include in the query."
6
+ )
7
+
8
+ clarify_agent = Agent(
9
+ name="ClarifyAgent",
10
+ instructions=INSTRUCTIONS,
11
+ model="gpt-4o-mini",
12
+ output_type=str,
13
+ )
14
+
deep_research.py ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from dotenv import load_dotenv
3
+ from research_manager import ResearchManager
4
+
5
+ load_dotenv(override=True)
6
+
7
+
8
+ async def do_research(query: str, clarification_questions: str, clarification_answers: str):
9
+ research_input = f"Original Query: {query}\n\nClarification Questions: {clarification_questions}\n\nClarification Answers: {clarification_answers}"
10
+ async for chunk in ResearchManager().conduct_research(research_input):
11
+ yield chunk
12
+
13
+ async def ask_clarification_questions(query: str):
14
+ return await ResearchManager().generate_clarification_questions(query)
15
+
16
+ with gr.Blocks(theme=gr.themes.Default(primary_hue="sky")) as ui:
17
+ gr.Markdown("# Deep Research")
18
+ query_textbox = gr.Textbox(label="What topic would you like to research?")
19
+
20
+ clarify_button = gr.Button("Generate Clarification Questions", variant="primary")
21
+ gr.Markdown("# Clarification Questions")
22
+ clarification_questions = gr.Markdown(label="Clarification Questions")
23
+ query_textbox.submit(fn=ask_clarification_questions, inputs=query_textbox, outputs=clarification_questions)
24
+ clarify_button.click(fn=ask_clarification_questions, inputs=query_textbox, outputs=clarification_questions)
25
+
26
+ clarification_answers_textbox = gr.Textbox(label="Answer the clarification questions...")
27
+
28
+ do_research_button = gr.Button("Do Research", variant="primary")
29
+ gr.Markdown("# Report")
30
+ report = gr.Markdown(label="Report")
31
+ do_research_button.click(fn=do_research, inputs=[query_textbox, clarification_questions, clarification_answers_textbox], outputs=report)
32
+ clarification_answers_textbox.submit(fn=do_research, inputs=[query_textbox, clarification_questions, clarification_answers_textbox], outputs=report)
33
+
34
+ ui.launch(inbrowser=True)
35
+
email_agent.py ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from typing import Dict
3
+
4
+ import sendgrid
5
+ from sendgrid.helpers.mail import Email, Mail, Content, To
6
+ from agents import Agent, function_tool
7
+
8
+ @function_tool
9
+ def send_email(subject: str, html_body: str) -> Dict[str, str]:
10
+ """ Send an email with the given subject and HTML body """
11
+ sg = sendgrid.SendGridAPIClient(api_key=os.environ.get('SENDGRID_API_KEY'))
12
+ from_email = Email("pratikmore33@gmail.com") # put your verified sender here
13
+ to_email = To("pratik.more@3pillarglobal.com") # put your recipient here
14
+ content = Content("text/html", html_body)
15
+ mail = Mail(from_email, to_email, subject, content).get()
16
+ response = sg.client.mail.send.post(request_body=mail)
17
+ print("Email response", response.status_code)
18
+ return {"status": "success"}
19
+
20
+ INSTRUCTIONS = """You are able to send a nicely formatted HTML email based on a detailed report.
21
+ You will be provided with a detailed report. You should use your tool to send one email, providing the
22
+ report converted into clean, well presented HTML with an appropriate subject line."""
23
+
24
+ email_agent = Agent(
25
+ name="Email agent",
26
+ instructions=INSTRUCTIONS,
27
+ tools=[send_email],
28
+ model="gpt-4o-mini",
29
+ )
planner_agent.py ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from pydantic import BaseModel, Field
2
+ from agents import Agent
3
+
4
+ HOW_MANY_SEARCHES = 5
5
+
6
+ INSTRUCTIONS = f"You are a helpful research assistant. Given a query, come up with a set of web searches \
7
+ to perform to best answer the query. Output {HOW_MANY_SEARCHES} terms to query for."
8
+
9
+
10
+ class WebSearchItem(BaseModel):
11
+ reason: str = Field(description="Your reasoning for why this search is important to the query.")
12
+ query: str = Field(description="The search term to use for the web search.")
13
+
14
+
15
+ class WebSearchPlan(BaseModel):
16
+ searches: list[WebSearchItem] = Field(description="A list of web searches to perform to best answer the query.")
17
+
18
+ planner_agent = Agent(
19
+ name="PlannerAgent",
20
+ instructions=INSTRUCTIONS,
21
+ model="gpt-4o-mini",
22
+ output_type=WebSearchPlan,
23
+ )
research_manager.py ADDED
@@ -0,0 +1,100 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from agents import Runner, trace, gen_trace_id
2
+ from search_agent import search_agent
3
+ from planner_agent import planner_agent, WebSearchItem, WebSearchPlan
4
+ from writer_agent import writer_agent, ReportData
5
+ from email_agent import email_agent
6
+ from clarify_agent import clarify_agent
7
+ import asyncio
8
+
9
+ class ResearchManager:
10
+
11
+ async def conduct_research(self, query: str):
12
+ """ Run the deep research process, yielding the status updates and the final report"""
13
+ trace_id = gen_trace_id()
14
+ with trace("Research trace", trace_id=trace_id):
15
+ print(f"View trace: https://platform.openai.com/traces/trace?trace_id={trace_id}")
16
+ yield f"View trace: https://platform.openai.com/traces/trace?trace_id={trace_id}"
17
+ print("Starting research...")
18
+ search_plan = await self.plan_searches(query)
19
+ yield "Searches planned, starting to search..."
20
+ search_results = await self.perform_searches(search_plan)
21
+ yield "Searches complete, writing report..."
22
+ report = await self.write_report(query, search_results)
23
+ # yield "Report written, sending email..."
24
+ # await self.send_email(report)
25
+ yield "Research complete"
26
+ yield report.markdown_report
27
+
28
+
29
+ async def plan_searches(self, query: str) -> WebSearchPlan:
30
+ """ Plan the searches to perform for the query """
31
+ print("Planning searches...")
32
+ result = await Runner.run(
33
+ planner_agent,
34
+ f"Query: {query}",
35
+ )
36
+ print(f"Will perform {len(result.final_output.searches)} searches")
37
+ return result.final_output_as(WebSearchPlan)
38
+
39
+ async def perform_searches(self, search_plan: WebSearchPlan) -> list[str]:
40
+ """ Perform the searches to perform for the query """
41
+ print("Searching...")
42
+ num_completed = 0
43
+ tasks = [asyncio.create_task(self.search(item)) for item in search_plan.searches]
44
+ results = []
45
+ for task in asyncio.as_completed(tasks):
46
+ result = await task
47
+ if result is not None:
48
+ results.append(result)
49
+ num_completed += 1
50
+ print(f"Searching... {num_completed}/{len(tasks)} completed")
51
+ print("Finished searching")
52
+ return results
53
+
54
+ async def search(self, item: WebSearchItem) -> str | None:
55
+ """ Perform a search for the query """
56
+ input = f"Search term: {item.query}\nReason for searching: {item.reason}"
57
+ try:
58
+ result = await Runner.run(
59
+ search_agent,
60
+ input,
61
+ )
62
+ return str(result.final_output)
63
+ except Exception:
64
+ return None
65
+
66
+ async def write_report(self, query: str, search_results: list[str]) -> ReportData:
67
+ """ Write the report for the query """
68
+ print("Thinking about report...")
69
+ input = f"Original query: {query}\nSummarized search results: {search_results}"
70
+ result = await Runner.run(
71
+ writer_agent,
72
+ input,
73
+ )
74
+
75
+ print("Finished writing report")
76
+ return result.final_output_as(ReportData)
77
+
78
+ async def send_email(self, report: ReportData) -> None:
79
+ print("Writing email...")
80
+ result = await Runner.run(
81
+ email_agent,
82
+ report.markdown_report,
83
+ )
84
+ print("Email sent")
85
+ return report
86
+
87
+ async def generate_clarification_questions(self, query: str) -> str:
88
+ """ Generate clarification questions based on the user's query """
89
+ print("Generating clarification questions...")
90
+ input = f"Please analyze this research query and generate 3 clarifying questions that would help focus the research: {query}"
91
+ try:
92
+ questions = await Runner.run(
93
+ clarify_agent,
94
+ input
95
+ )
96
+ print("Generated clarification questions")
97
+ return questions.final_output
98
+ except Exception as e:
99
+ print(f"Error generating questions: {e}")
100
+ return ""
search_agent.py ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from agents import Agent, WebSearchTool, ModelSettings
2
+
3
+ INSTRUCTIONS = (
4
+ "You are a research assistant. Given a search term, you search the web for that term and "
5
+ "produce a concise summary of the results. The summary must 2-3 paragraphs and less than 300 "
6
+ "words. Capture the main points. Write succintly, no need to have complete sentences or good "
7
+ "grammar. This will be consumed by someone synthesizing a report, so its vital you capture the "
8
+ "essence and ignore any fluff. Do not include any additional commentary other than the summary itself."
9
+ )
10
+
11
+ search_agent = Agent(
12
+ name="Search agent",
13
+ instructions=INSTRUCTIONS,
14
+ tools=[WebSearchTool(search_context_size="low")],
15
+ model="gpt-4o-mini",
16
+ model_settings=ModelSettings(tool_choice="required"),
17
+ )
writer_agent.py ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from pydantic import BaseModel, Field
2
+ from agents import Agent
3
+
4
+ INSTRUCTIONS = (
5
+ "You are a senior researcher tasked with writing a cohesive report for a research query. "
6
+ "You will be provided with the original query, and some initial research done by a research assistant.\n"
7
+ "You should first come up with an outline for the report that describes the structure and "
8
+ "flow of the report. Then, generate the report and return that as your final output.\n"
9
+ "The final output should be in markdown format, and it should be lengthy and detailed. Aim "
10
+ "for 5-10 pages of content, at least 1000 words."
11
+ )
12
+
13
+
14
+ class ReportData(BaseModel):
15
+ short_summary: str = Field(description="A short 2-3 sentence summary of the findings.")
16
+
17
+ markdown_report: str = Field(description="The final report")
18
+
19
+ follow_up_questions: list[str] = Field(description="Suggested topics to research further")
20
+
21
+
22
+ writer_agent = Agent(
23
+ name="WriterAgent",
24
+ instructions=INSTRUCTIONS,
25
+ model="gpt-4o-mini",
26
+ output_type=ReportData,
27
+ )